📄 ln97xend.c
字号:
#ifdef DRV_DEBUG /* if debugging driver */int ln97xDebug = DRV_DEBUG_LOAD | DRV_DEBUG_TX | DRV_DEBUG_RX;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (ln97xDebug & FLG) \ logMsg((char *) X0, (int)X1, (int)X2, (int)X3, \ (int)X4, (int)X5, (int)X6);#else /* DRV_DEBUG */#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#endif /* DRV_DEBUG *//* locals */LOCAL int lnTsize = LN_TMD_TLEN; /* deflt xmit ring size as power of 2 */LOCAL int lnRsize = LN_RMD_RLEN; /* deflt recv ring size as power of 2 */LOCAL volatile int ln97xBusEndianess = LN_LITTLE_ENDIAN;LOCAL volatile int ln97xInterruptLevel = LN_ACTIVE_LOW;LOCAL BOOL lnKickStartTx = LN_KICKSTART_TX;/* default description for the END device */LOCAL char * pDescription = "AMD 79C97x PCnet-PCI Enhanced Network Driver";/* forward declarations */LOCAL STATUS ln97xReset (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL void ln97xInt (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL void ln97xHandleRecvInt (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL STATUS ln97xRecv (LN_97X_DRV_CTRL * pDrvCtrl, LN_RMD *rmd);LOCAL LN_RMD * ln97xFullRMDGet (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL void ln97xRestart (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL STATUS ln97xRestartSetup (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL STATUS ln97xAddrFilterMod (LN_97X_DRV_CTRL *, const UINT8 *, FILTER_MOD_CMD);LOCAL void ln97xAddrFilterSet (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL void ln97xTRingScrub (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL STATUS ln97xMemInit (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL void ln97xHandleError (LN_97X_DRV_CTRL * pDrvCtrl, UINT32 errs);/* END-Specific interfaces */LOCAL STATUS ln97xStart (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL STATUS ln97xStop (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL STATUS ln97xUnload (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL int ln97xIoctl (LN_97X_DRV_CTRL * pDrvCtrl, int cmd, caddr_t data);LOCAL STATUS ln97xSend (LN_97X_DRV_CTRL * pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS ln97xMCastAddrAdd (LN_97X_DRV_CTRL* pDrvCtrl, char * pAddress);LOCAL STATUS ln97xMCastAddrDel (LN_97X_DRV_CTRL * pDrvCtrl, char * pAddress);LOCAL STATUS ln97xMCastAddrGet (LN_97X_DRV_CTRL * pDrvCtrl, MULTI_TABLE * pTable);LOCAL STATUS ln97xPollSend (LN_97X_DRV_CTRL * pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS ln97xPollReceive (LN_97X_DRV_CTRL * pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS ln97xPollStart (LN_97X_DRV_CTRL * pDrvCtrl);LOCAL STATUS ln97xPollStop (LN_97X_DRV_CTRL * pDrvCtrl);/* * Declare our function table. This is static across all driver * instances. */LOCAL NET_FUNCS ln97xFuncTable = { (FUNCPTR) ln97xStart, /* Function to start the device. */ (FUNCPTR) ln97xStop, /* Function to stop the device. */ (FUNCPTR) ln97xUnload, /* Unloading function for the driver. */ (FUNCPTR) ln97xIoctl, /* Ioctl function for the driver. */ (FUNCPTR) ln97xSend, /* Send function for the driver. */ (FUNCPTR) ln97xMCastAddrAdd, /* Multicast address add */ (FUNCPTR) ln97xMCastAddrDel, /* Multicast address delete */ (FUNCPTR) ln97xMCastAddrGet, /* Multicast table retrieve */ (FUNCPTR) ln97xPollSend, /* Polling send function */ (FUNCPTR) ln97xPollReceive, /* Polling receive function */ endEtherAddressForm, /* Put address info into a packet. */ endEtherPacketDataGet, /* Get a pointer to packet data. */ endEtherPacketAddrGet /* Get packet addresses. */ };/* inline functions *//********************************************************************************* csrWrite - select and write a CSR register** This routine selects a register to write, through the RAP register and* then writes the CSR value to the RDP register.** CAVEATS* Assumes the most-significant 16-bits of <value> are reserved and should* be written as zero. This is true of many, but not all, PCnet CSR* registers.** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void csrWrite ( const LN_97X_DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ int reg, /* CSR register to select */ UINT32 value /* CSR value to write */ ) { SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, REG_SWAP (pDrvCtrl, reg)); SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRdp, REG_SWAP (pDrvCtrl, (value & 0x0000ffff))); }/********************************************************************************* csrRead - select and read a CSR register** This routine selects a register to read, through the RAP register and* then reads the CSR value from the RDP register.** CAVEATS* Assumes the most-significant 16-bits of register are reserved and should* be returned as zero. This is true of many, but not all, PCnet CSR* registers.** RETURNS: The least significant 16-bits of the specified CSR register.** NOMANUAL*/__inline__ LOCAL UINT32 csrRead ( const LN_97X_DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ int reg /* register to select */ ) { UINT32 result; SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, REG_SWAP (pDrvCtrl, reg)); SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pRdp, result); return (REG_SWAP (pDrvCtrl, result) & 0x0000ffff); }/********************************************************************************* csrLockedWrite - select and write a CSR register (interrupts locked)** This routine selects a register to write, through the RAP register and* then writes the CSR value to the RDP register.** CAVEATS* Assumes the most-significant 16-bits of <value> are reserved and should* be written as zero. This is true of many, but not all, PCnet CSR* registers.** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void csrLockedWrite ( const LN_97X_DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ int reg, /* CSR register to select */ UINT32 value /* CSR value to write */ ) { int level = intLock (); SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, REG_SWAP (pDrvCtrl, reg)); SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRdp, REG_SWAP (pDrvCtrl, (value & 0x0000ffff))); intUnlock (level); }/********************************************************************************* csrLockedRead - select and read a CSR register (interrupts locked)** This routine selects a register to read, through the RAP register and* then reads the CSR value from the RDP register.** CAVEATS* Assumes the most-significant 16-bits of register are reserved and should* be returned as zero. This is true of many, but not all, PCnet CSR* registers.** RETURNS: The least significant 16-bits of the specified CSR register.** NOMANUAL*/__inline__ LOCAL UINT32 csrLockedRead ( const LN_97X_DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ int reg /* register to select */ ) { UINT32 result; int level = intLock (); SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, REG_SWAP (pDrvCtrl, reg)); SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pRdp, result); intUnlock (level); return (REG_SWAP (pDrvCtrl, result) & 0x0000ffff); }/********************************************************************************* bcrWrite - select and write a BCR register** This routine writes the bus configuration register. It first selects the* BCR register to write through the RAP register and then it writes the value* to the BDP register.** CAVEATS* Assumes the most-significant 16-bits of <value> are reserved and should* be written as zero. This is true of many, but not all, PCnet BCR* registers.** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void bcrWrite ( const LN_97X_DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ int reg, /* BCR register to select */ UINT32 value /* BCR value to write */ ) { SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, REG_SWAP (pDrvCtrl, reg)); SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pBdp, REG_SWAP (pDrvCtrl, (value & 0x0000ffff))); }/********************************************************************************* bcrRead - select and read a BCR register** This routine reads the bus configuration register. It first selects the* BCR register to read through the RAP register and then it reads the value* from the BDP register.** CAVEATS* Assumes the most-significant 16-bits of register are reserved and should* be returned as zero. This is true of many, but not all, PCnet BCR* registers.** RETURNS: The least significant 16-bits of the specified BCR register.** NOMANUAL*/__inline__ LOCAL UINT32 bcrRead ( const LN_97X_DRV_CTRL * pDrvCtrl, /* pointer to DRV_CTRL structure */ int reg /* register to select */ ) { UINT32 result; SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, REG_SWAP (pDrvCtrl, reg)); SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pBdp, result); return (REG_SWAP (pDrvCtrl, result) & 0x0000ffff); }/******************************************************************************** chipIdMake - get an Am79C97x PCI controller chip ID** This routine returns a unique chip ID value derived from registers CSR88* and CSR89. The chip ID value represented by the returned constant is* formed as follows:** chipId = (CSR(88) | (CSR(89) << 16))* chipId = (chipId >> 12) & 0xffff** RETURNS:* A chip ID value represented by one of the following constants* \is* \i "CHIP_ID_AM79C970A"* Am79C970A PCnet-PCI II* \i "CHIP_ID_AM79C971"* Am79C971 PCnet-FAST* \i "CHIP_ID_AM79C972"* Am79C972 PCnet-FAST +* \i "CHIP_ID_AM79C973"* Am79C973 PCnet-FAST III* \i "CHIP_ID_AM79C975"* Am79C975 PCnet Fast III* \ie** NOMANUAL*/__inline__ LOCAL UINT32 chipIdMake ( const LN_97X_DRV_CTRL * pDrvCtrl /* specifies device control structure */ ) { return (((csrRead (pDrvCtrl, CSR(88)) | (csrRead (pDrvCtrl, CSR(89)) << 16)) >> 12) & 0x0000ffff); }/******************************************************************************** suspendModeEnter - enter Am79C97x suspend mode** This routine will put the specified device in suspend mode by setting* the SPND bit in CSR0. Suspend mode allows updating certain registers* without setting the STOP bit.** Upon entering suspend mode, the controller will finish all on-going* transmit activity and update the corresponding transmit descriptor* entries. The controller will then finish all on-going receive activity* and update the corresponding receive descriptor entries.** CAVEATS* Do not call this routine with the STOP bit set in CSR0. Do not set* the STOP bit in CSR0 after this routine is called and before* suspendModeLeave() is called.** RETURNS: A suspend-mode key for the controller state prior to the call.** SEE ALSO: suspendModeLeave()** NOMANUAL*/__inline__ LOCAL UINT32 suspendModeEnter ( const LN_97X_DRV_CTRL * pDrvCtrl /* specifies device control structure */ ) { int intLevel = intLock(); UINT32 key = (csrRead (pDrvCtrl, CSR(5)) & CSR5_RESRVD_MASK); csrWrite (pDrvCtrl, CSR(5), key | CSR5_SPND); intUnlock (intLevel); do { ; /* poll for suspend mode entry */ } while ((csrLockedRead (pDrvCtrl, CSR(5)) & CSR5_SPND) == 0); return key; }/******************************************************************************** suspendModeLeave - leave Am79C97x suspend mode** This routine will take a specified device out of suspend mode by* clearing the SPND bit in CSR0. Upon entering suspend mode, the* device should have been stopped with an orderly termination of network* activity via suspendModeEnter(). The controller will leave the* suspend mode and continue at the transmit and receive descriptor ring* locations where it had left off.** RETURNS: N/A** SEE ALSO: suspendModeEnter()** NOMANUAL*/__inline__ LOCAL void suspendModeLeave ( const LN_97X_DRV_CTRL * pDrvCtrl, /* specifies device control structure */ UINT32 key /* key obtained when suspend entered */ ) { csrWrite (pDrvCtrl, CSR(5), key); }/******************************************************************************** rmdBuffAddrSet - set a receive descriptor's packet buffer address** This routine sets the input packet buffer address for an RMD, specified* by <pRmd>, to the address specified by <pBuf>.** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void rmdBuffAddrSet ( const LN_97X_DRV_CTRL * pDrvCtrl, /* specifies device control structure */ volatile LN_RMD * pRmd, /* specifies an RMD structure */ const char * pBuf /* buffer addr to associate with RMD */ ) { UINT32 pTmp = MEM_TO_PCI_PHYS (LN_CACHE_VIRT_TO_PHYS ((UINT32) pBuf)); pRmd->lnRMD0 = (UINT32) PCI_SWAP (pTmp); }/******************************************************************************** tmdBuffAddrSet - set a transmit descriptor's packet buffer address** This routine sets the output packet buffer address for a TMD, specified* by <pTmd>, to the address specified by <pBuf>.** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void tmdBuffAddrSet ( const LN_97X_DRV_CTRL * pDrvCtrl, /* specifies device control structure */ volatile LN_TMD * pTmd, /* specifies a TMD structure */ const char * pBuf /* buffer addr to associate with TMD */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -