if_i82559.c

来自「开放源码实时操作系统源码.」· C语言 代码 · 共 1,724 行 · 第 1/5 页

C
1,724
字号
// access.  But the 8-bit access to *(char *)&i also uses 0x1000 for the
// address as the code sees it, the memory system sees a byte request for
// address 0x1003, thus picking up the MSbyte, from data[24:31].
//
// For such addressing, offsets need to be redefined to swap bytes and
// shorts within words.  Therefore offsets are defined twice, once for
// "normal" addressing, and once for "GIB endian" addressing.
//
// FIXME: this BE/GE configuration probably won't work with an ARM in its
// BE mode - because that will define the global BE flags, yet it's not
// true BE, it's GE.
// Perhaps a solution whereby the GE flag CYG_ADDRESSING_IS_GIBENDIAN
// overrides the BYTEORDER choices would be good; we want the constants to
// be LE, but address offsets to be swapped per GE.
//
// 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));
}
#else

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 );   }

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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?