📄 sysnetif.c
字号:
#define NET_ADAPTER_DEVICE_ID LN97X_PCI_DEVICE_ID #define LN_97X_LOAD_FUNC ln97xEndLoad /* externs *//* defined in sysLib.c */IMPORT STATUS sysMmuMapAdd (void * address, UINT len, UINT initialStateMask, UINT initialState);IMPORT END_TBL_ENTRY endDevTbl[]; /* end device table */ /* typedefs */ typedef struct ln97xPciResource /* LN_97X_PCI_RESOURCES */ { UINT32 iobaseCsr; /* Base Address Register 0 */ UINT32 membaseCsr; /* Base Address Register 1 */ char irq; /* Interrupt Request Level */ UINT32 irqvec; /* Interrupt Request vector */ UINT32 configType; /* type of configuration */ UINT32 boardType; /* type of LAN board for this unit */ UINT32 pciBus; /* PCI Bus number */ UINT32 pciDevice; /* PCI Device number */ UINT32 pciFunc; /* PCI Function number */ } LN_97X_PCI_RESOURCES; typedef struct ln97xBoardResource /* LN_97X_BOARD_RESOURCES */ { UINT32 type; /* type of the board */ UINT32 vendorId; /* Vendor ID */ UINT32 deviceId; /* Device ID */ UINT32 lnUsrFlags; /* LN driver user flags */ FUNCPTR mediaSelectFunc; /* media select routine */ } LN_97X_BOARD_RESOURCES; /* locals */ /* * This array defines the board-specific PCI resources, the base address * register configuration mode and the Ethernet adapter type. It's indexed * using the device number returned from pciFindDevice(). */ LOCAL LN_97X_PCI_RESOURCES ln97xPciResources [LN97X_MAX_DEV] = { {LN97X_IO_ADR0, LN97X_MEM_ADR0, LN97X_INT_LVL0, LN97X_INT_VEC0, PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0}, {LN97X_IO_ADR1, LN97X_MEM_ADR1, LN97X_INT_LVL1, LN97X_INT_VEC1, PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0}, {LN97X_IO_ADR2, LN97X_MEM_ADR2, LN97X_INT_LVL2, LN97X_INT_VEC2, PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0}, {LN97X_IO_ADR3, LN97X_MEM_ADR3, LN97X_INT_LVL3, LN97X_INT_VEC3, PCI_CFG_TYPE, LN_TYPE_970, 0, 0, 0}, }; /* * This array defines board-specific vendor and device ids, flags to pass to * the drive load routine and the function used to select the media. */ LOCAL LN_97X_BOARD_RESOURCES ln97xBoardResources [LN97X_MAX_UNITS] = { {LN_TYPE_970, LN97X_PCI_VENDOR_ID, LN97X_PCI_DEVICE_ID, LN_USR_FLAGS_970, NULL}, {LN_TYPE_971, LN97X_PCI_VENDOR_ID, LN97X_PCI_DEVICE_ID, LN_USR_FLAGS_971, NULL}, {LN_TYPE_972, LN97X_PCI_VENDOR_ID, LN97X_PCI_DEVICE_ID, LN_USR_FLAGS_972, NULL}, {LN_TYPE_7990, LN97X_PCI_VENDOR_ID, LN7990_PCI_DEVICE_ID, LN_USR_FLAGS_7990, NULL}, }; /* forward declarations */ LOCAL void sysLan97xInitStrCook (LN_97X_PCI_RESOURCES *, int unitNum); /********************************************************************************* sysLan97xPciInit - prepare LAN adapter for LN97X initialization** This routine finds out the PCI device, maps its memory and IO address.* It must be done prior to initializing the LN970, sysLn97XInit(). Also* must be done prior to MMU initialization, usrMmuInit().** RETURNS: OK/ERROR*/ STATUS sysLan97xPciInit (void) { LN_97X_PCI_RESOURCES * pRsrc; /* pointer board resources */ UINT32 membaseCsr; UINT32 iobaseCsr; char irq; int pciBus; int pciDevice; int pciFunc; int unit; int found = 0; int ln97XUnits = 0; /* for all the support lan devices find if some of them exist */ for (unit = 0; unit < LN97X_MAX_UNITS; unit++) { if (pciFindDevice (ln97xBoardResources [unit].vendorId, ln97xBoardResources [unit].deviceId, unit, &pciBus, &pciDevice, &pciFunc) == OK) { /* board detected */ /* for now, we're ignoring the possibility of duplicates */ found = TRUE; /* load up the PCI device table */ pRsrc = ln97xPciResources + ln97XUnits; /* get the pci entry */ pRsrc->pciBus = pciBus; pRsrc->pciDevice = pciDevice; pRsrc->pciFunc = pciFunc; ln97XUnits++; /* number of units found */ } } if ((found != TRUE) || (pciDevice > PCI_MAX_DEV)) return (ERROR); /* Now initialize all the units we found */ for (unit = 0; unit < ln97XUnits; unit++) { /* Fill in the resource entry */ pRsrc = ln97xPciResources + unit; if (pRsrc->configType == PCI_CFG_FORCE) { /* write the iobase, membase, and irq */ pciConfigOutLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_BASE_ADDRESS_0, pRsrc->iobaseCsr | PCI_BASE_IO); pciConfigOutLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_BASE_ADDRESS_1, pRsrc->membaseCsr); pciConfigOutByte (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_DEV_INT_LINE, pRsrc->irq); } /* * get memory base address and IO base address * Note: we read it in again, even if we just wrote it out because the * device can change what we wrote */ pciConfigInLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_BASE_ADDRESS_0, &iobaseCsr); pciConfigInLong (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_BASE_ADDRESS_1, &membaseCsr); pciConfigInByte (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_DEV_INT_LINE, &irq); /* * mask off registers. IO base needs to be masked off because bit0 * will always be set to 1 */ membaseCsr &= PCI_MEMBASE_MASK; iobaseCsr &= PCI_IOBASE_MASK; #ifdef INCLUDE_MMU_BASIC if (sysMmuMapAdd ((void *)(membaseCsr & PCI_DEV_MMU_MSK), PCI_DEV_ADRS_SIZE, VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE, VM_STATE_VALID | VM_STATE_WRITABLE | VM_STATE_CACHEABLE_NOT ) == ERROR) { /* for now, exit, but later break and stop where we're at when we're detecting multiple units */ return (ERROR); }#else#warning INCLUDE_MMU_BASIC not defined#endif /* INCLUDE_MMU_BASIC */ /* over write the resource table with values read */ pRsrc->membaseCsr = membaseCsr; pRsrc->iobaseCsr = iobaseCsr; pRsrc->irq = irq; pRsrc->irqvec = irq + EXT_INTERRUPT_BASE; /* enable mapped memory and IO addresses */ pciConfigOutWord (pRsrc->pciBus, pRsrc->pciDevice, pRsrc->pciFunc, PCI_CFG_COMMAND, PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE); /* disable sleep mode */ pciConfigOutWord (pciBus, pciDevice, pciFunc, PCI_CFG_MODE, SLEEP_MODE_DIS); sysLan97xInitStrCook (pRsrc, unit); } return (OK); } /********************************************************************************* sysLan97xIntEnable - enable Lan97x interrupts** This routine enables ln7997x interrupts. This may involve operationson* interrupt control hardware.** RETURNS: OK or ERROR for invalid arguments.*/ STATUS sysLan97xIntEnable ( int level /* level number */ ) { return (sysIntEnablePIC(level)); } /********************************************************************************* sysLanIntDisable - disable ln970 interrupts** This routine disables ln970 interrupts. This may involve operationson* interrupt control hardware.** RETURNS: OK or ERROR for invalid arguments.*/ STATUS sysLan97xIntDisable ( int level /* level number */ ) { return (sysIntDisablePIC(level)); } /********************************************************************************* sysLan97xEnetAddrGet - get Ethernet address** This routine provides a target-specific interface for accessing a* device Ethernet address.** -- Specific to 971 ldt** RETURNS: OK or ERROR if could not be obtained.*/ STATUS sysLan97xEnetAddrGet ( LN_97X_DRV_CTRL * pDrvCtrl, /* Driver control */ char * enetAdrs ) { char aprom [LN_97X_APROM_SIZE]; /* copy of address prom space */ char * ioaddr; int ix; /* get IO address of unit */ ioaddr = (char *)(pDrvCtrl->devAdrs); /* load aprom into an array */ for (ix=0; ix<32; ix++) { SYS_IN_BYTE(pDrvCtrl,(ioaddr + ix), aprom [ix]); } /* check for 'w's at end of list */ if ((aprom [0xe] != 'W') || (aprom [0xf] != 'W')) { /* should set errno here ? ldt */ logMsg ("sysLn97XEnetAddrGet W's not stored in aprom\n", 0, 1, 2, 3, 4, 5); return ERROR; } bcopy (aprom, enetAdrs, 6); return (OK); } /********************************************************************************* sysLan97xInitStrCook - make the END load string for the device** The END device load string formed by this routine is in the following* following format.* <devMemAddr>:<devIoAddr>:<pciMemBase:<vecnum>:<intLvl>:<memAdrs>* :<memSize>:<memWidth>:<csr3b>:<offset>:<flags>** .IP <devMemAddr>* Device register base memory address* .IP <devIoAddr>* Device register base IO address* .IP <pciMemBase>* Base address of PCI memory space* .IP <vecNum>* Interrupt vector number.* .IP <intLvl>* Interrupt level.* .IP <memAdrs>* Memory pool address or NONE.* .IP <memSize>* Memory pool size or zero.* .IP <memWidth>* Memory system size, 1, 2, or 4 bytes (optional).* .IP <CSR3>* Value of CSR3 (for endian-ness mainly)* .IP <offset>* Offset of starting of data in the device buffers.* .IP <flags>* Device specific flags.** The endDevTbl entry is updated with the pointer to the load string* formed by this routine. This function expects all the ln97x entries* to declared in the endDevTbl to be contiguous.** NOTE* Note that this routine assumes that the entry for the END device is the* first entry in the in the END device table (endDevTbl[]).** RETURNS: N/A*/ LOCAL void sysLan97xInitStrCook ( LN_97X_PCI_RESOURCES * pRsrc, /* board resources */ int endDevNum /* lan device # found on PCI bus */ ) { int ix; int entryIxMax; END_TBL_ENTRY * pDevTbl; for (pDevTbl = endDevTbl, ix = 0; pDevTbl->endLoadFunc != END_TBL_END; pDevTbl++, ix++) ; /* max index of valid entry */ entryIxMax = ix - 1; for (pDevTbl = endDevTbl, ix = 0; pDevTbl->endLoadFunc != END_TBL_END; pDevTbl++, ix++) { if ((ix + endDevNum) > entryIxMax) break; if ((UINT32)pDevTbl->endLoadFunc == (UINT32)LN_97X_LOAD_FUNC) { pDevTbl->unit = endDevNum; sprintf (endDevTbl [ix + endDevNum].endLoadString, "0x%x:0x%x:0x%x:%d:%d:-1:-1:-1:0x%x:%d:0x%x", /* device memory Io base */ (UINT) pRsrc->membaseCsr + CPU_PCI_MEM_ADRS, /* device Io base */ (UINT) pRsrc->iobaseCsr + CPU_PCI_IO_ADRS, PCI2DRAM_BASE_ADRS, /* pciMemBase */ pRsrc->irqvec, /* interrupt IRQ vector */ pRsrc->irq, /* interrupt irq number */ LN97X_CSR3_VALUE, /* csr3 register value */ 0, /* offset */ NET_END_USER_FLAGS /* flags */ ); break; } } return; }#endif /* INCLUDE_LN_97X_END */#endif /* INCLUDE_END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -