📄 rtl81x9.c
字号:
*/#define MII_SET(x) \ rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_MII, \ rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_MII, RTL_WIN_0) | x, RTL_WIN_0 )#define MII_CLR(x) \ rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_MII, \ rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_MII, RTL_WIN_0) & ~x, RTL_WIN_0 )/* EEPROM Macros */#define EE_SET(x) \ rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_CFG_9346, \ rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CFG_9346, RTL_WIN_0) | x, RTL_WIN_0)#define EE_CLR(x) \ rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CFG_9346, \ rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CFG_9346, RTL_WIN_0) & ~x, RTL_WIN_0)/***** LOCALS *****/LOCAL int rtlRsize = RTL_RMD_RLEN; /* recv ring size *//* forward static functions */LOCAL STATUS rtl81x9Reset ();LOCAL void rtl81x9Int (RTL81X9END_DEVICE *);LOCAL void rtl81x9HandleRecvInt(RTL81X9END_DEVICE *);LOCAL void rtl81x9HandleTxInt (RTL81X9END_DEVICE *);LOCAL void rtl81x9Restart (RTL81X9END_DEVICE *);LOCAL STATUS rtl81x9RestartSetup (RTL81X9END_DEVICE *);LOCAL void rtl81x9Config (RTL81X9END_DEVICE *);LOCAL void rtl81x9AddrFilterSet(RTL81X9END_DEVICE *); /* END Specific interfaces. *//* This is the only externally visible interface. */END_OBJ * rtl81x9EndLoad (char *initString);LOCAL STATUS rtl81x9Start (RTL81X9END_DEVICE *);LOCAL STATUS rtl81x9Stop (RTL81X9END_DEVICE *);LOCAL STATUS rtl81x9Unload (RTL81X9END_DEVICE *);LOCAL int rtl81x9Ioctl (RTL81X9END_DEVICE *, int, caddr_t);LOCAL STATUS rtl81x9Send (RTL81X9END_DEVICE *, M_BLK *);LOCAL STATUS rtl81x9MCastAddrAdd (RTL81X9END_DEVICE *, char *);LOCAL STATUS rtl81x9MCastAddrDel (RTL81X9END_DEVICE *, char *);LOCAL STATUS rtl81x9MCastAddrGet (RTL81X9END_DEVICE *, MULTI_TABLE *);LOCAL STATUS rtl81x9PollSend (RTL81X9END_DEVICE *, M_BLK *);LOCAL STATUS rtl81x9PollReceive (RTL81X9END_DEVICE *, M_BLK *);LOCAL STATUS rtl81x9PollStart (RTL81X9END_DEVICE *);LOCAL STATUS rtl81x9PollStop (RTL81X9END_DEVICE *);LOCAL STATUS rtl81x9InitParse (RTL81X9END_DEVICE *, char *);LOCAL STATUS rtl81x9InitMem (RTL81X9END_DEVICE *);LOCAL void rtl81x9LowPowerMode (RTL81X9END_DEVICE *);LOCAL UCHAR rtl81x9CsrReadByte (RTL81X9END_DEVICE *, USHORT, int);LOCAL USHORT rtl81x9CsrReadWord (RTL81X9END_DEVICE *, USHORT, int);LOCAL ULONG rtl81x9CsrReadLong (RTL81X9END_DEVICE *, USHORT, int);LOCAL void rtl81x9CsrWriteByte (RTL81X9END_DEVICE *, USHORT, UCHAR, int);LOCAL void rtl81x9CsrWriteWord (RTL81X9END_DEVICE *, USHORT, USHORT, int);LOCAL void rtl81x9CsrWriteLong (RTL81X9END_DEVICE *, USHORT, ULONG, int);LOCAL void rtl81x9ReadEEPROM (RTL81X9END_DEVICE *, UCHAR *, ULONG, ULONG, ULONG);LOCAL void rtl81x9EEPROMPutByte(RTL81X9END_DEVICE *, ULONG);LOCAL void rtl81x9EEPROMGetWord(RTL81X9END_DEVICE *, ULONG, USHORT*);LOCAL void rtl81x9Phy_writereg (RTL81X9END_DEVICE *, int, int);LOCAL USHORT rtl81x9Phy_readreg (RTL81X9END_DEVICE *, int);LOCAL int rtl81x9MII_writereg (RTL81X9END_DEVICE *, RTL_MII_FRAME *);LOCAL void rtl81x9MII_sync (RTL81X9END_DEVICE *);LOCAL void rtl81x9MII_send (RTL81X9END_DEVICE *, ULONG, int);LOCAL int rtl81x9MII_readreg (RTL81X9END_DEVICE *, RTL_MII_FRAME *);LOCAL void rtl81x9AutoNegTx (RTL81X9END_DEVICE *);LOCAL int rtl81x9MII_autoneg (RTL81X9END_DEVICE *);LOCAL int rtl81x9MediaSet (RTL81X9END_DEVICE *, int);LOCAL int rtl81x9MediaConfig (RTL81X9END_DEVICE *);/* * Define the device function table. This is static across all driver * instances. */LOCAL NET_FUNCS rtlFuncTable = { (FUNCPTR)rtl81x9Start, /* start func. */ (FUNCPTR)rtl81x9Stop, /* stop func. */ (FUNCPTR)rtl81x9Unload, /* unload func. */ (FUNCPTR)rtl81x9Ioctl, /* ioctl func. */ (FUNCPTR)rtl81x9Send, /* send func. */ (FUNCPTR)rtl81x9MCastAddrAdd, /* multicast add func. */ (FUNCPTR)rtl81x9MCastAddrDel, /* multicast delete func. */ (FUNCPTR)rtl81x9MCastAddrGet, /* multicast get fun. */ (FUNCPTR)rtl81x9PollSend, /* polling send func. */ (FUNCPTR)rtl81x9PollReceive, /* polling receive func. */ endEtherAddressForm, /* put address info into a NET_BUFFER */ endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */ endEtherPacketAddrGet /* Get packet addresses. */ }; /********************************************************************************* rtl81x9EndLoad - 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>:<CSR_reg_addr>:<RAP_reg_addr>:<int_vector>:<int_level>:<shmem_addr>:* <shmem_size>:<shmem_width>** 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, "rtl") 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* rtl81x9EndLoad ( char* initString /* string to be parse by the driver */ ) { RTL81X9END_DEVICE *pDrvCtrl; USHORT rtl_dev_id = 0; int speed; int i; DRV_LOG (DRV_DEBUG_LOAD, "Loading rtl...\n", 1, 2, 3, 4, 5, 6); if (initString == NULL) return (NULL); if (initString[0] == NULL) { bcopy((char *)RTL_DEV_NAME, initString, RTL_DEV_NAME_LEN); return (0); } /* allocate the device structure */ pDrvCtrl = (RTL81X9END_DEVICE *)calloc (sizeof (RTL81X9END_DEVICE), 1); if (pDrvCtrl == NULL) goto errorExit; /* parse the init string, filling in the device structure */ if (rtl81x9InitParse (pDrvCtrl, initString) == ERROR) goto errorExit; /* Reset the adaptor */ rtl81x9Reset (pDrvCtrl); /* Read the station address */ for (i=0; i < 6; i++) { pDrvCtrl->enetAddr[i] = rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_IDR0 + i, RTL_WIN_0); } /* * Now read the exact device type from the EEPROM to find * out if it's an 8129 or 8139. */ rtl81x9ReadEEPROM (pDrvCtrl, (UCHAR *) &rtl_dev_id, RTL_EE_PCI_DID, 1, 0); /* Perform memory allocation */ if (rtl81x9InitMem (pDrvCtrl) == ERROR) goto errorExit; if (rtl_dev_id == RTL_DEVICEID_8139 || rtl_dev_id == ACCTON_DEVICEID_5030 || rtl_dev_id == DELTA_DEVICEID_8139 || rtl_dev_id == ADDTRON_DEVICEID_8139) { if ((rtl81x9CsrReadLong (pDrvCtrl, RTL_REGS_TX_CONFIG, NONE) & RTL_TXCG_BLID))/*vicadd*/ pDrvCtrl->devType = RTL_DEV_8139A; else pDrvCtrl->devType = RTL_DEV_8139B; } else if (rtl_dev_id == RTL_DEVICEID_8129) pDrvCtrl->devType = RTL_DEV_8129; else { DRV_LOG (DRV_DEBUG_LOAD, "rtl: unknown device ID: %x\n", rtl_dev_id, 2, 3, 4, 5, 6); goto errorExit; } speed = rtl81x9MediaConfig (pDrvCtrl); pDrvCtrl->nextDesc = 0; pDrvCtrl->freeDesc = RTL_NUM_TX_DESC; for (i=0; i < RTL_NUM_TX_DESC; i++) pDrvCtrl->pDescMem[i] = NULL; /* Perform memory distribution and reset and reconfigure the device */ if (rtl81x9RestartSetup (pDrvCtrl) == ERROR) goto errorExit; /* initialize the END and MIB2 parts of the structure */ if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, RTL_DEV_NAME, pDrvCtrl->unit, &rtlFuncTable, "RTL 81x9 Fast Ethernet Enhanced Network Driver") == ERROR || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, speed) == ERROR) goto errorExit; /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->end, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX); /*V_LOG (DRV_DEBUG_LOAD, "Done loading rtl...\n", 1, 2, 3, 4, 5, 6);*/ return (&pDrvCtrl->end);errorExit: if (pDrvCtrl != NULL) free ((char *)pDrvCtrl); return NULL; }/********************************************************************************* rtl81x9InitParse - parse parameter values from initString** Parse the input string. Fill in values in the driver control structure.** The initialization string format is:* "<device addr>:<PCI addr>:<ivec>:<ilevel>:<mem base>:<mem size>: \* <user flags>:<offset>"** .IP <device addr>* base address of hardware device registers* .IP <PCI addr>* main memory address over the PCI bus* .IP <ivec>* interrupt vector number* .IP <ilevel>* interrupt level* .IP <mem base>* base address of a DMA-able, cache free,pre-allocated memory* .IP <mem size>* size of the pre-allocated memory* .IP <user flags>* User flags control the run-time characteristics of the chip* .IP <offset>* Memory offset for alignment* .LP** RETURNS: OK or ERROR for invalid arguments.*/LOCAL STATUS rtl81x9InitParse ( RTL81X9END_DEVICE * pDrvCtrl, char * initString ) { char * tok; /*char** holder = NULL;*/ char* holder = NULL; /* vicadd*/ UINT32 devMemAddr; UINT32 devIoAddr; /* Parse the initString */ DRV_LOG (DRV_DEBUG_LOAD, "Parse starting ...\n", 1, 2, 3, 4, 5, 6); /* Unit number. */ tok = strtok_r (initString, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "Unit : %d ...\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); /* devAdrs address. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; devMemAddr = (UINT32) strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "devMemAddr : 0x%X ...\n", devMemAddr, 2, 3, 4, 5, 6); /* devIoAddrs address */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; devIoAddr = (UINT32) strtoul (tok, NULL, 16); /* always use memory mapped IO if provided, else use io map */ if ((devMemAddr == NONE) && (devIoAddr == NONE)) { DRV_LOG (DRV_DEBUG_LOAD, "No memory or IO base specified ...\n", 1, 2, 3, 4, 5, 6); return (ERROR); } else if (devMemAddr != NONE) { pDrvCtrl->devAdrs = devMemAddr; pDrvCtrl->flags |= RTL_FLG_MODE_MEM_IO_MAP; DRV_LOG (DRV_DEBUG_LOAD, "devMemAddr specified for devAdrs ...\n", 1, 2, 3, 4, 5, 6); } else { pDrvCtrl->devAdrs = devIoAddr; DRV_LOG (DRV_DEBUG_LOAD, "devIoAddr specified for devAdrs - 0x%X ...\n", devIoAddr, 2, 3, 4, 5, 6); } /* PCI memory base address as seen from the CPU */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pciMemBase = strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "Pci : 0x%X ...\n", pDrvCtrl->pciMemBase, 2, 3, 4, 5, 6); /* Interrupt vector. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->ivec = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "ivec : 0x%X ...\n", pDrvCtrl->ivec, 2, 3, 4, 5, 6); /* Interrupt level. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->ilevel = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "ilevel : 0x%X ...\n", pDrvCtrl->ilevel, 2, 3, 4, 5, 6); /* Caller supplied memory address. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->memAdrs = (char *)strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "memAdrs : 0x%X ...\n", (int)pDrvCtrl->memAdrs, 2, 3, 4, 5, 6); /* Caller supplied memory size. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->memSize = strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "memSize : 0x%X ...\n", pDrvCtrl->memSize, 2, 3, 4, 5, 6); /* Caller supplied memory width. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->memWidth = atoi (tok); /*DRV_LOG (DRV_DEBUG_LOAD, "memWidth : 0x%X ...\n", pDrvCtrl->memWidth, 2, 3, 4, 5, 6);*/ /* CSR3B value */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->csr3B = strtoul (tok, NULL, 16); /*DRV_LOG (DRV_DEBUG_LOAD, "csr3b value : %d ...\n", pDrvCtrl->csr3B, 2, 3, 4, 5, 6);*/ /* Caller supplied alignment offset. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->offset = atoi (tok); /*DRV_LOG (DRV_DEBUG_LOAD, "offset value : %d ...\n", pDrvCtrl->offset, 2, 3, 4, 5, 6);*/ /* caller supplied flags */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->flags |= strtoul (tok, NULL, 16); /*DRV_LOG (DRV_DEBUG_LOAD, "flags : 0x%X ...\n", pDrvCtrl->flags, 2, 3, 4, 5, 6);*/ return OK; }/********************************************************************************* rtl81x9InitMem - initialize memory for the device** Using data in the control structure, setup and initialize the memory* areas needed. If the memory address is not already specified, then allocate* cache safe memory.** RETURNS: OK or ERROR.**/LOCAL STATUS rtl81x9InitMem ( RTL81X9END_DEVICE * pDrvCtrl /* device to be initialized */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -