📄 ln97xend.c
字号:
__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 */ ) { UINT32 pTmp = MEM_TO_PCI_PHYS (LN_CACHE_VIRT_TO_PHYS ((UINT32) pBuf)); pTmd->lnTMD0 = (UINT32) PCI_SWAP (pTmp); }/******************************************************************************** tmdBuffAddrGet - get a transmit descriptor's packet buffer address** RETURNS: The packet buffer address associated with the specified TMD.** NOMANUAL*/__inline__ LOCAL char * tmdBuffAddrGet ( const LN_97X_DRV_CTRL * pDrvCtrl, /* specifies device control structure */ const volatile LN_TMD * pTmd /* specifies a TMD structure */ ) { UINT32 pTemp = PCI_TO_MEM_PHYS (PCI_SWAP (pTmd->lnTMD0)); return (char *)(LN_CACHE_PHYS_TO_VIRT (pTemp)); }/******************************************************************************** rmdBuffAddrGet - get a receive descriptor's packet buffer address** RETURNS: The packet buffer address associated with the specified RMD.** NOMANUAL*/__inline__ LOCAL char * rmdBuffAddrGet ( const LN_97X_DRV_CTRL * pDrvCtrl, /* specifies device control structure */ const volatile LN_RMD * pRmd /* specifies a RMD structure */ ) { UINT32 pTemp = PCI_TO_MEM_PHYS (PCI_SWAP (pRmd->lnRMD0)); return (char *)(LN_CACHE_PHYS_TO_VIRT (pTemp)); }/******************************************************************************** txDescClean - clean a transmit message descriptor (TMD)** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void txDescClean ( volatile LN_TMD * pTmd /* specifies the TMD to "clean" */ ) { pTmd->lnTMD2 = 0; /* clear error bit fields */ pTmd->lnTMD1 = PCI_SWAP (TMD1_CNST | TMD1_ENP | TMD1_STP); }/******************************************************************************** rxDescClean - clean a receive message descriptor (RMD)** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void rxDescClean ( volatile LN_RMD * pRmd /* specifies the RMD to "clean" */ ) { UINT32 temp = (RMD1_BCNT_MSK & -(LN_BUFSIZ)) | (RMD1_OWN | RMD1_CNST | RMD1_STP | RMD1_ENP); pRmd->lnRMD2 = 0; /* reset the message byte count */ pRmd->lnRMD1 = PCI_SWAP (temp); }/******************************************************************************** ibRxRingAddrSet - set RMD ring base address in the init block** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void ibRxRingAddrSet ( LN_97X_DRV_CTRL * pDrvCtrl /* specifies device control structure */ ) { UINT32 pTemp = MEM_TO_PCI_PHYS (LN_CACHE_VIRT_TO_PHYS(pDrvCtrl->pRring)); (pDrvCtrl->ib->lnIBRdra) = PCI_SWAP (pTemp); pTemp = PCI_SWAP (pDrvCtrl->ib->lnIBMode); pTemp |= IB_MODE_RLEN_MSK & ((pDrvCtrl->rringLen) << 20); (pDrvCtrl->ib->lnIBMode) = PCI_SWAP (pTemp); }/******************************************************************************** ibTxRingAddrSet - set TMD ring base address in the init block** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void ibTxRingAddrSet ( LN_97X_DRV_CTRL * pDrvCtrl /* specifies device control structure */ ) { UINT32 pTemp = MEM_TO_PCI_PHYS (LN_CACHE_VIRT_TO_PHYS(pDrvCtrl->pTring)); (pDrvCtrl->ib->lnIBTdra) = PCI_SWAP (pTemp); pTemp = PCI_SWAP (pDrvCtrl->ib->lnIBMode); pTemp |= IB_MODE_TLEN_MSK & ((pDrvCtrl->tringLen) << 28); (pDrvCtrl->ib->lnIBMode) = PCI_SWAP (pTemp); }/******************************************************************************** ibAddrFilterClear - clear the initialization block logical address filter** This routine clears the logical address filter in the specified* initialization block memory, <pIb>. The logical address filter* registers, CSR8 - CSR11, are not cleared in this routine.** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void ibAddrFilterClear ( volatile LN_IB * pIb /* initialization block base address */ ) { /* alias <lnIBLadrf> for a more efficient data MOV */ UINT32 * const pLadrf = (UINT32 *)(&(pIb->lnIBLadrf[0])); pLadrf[0] = 0x00000000; pLadrf[1] = 0x00000000; }/******************************************************************************** ibAddrFilterSet - set the initialization block logical address filter** The routine sets the logical address filter in the specified* initialization block memory, <pIb>, such that a new multicast address* will be accepted as input to the receiver unit.** RETURNS: N/A** NOMANUAL*/__inline__ LOCAL void ibAddrFilterSet ( volatile LN_IB * pIb, /* initialization block base address */ UINT32 crc /* CRC filter bit mask */ ) { ((pIb->lnIBLadrf[(crc & 0x0000003f) >> 3]) |= (1 << (crc & 0x7))); }/******************************************************************************** rmdHasErrors - test a Received Message Descriptor's error bits** RETURNS:* TRUE if the RMD ERR bit is set or if the associated packet data is not* contained entirely within the RMD packet buffer.** NOMANUAL*/__inline__ LOCAL BOOL rmdHasErrors ( const volatile LN_RMD * pRmd ) { ULONG rmd1 = PCI_SWAP (pRmd->lnRMD1); return ((rmd1 & RMD1_ERR) || ((rmd1 & (RMD1_STP | RMD1_ENP)) != (RMD1_STP | RMD1_ENP))); }/********************************************************************************* ln97xTMDGet - get the next transmit message descriptor (TMD)** RETURNS: an available transmit descriptor, otherwise NULL.** NOMANUAL*/__inline__ LOCAL LN_TMD * ln97xTMDGet ( LN_97X_DRV_CTRL * pDrvCtrl /* points to device control structure */ ) { volatile LN_TMD * pTmd = pDrvCtrl->pTring + pDrvCtrl->tmdIndex; LN_CACHE_INVALIDATE (pTmd, TMD_SIZ); /* check if this descriptor is owned by the chip or is out of bounds */ if ((LN_TMD_OWNED (pTmd)) || (((pDrvCtrl->tmdIndex + 1) % (pDrvCtrl->tringSize)) == pDrvCtrl->tmdIndexC)) { return (LN_TMD *) NULL; } return (LN_TMD *)(pTmd); }/********************************************************************************* ln97xFullRMDGet - get the next received message descriptor (RMD)** RETURNS:* A pointer to the next receive descriptor to process, or NULL if none ready.** NOMANUAL*/__inline__ LOCAL LN_RMD * ln97xFullRMDGet ( LN_97X_DRV_CTRL * pDrvCtrl /* points to DRV_CTRL structure */ ) { /* form a pointer to the next receive descriptor */ volatile LN_RMD * pRmd = pDrvCtrl->pRring + pDrvCtrl->rmdIndex; LN_CACHE_INVALIDATE (pRmd, RMD_SIZ); /* If receive buffer has been released to us, return it */ return ((LN_RMD_OWNED (pRmd) == 0) ? ((LN_RMD *) pRmd) : ((LN_RMD *) NULL)); }/******************************************************************************** ln97xEndLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device-specific parameters are passed in <initString>, which* expects a string of the following format:** <unit:devMemAddr:devIoAddr:pciMemBase:vecnum:intLvl:memAdrs* :memSize:memWidth:csr3b:offset:flags>** This routine can be called in two modes. If it is called with an empty but* allocated string, it places the name of this device (that is, "lnPci") into * the <initString> and returns 0.** If the string is allocated and not empty, the routine attempts to load* the driver using the values specified in the string.** RETURNS: An END object pointer, or NULL on error, or 0 and the name of the* device if the <initString> was NULL.*/END_OBJ * ln97xEndLoad ( char * initString /* string to be parse by the driver */ ) { LN_97X_DRV_CTRL * pDrvCtrl; if (initString == NULL) { return (NULL); } if (initString [0] == 0) { bcopy ((char *)LN_97X_DEV_NAME, initString, LN_97X_DEV_NAME_LEN); return ((END_OBJ *) OK); } /* allocate the device structure */ if ((pDrvCtrl = (LN_97X_DRV_CTRL *) calloc (sizeof (LN_97X_DRV_CTRL), 1)) == NULL) { goto errorExit; } /* parse the init string, filling in the device structure */ if (ln97xInitParse (pDrvCtrl, initString) == ERROR) { goto errorExit; } /* Have the BSP hand us our address. */ (* ln97xEnetAddrGet) (pDrvCtrl, (char *) &(pDrvCtrl->enetAddr [0])); /* initialize the END and MIB2 parts of the structure */ if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, LN_97X_DEV_NAME, pDrvCtrl->unit, &ln97xFuncTable, pDescription) == ERROR || END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, LN_SPEED) == ERROR) { goto errorExit; } /* Perform memory allocation */ if (ln97xMemInit (pDrvCtrl) == ERROR) { goto errorExit; } /* Perform memory distribution and reset and reconfigure the device */ if (ln97xRestartSetup (pDrvCtrl) == ERROR) { goto errorExit; } /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX); return (&pDrvCtrl->endObj);errorExit: if (pDrvCtrl != NULL) free ((char *)pDrvCtrl); return ((END_OBJ *)NULL); }/********************************************************************************* ln97xInitParse - parse the initialization string** Parse the input string. This routine is called from ln97xEndLoad() which* intializes some values in the driver control structure with the values* passed in the intialization string.** The initialization string format is:** <unit:devMemAddr:devIoAddr:pciMemBase:vecNum:intLvl:memAdrs* :memSize:memWidth:csr3b:offset:flags>** \is* \i <unit>* The device unit number. Unit numbers are integers starting at zero and* increasing for each device contolled by the driver.* \i <devMemAddr>* The device memory mapped I/O register base address. Device registers* must be mapped into the host processor address space in order for the* driver to be functional. Thus, this is a required parameter.* \i <devIoAddr>* Device register base I/O address (obsolete).* \i <pciMemBase>* Base address of PCI memory space.* \i <vecNum>* Interrupt vector number.* \i <intLvl>* Interrupt level. Generally, this value specifies an interrupt level* defined for an external interrupt controller.* \i <memAdrs>* Memory pool address or NONE.* \i <memSize>* Memory pool size or zero.* \i <memWidth>* Memory system size, 1, 2, or 4 bytes (optional).* \i <CSR3>* Control and Status Register 3 (CSR3) options.* \i <offset>* Memory alignment offset.* \i <flags>* Device specific flags reserved for future use.* \ie** RETURNS: OK, or ERROR if any arguments are invalid.*/STATUS ln97xInitParse ( LN_97X_DRV_CTRL * pDrvCtrl, /* pointer to the control structure */ char * initString /* initialization string */ ) { char * tok; char * pHolder = NULL; UINT32 devMemAddr; UINT32 devIoAddr; /* unit number */ if ((tok = strtok_r (initString, ":", &pHolder)) == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "Unit : %d ...\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); /* memory mapped IO address base */ if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL) return ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -