📄 sysnetif.c
字号:
* routine called. In the PC environment, it is necessary for this routine* then to find the hardware corresponding to the given unit number, before* it can return the Ethernet address! This is done by the function* sysInitNecessary() (q.v.).** Here we blithely assume that sysInitNecessary() finds a unit for us,* as if no one would have attched the unit if it didn't exist!** RETURNS: OK or ERROR.** SEE ALSO:*/STATUS sysEnetAddrGet ( int unit, char addr[] ) { I596_INFO *pI596Info = &i596Info[unit]; UINT charIndex; /* * Find a physical board to go with this unit and set up the * I596_INFO structure to refer to that board. */ if (sysInitNecessary (unit) != OK) return (ERROR); for (charIndex = 0; charIndex < 6; charIndex++) addr[charIndex] = sysInByte (pI596Info->port + NET_IA0 + charIndex); return (OK); }/********************************************************************************* sys596Init - prepare a LAN board for Ethernet initialization** This routine performs target-specific initialization that must occur* before the Intel 82596 Ethernet chip is initialized. Typically, this* routine is empty.** The driver calls this routine from the eiattach() routine, once per unit,* immediately before starting up the Intel 82596. We here call* sysInitNecessary() again in case eiattach() hasn't called sysInetAddrGet()* yet.** RETURNS: OK or ERROR.** SEE ALSO: eiattach(), sysInitNecessary()*/STATUS sys596Init ( int unit /* unit number */ ) { I596_INFO *pI596Info = &i596Info[unit]; UCHAR intIndex; if (sysInitNecessary (unit) != OK) return (ERROR); if ( (sysInByte (pI596Info->port + IRQCTL) & IRQ_EXTEND) == 0) { intIndex = (sysInByte (pI596Info->port + PLX_CONF0) & (IRQ_SEL0 | IRQ_SEL1)) >> 1; } else { intIndex = ( (sysInByte (pI596Info->port + IRQCTL) & (IRQ_SEL0 | IRQ_SEL1)) >> 1) + 4; } pI596Info->ilevel = eex32IntLevel[intIndex]; sysIntEnablePIC (pI596Info->ilevel); return (OK); }/********************************************************************************* sys596IntAck - acknowledge an Ethernet chip interrupt ** This routine acknowledges any specified non-Intel 82596 Ethernet chip* interrupt. Typically, this involves an operation to some interrupt* control hardware.** The interrupt signal from the 82596 behaves in an "edge-triggered" mode;* therefore, this routine clears a latch within the control* circuitry.** NOTE: The driver calls this routine from the interrupt service routine.** RETURNS: OK, or ERROR if the */STATUS sys596IntAck ( int unit /* unit number */ ) { I596_INFO *pI596Info = &i596Info[unit]; if (pI596Info->type == TYPE_UNKNOWN) return (ERROR); sysOutByte (pI596Info->port + IRQCTL, sysInByte (pI596Info->port + IRQCTL) | IRQ_LATCH); return (OK); }/********************************************************************************* sys596IntEnable - enable an interrupt from an Intel 82596 Ethernet chip** This routine manipulates i386/i486 board hardware to permit an interrupt.** The Ethernet chip driver calls this routine throughout normal operation to* terminate critical sections of code.** RETURNS: OK, or ERROR if** SEE ALSO: sys596IntDisable*/STATUS sys596IntEnable ( int unit /* unit number */ ) { I596_INFO *pI596Info = &i596Info[unit]; if (pI596Info->type == TYPE_UNKNOWN) return (ERROR); sysOutByte (pI596Info->port + IRQCTL, sysInByte (pI596Info->port + IRQCTL) & ~IRQ_FORCE_LOW); return (OK); }/********************************************************************************* sys596IntDisable - disable an interrupt from an Intel 82596 Ethernet chip** This routine manipulates i386/i486 board hardware to prevent interrupts.** The Ethernet chip driver calls this routine throughout normal operation to* protect critical sections of code from interrupt service routine* intervention.** RETURNS: N/A** SEE ALSO: sys596IntEnable()*/void sys596IntDisable ( int unit /* unit number */ ) { I596_INFO *pI596Info = &i596Info[unit]; if (pI596Info->type == TYPE_UNKNOWN) return; sysOutByte (pI596Info->port + IRQCTL, sysInByte (pI596Info->port + IRQCTL) | IRQ_FORCE_LOW); }/********************************************************************************* sys596Port - issue PORT command to 82596** This routine provides access to the special port function of the Intel* 82596 Ethernet chip. The driver expects this routine to deliver the* command and address arguments to the port of the specified unit.** The Ethernet chip driver calls this routine primarily during* initialization, but may also call it during error recovery procedures.* Because it is called during initialization, this routine can be called* before the board for this unit has been found, depending on how eiattach()* might be modified in the future.** RETURNS: N/A*/void sys596Port ( int unit, int cmd, UINT32 addr ) { I596_INFO *pI596Info = &i596Info[unit]; if (sysInitNecessary (unit) != OK) /* Just in case not called yet! */ return; /* PORT command wants to see 16 bits at a time, low-order first */ sysOutWord (pI596Info->port + PORT, (cmd + addr) & 0xffff); sysOutWord (pI596Info->port + PORT + 2, ((cmd + addr) >> 16) & 0xffff); }/********************************************************************************* sys596ChanAtn - assert channel attention signal to an Intel 82596** This routine provides the channel attention signal to the Intel 82596* Ethernet chip for a specified unit.** The driver calls this routine frequently throughout all phases of* operation.** RETURNS: N/A*/void sys596ChanAtn ( int unit /* unit number */ ) { I596_INFO *pI596Info = &i596Info[unit]; if (pI596Info->type == TYPE_UNKNOWN) return; sysOutByte (pI596Info->port + CA, 0); }/********************************************************************************* sysInitNecessary - if unit is undefined, locate and set up the next board**/LOCAL STATUS sysInitNecessary ( int unit /* unit number */ ) { I596_INFO *pI596Info = &i596Info[unit]; if (pI596Info->type == TYPE_UNKNOWN) { if (sysFindEisaBoard (pI596Info, eex32IdString) == ERROR) return (ERROR); pI596Info->type = TYPE_EEX32; } /* Set up next unit structure in case there's another board */ if (unit < (MAX_UNITS - 1)) i596Info[unit + 1].port = i596Info[unit].port; return (OK); }/********************************************************************************* sysFindEisaBoard - scan selected EISA slots for a board with given ID bytes**/LOCAL STATUS sysFindEisaBoard ( I596_INFO *pI596Info, /* Start at I/O address in here */ UCHAR *idString ) { UINT byteNumber; BOOL failed; do { failed = FALSE; for (byteNumber = 0; (byteNumber < 4) && !failed; byteNumber++) { failed = (sysInByte (pI596Info->port + EISA_ID0 + byteNumber) != idString[byteNumber]); } if (!failed) return (OK); pI596Info->port += 0x1000; } while (pI596Info->port != 0xf000); return (ERROR); }#endif /* INCLUDE_EEX32 */#ifdef INCLUDE_END#ifdef INCLUDE_LN_97X_END #include "drv/end/ln97xEnd.h" /* defines */ /* Offsets of PCI resources in host space */ #ifndef CPU_PCI_IO_ADRS#define CPU_PCI_IO_ADRS 0 /* base of PCI I/O addr */#endif /* CPU_PCI_IO_ADRS */ #ifndef CPU_PCI_MEM_ADRS#define CPU_PCI_MEM_ADRS 0 /* base of PCI mem address */#endif /* CPU_PCI_MEM_ADRS */ #ifndef PCI2DRAM_BASE_ADRS#define PCI2DRAM_BASE_ADRS 0 /* DRAM base addrs from PCI */#endif /* PCI2DRAM_BASE_ADRS */ #ifndef CPU_PCI_ISA_IO_ADRS#define CPU_PCI_ISA_IO_ADRS 0 /* IO space */#endif /* CPU_PCI_ISA_IO_ADRS */ #define EXT_INTERRUPT_BASE INT_NUM_IRQ0 /* irq0 */ #define PCI_DEV_MMU_MSK (~(VM_PAGE_SIZE - 1)) /* Mask MMU page */ #define PCI_DEV_ADRS_SIZE VM_PAGE_SIZE /* one page */ /* PCI device configuration type definitions */ #ifndef PCI_CFG_TYPE#define PCI_CFG_TYPE PCI_CFG_NONE#endif /* AMD 7997x 10/100Base-TX Board type */ #define LN_TYPE_970 1 /* AMD 97c970 PCI Ethernet PCNet */#define LN_TYPE_971 2 /* AMD 97c970 PCI Ethernet PCNet Fast */#define LN_TYPE_972 3 /* AMD 97c970 PCI Ethernet PCNet Fast+ */#define LN_TYPE_7990 4 #define LN97X_MAX_UNITS 4 /* number of board types */ /* LN970 driver user flags */ #define LN_USR_FLAGS_970 0#define LN_USR_FLAGS_971 0#define LN_USR_FLAGS_972 0#define LN_USR_FLAGS_7990 0 /* PCI vendor/device Ids and rev mask */ #define LN97X_PCI_VENDOR_ID 0x1022 /* AMD */#define LN97X_PCI_DEVICE_ID 0x2000 /* PCI device ID */#define LN7990_PCI_DEVICE_ID 0x0000 /* PCI device ID */#define LN970_PCI_REV_MASK 0x10 /* 79970 pci rev mask */#define LN971_PCI_REV_MASK 0x20 /* 79971 pci rev mask */#define LN972_PCI_REV_MASK 0x30 /* 79972 pci rev mask */#define LN97X_CSR3_VALUE 0 /* csr3 value *//* * default values if PCI_CFG_TYPE defined to be PCI_CFG_FORCE * note: memory addresses must be aligned on MMU page boundaries */ #define LN97X_IO_ADR0 0xf400#define LN97X_MEM_ADR0 0xfd000000#define LN97X_INT_LVL0 0x0b#define LN97X_INT_VEC0 0 #define LN97X_IO_ADR1 0xf420#define LN97X_MEM_ADR1 0xfd200000#define LN97X_INT_LVL1 0x05#define LN97X_INT_VEC1 0 #define LN97X_IO_ADR2 0xf440#define LN97X_MEM_ADR2 0xfd300000#define LN97X_INT_LVL2 0x0c#define LN97X_INT_VEC2 0 #define LN97X_IO_ADR3 0xf460#define LN97X_MEM_ADR3 0xfd400000#define LN97X_INT_LVL3 0x9#define LN97X_INT_VEC3 0 #define LN97X_MAX_DEV 4 #define NET_END_USER_FLAGS LN_USR_FLAGS_972#define NET_ADAPTER_VENDOR_ID LN97X_PCI_VENDOR_ID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -