⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_ebsa285.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 5 页
字号:
//==========================================================================
//
//      if_ebsa285.c
//
//	Ethernet drivers
//	Intel EBSA285 and PRO/100+ platform specific support
//
//==========================================================================
//####COPYRIGHTBEGIN####
//                                                                          
// -------------------------------------------                              
// The contents of this file are subject to the Red Hat eCos Public License 
// Version 1.1 (the "License"); you may not use this file except in         
// compliance with the License.  You may obtain a copy of the License at    
// http://www.redhat.com/                                                   
//                                                                          
// Software distributed under the License is distributed on an "AS IS"      
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
// License for the specific language governing rights and limitations under 
// the License.                                                             
//                                                                          
// The Original Code is eCos - Embedded Configurable Operating System,      
// released September 30, 1998.                                             
//                                                                          
// The Initial Developer of the Original Code is Red Hat.                   
// Portions created by Red Hat are                                          
// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.
// All Rights Reserved.                                                     
// -------------------------------------------                              
//                                                                          
//####COPYRIGHTEND####
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD or other sources,
// and are covered by the appropriate copyright disclaimers included herein.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    hmt, gthomas
// Contributors: Ron Spence, Pacific Softworks
// Date:         2000-02-01
// Purpose:      
// Description:  hardware driver for 82559 Intel PRO/100+ ethernet and
//               Intel StrongARM EBSA-285 development boards
//              
//
//####DESCRIPTIONEND####
//
//==========================================================================

#include <pkgconf/system.h>
#include <pkgconf/devs_eth_arm_ebsa285.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/cyg_ass.h>
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/infra/diag.h>
#include <cyg/hal/drv_api.h>
#include <netdev.h>
#include <eth_drv.h>

#ifdef CYGPKG_NET
#include <pkgconf/net.h>
#include <net/if.h>  /* Needed for struct ifnet */
#else
#include <cyg/hal/hal_if.h>
#define diag_printf printf
#endif

#ifdef CYGPKG_IO_PCI
#include <cyg/io/pci.h>
// So we can check the validity of the PCI window against the MLTs opinion,
// and thereby what the malloc heap consumes willy-nilly:
#include CYGHWR_MEMORY_LAYOUT_H
#else
#error "Need PCI package here"
#endif

// Exported statistics and the like
#include <cyg/devs/eth/ebsa285_info.h>
#include <eth_drv_stats.h>

// ------------------------------------------------------------------------

#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_CHATTER
#define notDEBUG_82559 // This one prints stuff as packets come and go
#define DEBUG          // Startup printing mainly
#define DEBUG_EE       // Some EEPROM specific retries &c
#endif

#define os_printf diag_printf
#define db_printf diag_printf

// ------------------------------------------------------------------------
// I/O access macros as inlines for type safety

static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)
{   *((volatile cyg_uint8 *)io_address) = value;    }

static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)
{   *((volatile cyg_uint16 *)io_address) = value;   }

static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address)
{   *((volatile cyg_uint32 *)io_address) = value;   }

static inline cyg_uint8 INB(cyg_uint32 io_address)
{   return *((volatile cyg_uint8 *)io_address);     }

static inline cyg_uint16 INW(cyg_uint32 io_address)
{   return *((volatile cyg_uint16 *)io_address);    }

static inline cyg_uint32 INL(cyg_uint32 io_address)
{   return *((volatile cyg_uint32 *)io_address);    }

#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_))
static inline cyg_uint32 virt_to_bus(cyg_uint32 p_memory)
{    return (p_memory - CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE);    }

#define BUS_TO_VIRT( _x_ ) bus_to_virt((cyg_uint32)(_x_))
static inline cyg_uint32 bus_to_virt(cyg_uint32 p_memory)
{    return (p_memory + CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE);    }


// ------------------------------------------------------------------------
//                                                                      
//                   82559 REGISTER OFFSETS (I/O SPACE)                 
//                                                                      
// ------------------------------------------------------------------------
#define SCBStatus       0               // Rx/Command Unit command and status.
#define SCBCmd          2               // Rx/Command Unit command and status.
#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_TX (SCB_STATUS_CX | SCB_STATUS_CNA)
#define SCB_INTACK_RX (SCB_STATUS_FR | SCB_STATUS_RNR)

// ------------------------------------------------------------------------
//
//               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  (2) // Delay between clock edges *and* data
                             // read or transition; 3 of these per bit.
#define EEPROM_DONE_DELAY (100) // Delay when all done


// ------------------------------------------------------------------------
//
//               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 SCB_M	        0x0100          // 0 = enable interrupt, 1 = disable
#define SCB_SI          0x0200          // 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

// ------------------------------------------------------------------------
//
//               RECEIVE FRAME DESCRIPTORS
//
// ------------------------------------------------------------------------
typedef struct rfd {
    volatile union {
        cyg_uint32 u32_status;         // result of receive operation
        cyg_uint16 u16_status[2];
    } u_status;
    volatile cyg_uint32 link;           // offset from RU base to next RFD
    volatile cyg_uint32 rdb_address;    // pointer to Rx data buffer
    volatile cyg_uint32 count:14,       // number of bytes received +
        f:1,                            //   + EOF & F flags
        eof:1,
            size:16;                    // size of the data buffer
    volatile cyg_uint8 buffer[0];       // data buffer (simple mode)
} RFD;

// 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.

#define rxstatus    u_status.u32_status
#define rxstatus_hi u_status.u16_status[1]
#define rxstatus_lo u_status.u16_status[0]

#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_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


typedef struct rbd {
    volatile cyg_uint32 count:14,       // bytes used in buffer
        f:1,                            // buffer has been used (filled)
        eof:1;                          // last receive buffer in frame
    volatile cyg_uint32 next_rbd;       // next RBD (RU base relative)
    volatile cyg_uint32 buffer_address; // address of receive data buffer
    volatile cyg_uint32 size:15,        // size of the associated buffer
        el:1;                           // buffer of this RBD is last
} RBD;


// ------------------------------------------------------------------------
//
//               TRANSMIT FRAME DESCRIPTORS
//
// ------------------------------------------------------------------------
typedef struct txcb {
    volatile cyg_uint32 txstatus:16,      // result of transmit operation
        command:16;                     // transmit command
    volatile cyg_uint32 link;           // offset from RU base to next RFD
    volatile cyg_uint32 tbd_address;    // pointer to Rx data buffer
    volatile cyg_uint32 count:15,       // number of bytes in transmit buffer
        eof:1,
        tx_threshold:8,
        tbd_number:8;
    volatile cyg_uint8 buffer[0];       // data buffer (simple mode)
} TxCB;


#define TxCB_CMD_TRANSMIT   0x0004      // transmit command
#define TxCB_CMD_SF         0x0008      // 0=simplified, 1=flexible mode
#define TxCB_CMD_NC         0x0010      // 0=CRC insert by controller
#define TxCB_CMD_I          0x2000      // generate interrupt on completion
#define TxCB_CMD_S          0x4000      // suspend on completion
#define TxCB_CMD_EL         0x8000      // last command block in CBL


// ------------------------------------------------------------------------
//
//                   STRUCTURES ADDED FOR PROMISCUOUS MODE
//
// ------------------------------------------------------------------------
typedef struct {
    cyg_uint32 cb_status_word:13,
        cb_ok:1,
        cb_dc:1,
        cb_complete:1,
        cb_cmd:3,
        cb_cmd_word:10,
        cb_int:1,
        cb_suspend:1,
        cb_el:1;
    cyg_uint32 cb_link_offset;
} CB_STRUCT;


typedef struct {
    CB_STRUCT cb_entry;
    cyg_uint8 config_bytes[24];
} CONFIG_CMD_STRUCT;

// ------------------------------------------------------------------------
//
//                       STATISTICAL COUNTER STRUCTURE
//
// ------------------------------------------------------------------------
#ifdef KEEP_STATISTICS
STATISTICS statistics[2];
I82559_COUNTERS i82559_counters[2];
#endif // KEEP_STATISTICS

// ------------------------------------------------------------------------
//
//                      DEVICES AND PACKET QUEUES
//
// ------------------------------------------------------------------------

⌨️ 快捷键说明

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