📄 if_i82559.c
字号:
//// Essay ends.//// ------------------------------------------------------------------------// I/O access macros as inlines for type safety#if (CYG_BYTEORDER == CYG_MSBFIRST)#define HAL_CTOLE32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))#define HAL_LE32TOC(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))#define HAL_CTOLE16(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))#define HAL_LE16TOC(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))#else// Maintaining the same styleee as above...#define HAL_CTOLE32(x) ((((x))))#define HAL_LE32TOC(x) ((((x))))#define HAL_CTOLE16(x) ((((x))))#define HAL_LE16TOC(x) ((((x))))#endif#if (CYG_BYTEORDER == CYG_MSBFIRST) && !defined(CYGHWR_DEVS_ETH_INTEL_I82559_ENDIAN_NEUTRAL_IO)static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address){ HAL_WRITE_UINT8( io_address, value);}static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address){ HAL_WRITE_UINT16( io_address, (((value & 0xff) << 8) | ((value & 0xff00) >> 8)) );}static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address){ HAL_WRITE_UINT32( io_address, ((((value) & 0xff) << 24) | (((value) & 0xff00) << 8) | (((value) & 0xff0000) >> 8) | (((value) >> 24) & 0xff)) );}static inline cyg_uint8 INB(cyg_uint32 io_address){ cyg_uint8 d; HAL_READ_UINT8( io_address, d ); return d;}static inline cyg_uint16 INW(cyg_uint32 io_address){ cyg_uint16 d; HAL_READ_UINT16( io_address, d ); return (((d & 0xff) << 8) | ((d & 0xff00) >> 8));}static inline cyg_uint32 INL(cyg_uint32 io_address){ cyg_uint32 d; HAL_READ_UINT32( io_address, d ); return ((((d) & 0xff) << 24) | (((d) & 0xff00) << 8) | (((d) & 0xff0000) >> 8) | (((d) >> 24) & 0xff));}#elsestatic inline void OUTB(cyg_uint8 value, cyg_uint32 io_address){ HAL_WRITE_UINT8( io_address, value ); }static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address){ HAL_WRITE_UINT16( io_address, value ); }static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address){ HAL_WRITE_UINT32( io_address, value ); }static inline cyg_uint8 INB(cyg_uint32 io_address) { cyg_uint8 _t_; HAL_READ_UINT8( io_address, _t_ ); return _t_; }static inline cyg_uint16 INW(cyg_uint32 io_address) { cyg_uint16 _t_; HAL_READ_UINT16( io_address, _t_ ); return _t_; }static inline cyg_uint32 INL(cyg_uint32 io_address) { cyg_uint32 _t_; HAL_READ_UINT32( io_address, _t_ ); return _t_; }#endif // byteorder// ------------------------------------------------------------------------// Macros for writing shared memory structures - no need for byte flipping#define READMEM8( _reg_, _val_ ) ((_val_) = *((volatile CYG_BYTE *)(_reg_)))#define WRITEMEM8( _reg_, _val_ ) (*((volatile CYG_BYTE *)(_reg_)) = (_val_))#define READMEM16( _reg_, _val_ ) ((_val_) = *((volatile CYG_WORD16 *)(_reg_)))#define WRITEMEM16( _reg_, _val_ ) (*((volatile CYG_WORD16 *)(_reg_)) = (_val_))#define READMEM32( _reg_, _val_ ) ((_val_) = *((volatile CYG_WORD32 *)(_reg_)))#define WRITEMEM32( _reg_, _val_ ) (*((volatile CYG_WORD32 *)(_reg_)) = (_val_))// ------------------------------------------------------------------------// Map from CPU-view addresses to PCI-bus master's view - however that is:#ifdef CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS#define VIRT_TO_BUS( _x_ ) CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ )#else // use default mappings: get a physical address to give to the device#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_))static inline cyg_uint32 virt_to_bus(cyg_uint32 p_memory){ return CYGARC_PHYSICAL_ADDRESS(p_memory); }#endif // not defined CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS// ------------------------------------------------------------------------// // 82559 REGISTER OFFSETS (I/O SPACE) // // ------------------------------------------------------------------------#define SCBStatus 0 // Rx/Command Unit Status *Word*#define SCBIntAckByte 1 // Rx/Command Unit STAT/ACK byte#define SCBCmd 2 // Rx/Command Unit Command *Word*#define SCBIntrCtlByte 3 // Rx/Command Unit Intr.Control Byte#define SCBPointer 4 // General purpose pointer.#define SCBPort 8 // Misc. commands and operands.#define SCBflash 12 // Flash memory control.#define SCBeeprom 14 // EEPROM memory control.#define SCBCtrlMDI 16 // MDI interface control.#define SCBEarlyRx 20 // Early receive byte count.#define SCBGenControl 28 // 82559 General Control Register#define SCBGenStatus 29 // 82559 General Status register// ------------------------------------------------------------------------//// 82559 SCB STATUS WORD DEFNITIONS//// ------------------------------------------------------------------------#define SCB_STATUS_CX 0x8000 // CU finished command (transmit)#define SCB_STATUS_FR 0x4000 // frame received#define SCB_STATUS_CNA 0x2000 // CU left active state#define SCB_STATUS_RNR 0x1000 // receiver left ready state#define SCB_STATUS_MDI 0x0800 // MDI read/write cycle done#define SCB_STATUS_SWI 0x0400 // software generated interrupt#define SCB_STATUS_FCP 0x0100 // flow control pause interrupt#define SCB_INTACK_MASK 0xFD00 // all the above#define SCB_INTACK_MASK_BYTE 0xFD // all the above#define SCB_INTACK_TX (SCB_STATUS_CX | SCB_STATUS_CNA)#define SCB_INTACK_RX (SCB_STATUS_FR | SCB_STATUS_RNR)// ------------------------------------------------------------------------//// SYSTEM CONTROL BLOCK COMMANDS//// ------------------------------------------------------------------------// CU COMMANDS#define CU_NOP 0x0000#define CU_START 0x0010#define CU_RESUME 0x0020#define CU_STATSADDR 0x0040 // Load Dump Statistics ctrs addr#define CU_SHOWSTATS 0x0050 // Dump statistics counters.#define CU_ADDR_LOAD 0x0060 // Base address to add to CU commands#define CU_DUMPSTATS 0x0070 // Dump then reset stats counters.// RUC COMMANDS#define RUC_NOP 0x0000#define RUC_START 0x0001#define RUC_RESUME 0x0002#define RUC_ABORT 0x0004#define RUC_ADDR_LOAD 0x0006 // (seems not to clear on acceptance)#define RUC_RESUMENR 0x0007#define CU_CMD_MASK 0x00f0#define RU_CMD_MASK 0x0007#define SCB_M 0x0100 // 0 = enable interrupt, 1 = disable#define SCB_SWI 0x0200 // 1 - cause device to interrupt#define SCB_BYTE_M 0x01 // 0 = enable interrupt, 1 = disable#define SCB_BYTE_SWI 0x02 // 1 - cause device to interrupt#define CU_STATUS_MASK 0x00C0#define RU_STATUS_MASK 0x003C#define RU_STATUS_IDLE (0<<2)#define RU_STATUS_SUS (1<<2)#define RU_STATUS_NORES (2<<2)#define RU_STATUS_READY (4<<2)#define RU_STATUS_NO_RBDS_SUS ((1<<2)|(8<<2))#define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2))#define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2))#define MAX_MEM_RESERVED_IOCTL 1000// ------------------------------------------------------------------------//// 82559 PORT INTERFACE COMMANDS//// ------------------------------------------------------------------------#define I82559_RESET 0x00000000 // software reset#define I82559_SELFTEST 0x00000001 // 82559 selftest command#define I82559_SELECTIVE_RESET 0x00000002#define I82559_DUMP 0x00000003#define I82559_DUMP_WAKEUP 0x00000007// ------------------------------------------------------------------------//// 82559 EEPROM INTERFACE//// ------------------------------------------------------------------------// EEPROM_Ctrl bits.#define EE_SHIFT_CLK 0x01 // EEPROM shift clock.#define EE_CS 0x02 // EEPROM chip select.#define EE_DATA_WRITE 0x04 // EEPROM chip data in.#define EE_DATA_READ 0x08 // EEPROM chip data out.#define EE_ENB (0x4800 | EE_CS)// Delay between EEPROM clock transitions.#define eeprom_delay(usec) udelay(usec);// The EEPROM commands include the always-set leading bit.#define EE_WRITE_CMD(a) (5 << (a))#define EE_READ_CMD(a) (6 << (a))#define EE_ERASE_CMD(a) (7 << (a))#define EE_WRITE_EN_CMD(a) (19 << ((a)-2))#define EE_WRITE_DIS_CMD(a) (16 << ((a)-2))#define EE_ERASE_ALL_CMD(a) (18 << ((a)-2))#define EE_TOP_CMD_BIT(a) ((a)+2) // Counts down to zero#define EE_TOP_DATA_BIT (15) // Counts down to zero#define EEPROM_ENABLE_DELAY (10) // Delay at chip select#define EEPROM_SK_DELAY (4) // Delay between clock edges *and* data // read or transition; 3 of these per bit.#define EEPROM_DONE_DELAY (100) // Delay when all done// ------------------------------------------------------------------------//// RECEIVE FRAME DESCRIPTORS//// ------------------------------------------------------------------------// The status is split into two shorts to get atomic access to the EL bit;// the upper word is not written by the device, so we can just hit it,// leaving the lower word (which the device updates) alone. Otherwise// there's a race condition between software moving the end-of-list (EL)// bit round and the device writing into the previous slot.#if (CYG_BYTEORDER == CYG_MSBFIRST)// Note that status bits are endian converted - so we don't need to// fiddle the byteorder when accessing the status word!#define RFD_STATUS_EL 0x00000080 // 1=last RFD in RFA#define RFD_STATUS_S 0x00000040 // 1=suspend RU after receiving frame#define RFD_STATUS_H 0x00001000 // 1=RFD is a header RFD#define RFD_STATUS_SF 0x00000800 // 0=simplified, 1=flexible mode#define RFD_STATUS_C 0x00800000 // completion of received frame#define RFD_STATUS_OK 0x00200000 // frame received with no errors#define RFD_STATUS_HI_EL 0x0080 // 1=last RFD in RFA#define RFD_STATUS_HI_S 0x0040 // 1=suspend RU after receiving frame#define RFD_STATUS_HI_H 0x1000 // 1=RFD is a header RFD#define RFD_STATUS_HI_SF 0x0800 // 0=simplified, 1=flexible mode#define RFD_STATUS_LO_C 0x0080 // completion of received frame#define RFD_STATUS_LO_OK 0x0020 // frame received with no errors#define RFD_COUNT_MASK 0x3fff#define RFD_COUNT_F 0x4000#define RFD_COUNT_EOF 0x8000#define RFD_RX_CRC 0x00080000 // crc error#define RFD_RX_ALIGNMENT 0x00040000 // alignment error#define RFD_RX_RESOURCE 0x00020000 // out of space, no resources#define RFD_RX_DMA_OVER 0x00010000 // DMA overrun#define RFD_RX_SHORT 0x80000000 // short frame error#define RFD_RX_LENGTH 0x20000000 //#define RFD_RX_ERROR 0x10000000 // receive error#define RFD_RX_NO_ADR_MATCH 0x04000000 // no address match#define RFD_RX_IA_MATCH 0x02000000 // individual address does not match#define RFD_RX_TCO 0x01000000 // TCO indication#else // Little-endian#define RFD_STATUS_EL 0x80000000 // 1=last RFD in RFA#define RFD_STATUS_S 0x40000000 // 1=suspend RU after receiving frame#define RFD_STATUS_H 0x00100000 // 1=RFD is a header RFD#define RFD_STATUS_SF 0x00080000 // 0=simplified, 1=flexible mode#define RFD_STATUS_C 0x00008000 // completion of received frame#define RFD_STATUS_OK 0x00002000 // frame received with no errors#define RFD_STATUS_HI_EL 0x8000 // 1=last RFD in RFA#define RFD_STATUS_HI_S 0x4000 // 1=suspend RU after receiving frame#define RFD_STATUS_HI_H 0x0010 // 1=RFD is a header RFD#define RFD_STATUS_HI_SF 0x0008 // 0=simplified, 1=flexible mode#define RFD_STATUS_LO_C 0x8000 // completion of received frame#define RFD_STATUS_LO_OK 0x2000 // frame received with no errors#define RFD_COUNT_MASK 0x3fff#define RFD_COUNT_F 0x4000#define RFD_COUNT_EOF 0x8000#define RFD_RX_CRC 0x00000800 // crc error#define RFD_RX_ALIGNMENT 0x00000400 // alignment error#define RFD_RX_RESOURCE 0x00000200 // out of space, no resources#define RFD_RX_DMA_OVER 0x00000100 // DMA overrun#define RFD_RX_SHORT 0x00000080 // short frame error#define RFD_RX_LENGTH 0x00000020 //#define RFD_RX_ERROR 0x00000010 // receive error#define RFD_RX_NO_ADR_MATCH 0x00000004 // no address match#define RFD_RX_IA_MATCH 0x00000002 // individual address does not match#define RFD_RX_TCO 0x00000001 // TCO indication#endif // CYG_BYTEORDER#ifndef CYG_ADDRESSING_IS_GIBENDIAN// Normal addressing#define RFD_STATUS 0#define RFD_STATUS_LO 0#define RFD_STATUS_HI 2#define RFD_LINK 4#define RFD_RDB_ADDR 8#define RFD_COUNT 12#define RFD_SIZE 14#define RFD_BUFFER 16#define RFD_SIZEOF 16#else // CYG_ADDRESSING_IS_GIBENDIAN// GIBENDIAN addressing; A0 and A1 are flipped:#define RFD_STATUS 0#define RFD_STATUS_LO 2 // swapped#define RFD_STATUS_HI 0 // swapped#define RFD_LINK 4#define RFD_RDB_ADDR 8#define RFD_COUNT 14 // swapped#define RFD_SIZE 12 // swapped#define RFD_BUFFER 16#define RFD_SIZEOF 16#endif // CYG_ADDRESSING_IS_GIBENDIAN// ------------------------------------------------------------------------//// TRANSMIT FRAME DESCRIPTORS//// ------------------------------------------------------------------------#if (CYG_BYTEORDER == CYG_MSBFIRST)// Note that CMD/STATUS bits are endian converted - so we don't need// to fiddle the byteorder when accessing the CMD/STATUS word!#define TxCB_CMD_TRANSMIT 0x0400 // transmit command
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -