📄 fei82557end.c
字号:
#define FREE_CFD_GET(pCurrFD) \ ((pCurrFD) = pDrvCtrl->pFreeCFD)#define USED_CFD_GET(pCurrFD) \ ((pCurrFD) = pDrvCtrl->pUsedCFD)#define RFD_GET(pCurrFD) \ ((pCurrFD) = pDrvCtrl->pRFD)/* command frame descriptors write macros */#define CFD_BYTE_WR(base, offset, value) \ FEI_BYTE_WR ((UINT32 *) ((UINT32) (base) + (offset)), \ (value))#define CFD_WORD_WR(base, offset, value) \ FEI_WORD_WR ((UINT32 *) ((UINT32) (base) + (offset)), \ (value))#define CFD_LONG_WR(base, offset, value) \ FEI_LONG_WR ((UINT32 *) ((UINT32) (base) + (offset)), \ (value))/* this is a special case, as the device will read as an address */#define CFD_NEXT_WR(base, value) \ do { \ volatile UINT32 temp = (UINT32) FEI_VIRT_TO_SYS (value); \ \ CFD_LONG_WR ((UINT32) (base), CFD_NEXT_OFFSET, (temp)); \ } while (0)/* this is a special case, as the device will read as an address */#define CFD_TBD_WR(base, value) \ do { \ volatile UINT32 temp; \ temp = (value == TBD_NOT_USED) ? value : \ ((UINT32) FEI_VIRT_TO_SYS ((UINT32) (value))); \ CFD_LONG_WR ((UINT32) (base), CFD_TBD_OFFSET, (temp)); \ } while (0)/* receive frame descriptors write macros */#define RFD_BYTE_WR(base, offset, value) \ FEI_BYTE_WR ((UINT32 *) ((UINT32) (base) + (offset)), \ (value))#define RFD_WORD_WR(base, offset, value) \ FEI_WORD_WR ((UINT32 *) ((UINT32) (base) + (offset)), \ (value))#define RFD_LONG_WR(base, offset, value) \ FEI_LONG_WR ((UINT32 *) ((UINT32) (base) + (offset)), \ (value))/* this is a special case, as the device will read as an address */#define RFD_NEXT_WR(base, value) \ do { \ volatile UINT32 temp = (UINT32) FEI_VIRT_TO_SYS ((UINT32) (value)); \ \ RFD_LONG_WR ((UINT32) (base), RFD_NEXT_OFFSET, (temp)); \ } while (0)/* this is a special case, as the device will read as an address */#define RFD_RBD_WR(base, value) \ do { \ volatile UINT32 temp; \ temp = (value == RBD_NOT_USED) ? value : \ ((UINT32) FEI_VIRT_TO_SYS ((UINT32) (value))); \ RFD_LONG_WR ((UINT32) (base), RFD_RBD_OFFSET, (temp)); \ } while (0)/* command frame descriptors read macros */#define CFD_BYTE_RD(base, offset, value) \ FEI_BYTE_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))#define CFD_WORD_RD(base, offset, value) \ FEI_WORD_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))#define CFD_LONG_RD(base, offset, value) \ FEI_LONG_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))/* this is a special case, as the device will read as an address */#define CFD_NEXT_RD(base, value) \ do { \ volatile UINT32 tempVal; \ \ CFD_LONG_RD ((UINT32) (base), CFD_NEXT_OFFSET, (tempVal)); \ \ value = (UINT32) FEI_SYS_TO_VIRT (((UINT32) (tempVal))); \ } while (0)/* this is a special case, as the device will read as an address */#define CFD_TBD_RD(base, value) \ do { \ volatile UINT32 tempVal; \ \ CFD_LONG_RD ((UINT32) (base), CFD_TBD_OFFSET, (tempVal)); \ \ value = (UINT32) FEI_SYS_TO_VIRT (((UINT32) (tempVal))); \ } while (0)/* receive frame descriptors read macros */#define RFD_BYTE_RD(base, offset, value) \ FEI_BYTE_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))#define RFD_WORD_RD(base, offset, value) \ FEI_WORD_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))#define RFD_LONG_RD(base, offset, value) \ FEI_LONG_RD ((UINT32 *) ((UINT32) (base) + (offset)), (value))/* this is a special case, as the device will read as an address */#define RFD_NEXT_RD(base, value) \ do { \ volatile UINT32 tempVal; \ \ RFD_LONG_RD ((UINT32) (base), RFD_NEXT_OFFSET, (tempVal)); \ \ value = (UINT32) FEI_SYS_TO_VIRT (((UINT32) (tempVal))); \ } while (0)/* various command frame descriptors macros */#define CFD_PKT_ADDR(cfdBase) \ ((UINT32 *) ((UINT32) cfdBase + CFD_PKT_OFFSET))#define RFD_PKT_ADDR(cfdBase) \ ((UINT32 *) ((UINT32) cfdBase + RFD_PKT_OFFSET))#define CFD_IA_ADDR(cfdBase) \ ((UINT32 *) ((UINT32) (cfdBase) + CFD_IA_OFFSET))#define CFD_MC_ADDR(cfdBase) \ ((UINT32 *) ((UINT32) (cfdBase) + CFD_MC_OFFSET))#define CFD_CONFIG_WR(address, value) \ FEI_BYTE_WR ((UINT32 *) ((UINT32) (address)), \ (value))#define I82557_INT_ENABLE \ CSR_BYTE_WR (CSR_INT_OFFSET, (UINT8) 0)#define I82557_INT_DISABLE \ CSR_BYTE_WR (CSR_INT_OFFSET, (UINT8) SCB_C_M)/* * This is the multiplier that is applied to the number of RFDs requested * to determine the number of "spares" available for loaning to the network * stack. */#define FEI_RFD_LOAN_MULTIPLIER 4/* globals */FUNCPTR feiEndIntConnect = (FUNCPTR) intConnect;FUNCPTR feiEndIntDisconnect = (FUNCPTR) NULL;/* locals *//* The definition of the driver control structure */typedef struct drv_ctrl { END_OBJ endObj; /* base class */ int unit; /* unit number */ char * pMemBase; /* 82557 memory pool base */ ULONG memSize; /* 82557 memory pool size */ char * pMemArea; /* cluster block pointer */ int nCFDs; /* how many CFDs to create */ int nRFDs; /* how many RFDs to create */ volatile CSR_ID pCSR; /* pointer to CSR base */ volatile CFD_ID pFreeCFD; /* current free CFD */ volatile CFD_ID pUsedCFD; /* first used CFD */ volatile RFD_ID pRFD; /* current Receive Frame Descriptor */ INT8 flags; /* driver state */ BOOL attached; /* interface has been attached */ volatile BOOL rxHandle; /* rx handler scheduled */ BOOL txHandle; /* tx handler scheduled */ BOOL txStall; /* tx handler stalled - no CFDs */ CACHE_FUNCS cacheFuncs; /* cache descriptor */ FEI_BOARD_INFO board; /* board specific info */ CL_POOL_ID pClPoolId; /* cluster pool identifier */ int offset; /* Alignment offset */ } DRV_CTRL;/* Function declarations not in any header files */IMPORT STATUS sys557Init (int unit, FEI_BOARD_INFO *pBoard);/* forward function declarations */LOCAL int fei82557ClkRate = 0;LOCAL STATUS fei82557InitParse (DRV_CTRL *pDrvCtrl, char *initString);LOCAL STATUS fei82557InitMem (DRV_CTRL *pDrvCtrl);LOCAL STATUS fei82557Send (DRV_CTRL *pDrvCtrl, M_BLK *pMblk);LOCAL UINT16 fei82557Action (DRV_CTRL *pDrvCtrl, UINT16 action);LOCAL STATUS fei82557PhyInit (DRV_CTRL *pDrvCtrl);LOCAL STATUS fei82557Stop (DRV_CTRL *pDrvCtrl);LOCAL STATUS fei82557Reset (DRV_CTRL *pDrvCtrl);LOCAL STATUS fei82557SCBCommand (DRV_CTRL *pDrvCtrl, UINT8 cmd, BOOL addrValid, UINT32 *addr);LOCAL STATUS fei82557Diag (DRV_CTRL *pDrvCtrl);LOCAL STATUS fei82557IASetup (DRV_CTRL *pDrvCtrl);LOCAL STATUS fei82557Config (DRV_CTRL *pDrvCtrl);LOCAL void fei82557MCastListForm (DRV_CTRL *pDrvCtrl, CFD_ID pCFD);LOCAL void fei82557ConfigForm (DRV_CTRL *pDrvCtrl, CFD_ID pCFD);LOCAL int fei82557MDIPhyLinkSet (DRV_CTRL *pDrvCtrl, int phyAddr);LOCAL STATUS fei82557NOP (DRV_CTRL *pDrvCtrl);LOCAL void fei82557CFDFree (DRV_CTRL *pDrvCtrl);LOCAL void fei82557FDUpdate (DRV_CTRL *pDrvCtrl, UINT8 fdList);LOCAL void fei82557RFDReturn (DRV_CTRL *pDrvCtrl, volatile RFD_ID pRFDNew);LOCAL STATUS fei82557MDIPhyConfig (DRV_CTRL *pDrvCtrl, int phyAddr);LOCAL void fei82557Int (DRV_CTRL *pDrvCtrl);LOCAL void fei82557HandleRecvInt (DRV_CTRL *pDrvCtrl);LOCAL void fei82557Receive (DRV_CTRL *pDrvCtrl, RFD_ID pRfd);LOCAL int fei82557MDIRead (DRV_CTRL *pDrvCtrl, int regAddr, int phyAddr, UINT16 *retVal);LOCAL int fei82557MDIWrite (DRV_CTRL *pDrvCtrl, int regAddr, int phyAddr, UINT16 writeData);/* debug routines, not normally compiled */ STATUS fei82557ErrCounterDump (DRV_CTRL *pDrvCtrl, UINT32 *memAddr); STATUS fei82557DumpPrint (DRV_CTRL *pDrvCtrl);/* END Specific interfaces. */END_OBJ * fei82557EndLoad (char *initString); LOCAL STATUS fei82557Start (DRV_CTRL *pDrvCtrl);LOCAL STATUS fei82557Unload (DRV_CTRL *pDrvCtrl);LOCAL STATUS fei82557Stop (DRV_CTRL *pDrvCtrl);LOCAL int fei82557Ioctl (DRV_CTRL *pDrvCtrl, int cmd, caddr_t data);LOCAL STATUS fei82557Send (DRV_CTRL *pDrvCtrl, M_BLK_ID pMblk);LOCAL STATUS fei82557MCastAddrAdd (DRV_CTRL *pDrvCtrl, char* pAddress);LOCAL STATUS fei82557MCastAddrDel (DRV_CTRL *pDrvCtrl, char* pAddress);LOCAL STATUS fei82557MCastAddrGet (DRV_CTRL *pDrvCtrl, MULTI_TABLE *pTable);LOCAL STATUS fei82557PollSend (DRV_CTRL *pDrvCtrl, M_BLK_ID pMblk);LOCAL STATUS fei82557PollReceive (DRV_CTRL *pDrvCtrl, M_BLK_ID pMblk);LOCAL STATUS fei82557PollStart (DRV_CTRL *pDrvCtrl);LOCAL STATUS fei82557PollStop (DRV_CTRL *pDrvCtrl);/* * Define the device function table. This is static across all driver * instances. */LOCAL NET_FUNCS netFuncs = { (FUNCPTR)fei82557Start, /* start func. */ (FUNCPTR)fei82557Stop, /* stop func. */ (FUNCPTR)fei82557Unload, /* unload func. */ (FUNCPTR)fei82557Ioctl, /* ioctl func. */ (FUNCPTR)fei82557Send, /* send func. */ (FUNCPTR)fei82557MCastAddrAdd, /* multicast add func. */ (FUNCPTR)fei82557MCastAddrDel, /* multicast delete func. */ (FUNCPTR)fei82557MCastAddrGet, /* multicast get fun. */ (FUNCPTR)fei82557PollSend, /* polling send func. */ (FUNCPTR)fei82557PollReceive, /* polling receive func. */ endEtherAddressForm, /* put address info into a NET_BUFFER. */ endEtherPacketDataGet, /* get pointer to data in NET_BUFFER. */ endEtherPacketAddrGet /* Get packet addresses. */ }; /********************************************************************************* fei82557EndLoad - initialize the driver and device** This routine initializes both, driver and device to an operational state* using device specific parameters specified by <initString>.** The parameter string, <initString>, is an ordered list of parameters each* separated by a colon. The format of <initString> is,* "<unit>:<memBase>:<memSize>:<nCFDs>:<nRFDs>:<flags>"** The 82557 shares a region of memory with the driver. The caller of this* routine can specify the address of this memory region, or can specify that* the driver must obtain this memory region from the system resources.** A default number of transmit/receive frames of 32 can be selected by* passing zero in the parameters <nTfds> and <nRfds>. In other cases, the* number of frames selected should be greater than two.** The <memBase> parameter is used to inform the driver about the shared* memory region. If this parameter is set to the constant "NONE," then this* routine will attempt to allocate the shared memory from the system. Any* other value for this parameter is interpreted by this routine as the address* of the shared memory region to be used. The <memSize> parameter is used* to check that this region is large enough with respect to the provided* values of both transmit/receive frames.** If the caller provides the shared memory region, then the driver assumes* that this region does not require cache coherency operations, nor does it* require conversions between virtual and physical addresses.** If the caller indicates that this routine must allocate the shared memory* region, then this routine will use cacheDmaMalloc() to obtain* some non-cacheable memory. The attributes of this memory will be checked,* and if the memory is not write coherent, this routine will abort and* return ERROR.** RETURNS: an END object pointer, or NULL on error.** SEE ALSO: ifLib,* .I "Intel 82557 User's Manual"*/END_OBJ* fei82557EndLoad ( char *initString /* parameter string */ ) { DRV_CTRL * pDrvCtrl; /* pointer to DRV_CTRL structure */ UCHAR enetAddr[6]; /* ethernet address */ UINT32 speed; UINT32 scbStatus; char bucket[2]; DRV_LOG (DRV_DEBUG_LOAD, ("Loading end\n"), 1, 2, 3, 4, 5, 6); if (initString == NULL) return (NULL); if (initString[0] == 0) { bcopy ((char *)DEV_NAME, (void *)initString, DEV_NAME_LEN); return (0); } /* allocate the device structure */ pDrvCtrl = (DRV_CTRL *) calloc (sizeof (DRV_CTRL), 1); if (pDrvCtrl == NULL) return (NULL); /* Parse InitString */ if (fei82557InitParse (pDrvCtrl, initString) == ERROR) goto errorExit; /* sanity check the unit number */ if (pDrvCtrl->unit < 0 ) goto errorExit; /* * initialize the default parameter for the Physical medium * layer control user has his chance to override in the BSP, * just be CAREFUL */ pDrvCtrl->board.phyAddr = 1; pDrvCtrl->board.phySpeed = PHY_AUTO_SPEED; pDrvCtrl->board.phyDpx = PHY_AUTO_DPX; pDrvCtrl->board.others = 0; pDrvCtrl->board.tcbTxThresh = FEI_TCB_TX_THRESH; /* callout to perform adapter init */ if (sys557Init (pDrvCtrl->unit, &pDrvCtrl->board) == ERROR) goto errorExit; /* get CSR address from the FEI_BOARD_INFO structure */ if ((pDrvCtrl->pCSR = (CSR_ID) pDrvCtrl->board.baseAddr) == NULL) goto errorExit; /* probe for memory-mapped CSR */ CSR_WORD_RD (CSR_STAT_OFFSET, scbStatus); if (vxMemProbe ((char *) &scbStatus, VX_READ, 2, &bucket[0]) != OK) { DRV_LOG (DRV_DEBUG_LOAD, (": need MMU mapping for address 0x%x\n"), (UINT32) pDrvCtrl->pCSR, 2, 3, 4, 5, 6); goto errorExit; } /* memory initialization */ if (fei82557InitMem (pDrvCtrl) == ERROR) goto errorExit; I82557_INT_DISABLE; /* initialize the Physical medium layer */ if (fei82557PhyInit (pDrvCtrl) != OK) { DRV_PRINT (DRV_DEBUG_LOAD, ("LINK FAILS, Check line connection\n")); } speed = ((((int) pDrvCtrl->board.phySpeed) == PHY_100MBS) ? FEI_100MBS : FEI_10MBS); if (fei82557ClkRate == 0) fei82557ClkRate = sysClkRateGet (); /* * reset the chip: this should be replaced by a true * adapter reset routine, once the init code is here. */ if (fei82557Reset (pDrvCtrl) != OK) goto errorExit; /* CU and RU should be idle following fei82557Reset() */ if (fei82557SCBCommand (pDrvCtrl, SCB_C_CULDBASE, TRUE, 0x0) == ERROR) goto errorExit; if (fei82557SCBCommand (pDrvCtrl, SCB_C_RULDBASE, TRUE, 0x0) == ERROR) goto errorExit; pDrvCtrl->attached = TRUE; /* get our ethernet hardware address */ bcopy ((char *)&pDrvCtrl->board.enetAddr, (char *)&enetAddr[0], FEI_ADDR_LEN); DRV_LOG (DRV_DEBUG_LOAD, ("fei82557Load...\n ADRR: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n "), enetAddr[0], enetAddr[1], enetAddr[2], enetAddr[3], enetAddr[4], enetAddr[5]); /* endObj initializations */ if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ*) pDrvCtrl, DEV_NAME, pDrvCtrl->unit, &netFuncs, "Intel 82557 Ethernet Enhanced Network Driver") == ERROR) goto errorExit; if (END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, (u_char *) &enetAddr[0], FEI_ADDR_LEN,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -