257 lines
11 KiB
C++
257 lines
11 KiB
C++
// ---------------------------------------------------------------------------------------
|
|
// nicx.h
|
|
//
|
|
// Copyright (C) Microsoft Corporation
|
|
// ---------------------------------------------------------------------------------------
|
|
|
|
#ifndef _NICX_H_
|
|
#define _NICX_H_
|
|
|
|
// ---------------------------------------------------------------------------------------
|
|
// Definitions
|
|
// ---------------------------------------------------------------------------------------
|
|
|
|
struct NICSTATS
|
|
{
|
|
ULONG isrCount;
|
|
ULONG dpcCount;
|
|
ULONG txGoodFrames;
|
|
ULONG rxGoodFrames;
|
|
ULONG txUnderflowErrors;
|
|
ULONG txLateCollisions;
|
|
ULONG txLostCarriers;
|
|
ULONG txDefers;
|
|
ULONG txExcessiveDefers;
|
|
ULONG txRetryErrors;
|
|
ULONG rxMinSizeErrors;
|
|
ULONG rxFramingErrors;
|
|
ULONG rxOverFlowErrors;
|
|
ULONG rxCrcErrors;
|
|
ULONG rxLengthErrors;
|
|
ULONG rxMaxFrameErrors;
|
|
ULONG rxLateCollisions;
|
|
ULONG rxRunts;
|
|
ULONG rxExtraByteErrors;
|
|
ULONG rxMissedFrames;
|
|
ULONG rxEndOfFrameErrors;
|
|
|
|
};
|
|
|
|
#define NIC_VENDORID 0x10DE // nVidia Vendor ID
|
|
#define NIC_DEVICEID 0x01C3 // nVidia Device ID
|
|
|
|
#define RXDESC_OWN BIT(31) // 0 - host owns; 1 - controller owns
|
|
#define RXDESC_ERR BIT(30) // receive error
|
|
#define RXDESC_FRAM BIT(29) // framing error
|
|
#define RXDESC_OFOL BIT(28) // overflow error
|
|
#define RXDESC_CRC BIT(27) // CRC error
|
|
#define RXDESC_LFER BIT(26) // length field error
|
|
#define RXDESC_MAX BIT(25) // received frame larger than max size
|
|
#define RXDESC_LCOL BIT(24) // late collision
|
|
#define RXDESC_RUNT BIT(23) // runt packet received
|
|
#define RXDESC_PAM BIT(22) // physical address match
|
|
#define RXDESC_MAM BIT(21) // multicast address match
|
|
#define RXDESC_BAM BIT(20) // broadcast address match
|
|
#define RXDESC_EXTRA BIT(18) // received frame length has an extra byte
|
|
#define RXDESC_MISS BIT(17) // missed data reception
|
|
#define RXDESC_REND BIT(16) // end of receive frame
|
|
|
|
#define TXDESC_OWN BIT(31) // 0 - host owns; 1 - controller owns
|
|
#define TXDESC_ERR BIT(30) // transmit error
|
|
#define TXDESC_UFLO BIT(29) // underflow error
|
|
#define TXDESC_LCOL BIT(28) // late collision
|
|
#define TXDESC_LCAR BIT(27) // loss of carrier
|
|
#define TXDESC_DEF BIT(26) // deferred
|
|
#define TXDESC_EXDEF BIT(25) // excessive deferral
|
|
#define TXDESC_INTEN BIT(24) // interrupt override
|
|
#define TXDESC_RTRY BIT(19) // retry error (23-20: retry count)
|
|
#define TXDESC_TEND BIT(16) // end of transmit frame
|
|
|
|
struct XmitDesc
|
|
{
|
|
DWORD _dwPhyAddr; // physical address of xmit buffer
|
|
DWORD _dwFlagsCount; // HIWORD - control/status bits; LOWORD - byte count minus 1
|
|
};
|
|
|
|
struct RecvDesc
|
|
{
|
|
DWORD _dwPhyAddr; // physical address of recv buffer
|
|
DWORD _dwFlagsCount; // HIWORD - control/status bits; LOWORD - byte count
|
|
};
|
|
|
|
#define NIC_FRAME_SIZE (PAGE_SIZE/2)
|
|
#define NIC_FRAME_ALIGNMENT 2
|
|
|
|
// ---------------------------------------------------------------------------------------
|
|
// CXnNic
|
|
// ---------------------------------------------------------------------------------------
|
|
|
|
class NOVTABLE CXnNic : public CXnBase
|
|
{
|
|
// Definitions -----------------------------------------------------------------------
|
|
|
|
struct XNADDRXBDM
|
|
{
|
|
BYTE bSizeOfStruct; // sizeof(XNADDR)
|
|
BYTE bFlags; // XNET_XNADDR_* flags below
|
|
BYTE abEnet[6]; // Ethernet MAC address
|
|
IN_ADDR ina; // IP address (zero if not static/DHCP)
|
|
IN_ADDR inaOnline; // Online IP address (zero if not online)
|
|
WORD wPortOnline; // Online port (zero if not online)
|
|
BYTE abIdOnline[20]; // Online identifier (zero if not online)
|
|
};
|
|
|
|
// External --------------------------------------------------------------------------
|
|
|
|
public:
|
|
|
|
HAL_DECLARE_NEW_DELETE(CXnNic)
|
|
|
|
BOOL NicXmitReady();
|
|
void NicXmit(CPacket * ppkt);
|
|
VIRTUAL void NicTimer();
|
|
|
|
#if defined(XNET_FEATURE_XBDM_CLIENT) || defined(XNET_FEATURE_XBDM_SERVER)
|
|
DWORD NicGetOtherXnAddr(XNADDR * pxna);
|
|
#endif
|
|
|
|
protected:
|
|
|
|
NTSTATUS NicInit(XNetInitParams * pxnip);
|
|
INLINE INT NicConfig(const XNetConfigParams * pxncp) { return(0); }
|
|
void NicStart();
|
|
void NicFlush();
|
|
void NicStop();
|
|
void NicTerm();
|
|
|
|
VIRTUAL void EnetRecv(CPacket * ppkt, UINT uiType) VPURE;
|
|
VIRTUAL void EnetPush() VPURE;
|
|
|
|
// Internal --------------------------------------------------------------------------
|
|
|
|
private:
|
|
|
|
INLINE XmitDesc * PxdNext(XmitDesc * pxd) { return(pxd == _pxdLast ? _pxdFirst : (pxd + 1)); }
|
|
INLINE RecvDesc * PrdNext(RecvDesc * prd) { return(prd == _prdLast ? _prdFirst : (prd + 1)); }
|
|
INLINE DWORD_PTR PhyAddr(void * pv) { return((DWORD_PTR)pv + _dwPhyOff); }
|
|
INLINE void * VirAddr(DWORD_PTR dw) { return((void *)(dw - _dwPhyOff)); }
|
|
|
|
void NicStartXmitRecv();
|
|
void NicStopXmitRecv();
|
|
static BOOLEAN NicIsr(PKINTERRUPT, PVOID pvContext);
|
|
BOOLEAN NicProcessIsr();
|
|
static void NicDpc(PKDPC dpc, void * pvContext, void * pvArg1, void * pvArg2);
|
|
void NicProcessDpc();
|
|
void NicMiiInterrupt(DWORD dwMintr, BOOL fInit);
|
|
void NicRecvInterrupt();
|
|
void NicXmitInterrupt();
|
|
|
|
static void HalShutdownNotification(HAL_SHUTDOWN_REGISTRATION * pHalShutdownReg);
|
|
|
|
class CXbdmClient
|
|
{
|
|
public:
|
|
INLINE CXnNic * GetXnNic();
|
|
virtual void XmitComplete(void * pvPkt);
|
|
virtual void EnetRecv(UINT uiFlags, void * pv, UINT cb, UINT uiType);
|
|
virtual void EnetPush();
|
|
virtual DWORD GetXnAddr(XNADDRXBDM * pxnaXbdm);
|
|
};
|
|
|
|
class CXbdmServer
|
|
{
|
|
public:
|
|
// This magic cookie on the XBDM server CXnNic protects the client from connecting
|
|
// to an incompatible version. We only change it when this interface changes in
|
|
// a non-backward compatible way.
|
|
#define XBDM_SERVER_COOKIE 'XBD6'
|
|
CXbdmServer() { _dwCookie = XBDM_SERVER_COOKIE; }
|
|
BOOL IsValidServer() { return(_dwCookie == XBDM_SERVER_COOKIE); }
|
|
INLINE CXnNic * GetXnNic();
|
|
virtual void NicStop();
|
|
virtual NTSTATUS InitClient(UINT cfgRecvQ, UINT cfgXmitQ, CEnetAddr * pea, BOOL * pfLinkIsUp);
|
|
virtual void AttachClient(CXbdmClient * pXbdmClient);
|
|
virtual void DetachClient();
|
|
virtual DWORD GetXnAddr(XNADDRXBDM * pxnaXbdm);
|
|
virtual void Xmit(void * pvPkt, void * pv, UINT cb);
|
|
virtual BOOL XmitReady();
|
|
DWORD _dwCookie;
|
|
};
|
|
|
|
class CXbdmPacket : public CPacket
|
|
{
|
|
|
|
public:
|
|
|
|
void * _pvPkt; // Client's packet pointer
|
|
};
|
|
|
|
#ifdef XNET_FEATURE_STATS
|
|
#define STATINC(n) StatInc(offsetof(NICSTATS, n))
|
|
#define STATINC_(x,n) if (x) STATINC(n)
|
|
void StatInit();
|
|
void StatTerm();
|
|
void StatInc(UINT iStat);
|
|
void StatTimer(CTimer * pt);
|
|
#else
|
|
#define STATINC(n)
|
|
#define STATINC_(x,n)
|
|
INLINE void StatInit() {};
|
|
INLINE void StatTerm() {};
|
|
#endif
|
|
|
|
// Data ------------------------------------------------------------------------------
|
|
|
|
public:
|
|
|
|
CEnetAddr _ea; // Ethernet address
|
|
|
|
private:
|
|
|
|
KDPC _dpc; // DPC object
|
|
ULONG _ulIntrVector; // interrupt vector
|
|
KIRQL _irqlIntr; // interrupt IRQ level
|
|
DWORD _dwRxPollFreq; // Rx polling frequency
|
|
DWORD _dwLinkState; // last known link state (from PhyGetLinkState)
|
|
BOOL _fXmitFull; // TRUE if _cxdBusy >= _cxdPool
|
|
DWORD_PTR _dwPhyOff; // virtual to physical offset
|
|
LONG _cxdBusy; // count of busy transmit descriptors
|
|
LONG _cxdPool; // number of transmit descriptors (minus 1)
|
|
XmitDesc * _pxdFirst; // first transmit descriptor
|
|
XmitDesc * _pxdLast; // last transmit descriptor
|
|
XmitDesc * _pxdBusy; // first busy transmit descriptor
|
|
XmitDesc * _pxdFree; // first free transmit descriptor
|
|
CPacketQueue _pqXmit; // queue of packets being transmitted
|
|
LONG _crdPool; // number of receive descriptors available
|
|
RecvDesc * _prdFirst; // first receive descriptor
|
|
RecvDesc * _prdLast; // last receive descriptor
|
|
RecvDesc * _prdPtr; // current receive descriptor
|
|
HAL_SHUTDOWN_REGISTRATION _HalShutdownReg; // registration for system shutdown
|
|
|
|
#ifdef XNET_FEATURE_XBDM_CLIENT
|
|
CXbdmServer * _pXbdmServer; // Non-NULL when XBDM is running in this process
|
|
CXbdmClient _XbdmClient; // The object we give to the XBDM server
|
|
#endif
|
|
|
|
#ifdef XNET_FEATURE_XBDM_SERVER
|
|
CXbdmClient * _pXbdmClient; // Non-NULL when the title stack is attached
|
|
CXbdmServer _XbdmServer; // The object we give to the XBDM client
|
|
CEnetAddr _eaClient; // Ethernet address of title stack
|
|
CPacketQueue _pqClient; // Packet queue of client packets
|
|
CXbdmPacket * _ppktXbdm; // Vector of CXbdmPacket structures
|
|
#endif
|
|
|
|
#ifdef XNET_FEATURE_STATS
|
|
NICSTATS _NicStats; // statistics
|
|
NICSTATS _NicStatsLast; // statistics at last report
|
|
CTimer _timerStats; // statistics timer
|
|
#endif
|
|
|
|
private:
|
|
|
|
static KINTERRUPT s_InterruptObject;
|
|
|
|
};
|
|
|
|
#endif // _NICX_H_
|