📄 lan91c111.c
字号:
/*
* Ethernet card over the Au1xxx Static Bus
* version date description author
* -------+------+-----------------------------------+------
* 0.1 080104 initial write-up for YAMON kcn
*
* [References]
* (1) SMSC LAN91C111 10/100 Non-PCI Ethernet Single Chip MAC + PHY Rev. 1.4(12-12-03)
*/
#include <string.h>
#include <stdio.h>
#include <init.h>
#include <sysdefs.h>
#include <syserror.h>
#include <sysdev.h>
#include <io_api.h>
#include <syscon_api.h>
#include <sys_api.h>
#include <lan_api.h>
#include <lan_lan91c111_api.h>
/* To pick-up LAN91C111_ADDR */
#include <pb1000.h>
/*****************************************************
* SMS Data Sturctures and Registers (see Chapter 8)
*****************************************************/
/* frame format in buffer memory
* HWORD
* -----------------
* status word[16:0]
* rsv + byte count[11:0]
* data 2042 byte
* control byte[15:8] + padding byte if odd
*/
/*
* Bank Select register
*/
#define BANK_7 (7)
#define BANK_3 (3)
#define BANK_2 (2)
#define BANK_1 (1)
#define BANK_0 (0)
#define BANK_REG_MAGIC_NUM (0x33)
#define BANK_REG_MASK (0x07)
#define BANK_SELECT(n) (n & BANK_REG_MASK)
/* no sanity check for the value */
#define select(bank) (lan91c111->BANK = bank)
/***************************************************
* data frame registers' definitions
*****************************************************/
/*
* control by te register
* TX: ODD and CRC
* RX: ODD only
*/
/* indicating extra padding byte */
#define CONTROL_BYTE_ODD (1 << 5)
/* CRC bit (only if TCR is set) */
#define CONTROL_BYTE_CRC (1 << 4)
/*
* Receive Frame Status reg
*/
#define RFS_ALIGNERROR (1 << 15)
#define RFS_BROADCAST (1 << 14)
#define RFS_BADCRC (1 << 13)
#define RFS_ODDFRM (1 << 12)
#define RFS_TOOLONG (1 << 11)
#define RFS_TOOSHORT (1 << 10)
#define RFS_MULTCAST (1 << 0)
#define RFS_HASH (0x7f << 1)
#define RFS_ALL_ERRORS (RFS_ALIGNERROR | RFS_BADCRC | RFS_TOOLONG | RFS_TOOSHORT)
#define FRAME_BYTECOUNT_MASK (0x3ff)
/**********************************************
* Bank registers' definitions
**********************************************/
/* bank 0 transmit control register: offset=0 */
#define TCR_SWFDUP (1 << 15) /* */
#define TCR_EPH_LOOP (1 << 13) /* internal PHY loopback */
#define TCR_STPSQET (1 << 12) /* stop tx on SQET err */
#define TCR_FDUPLX (1 << 11)
#define TCR_MONCSN (1 << 10) /* */
#define TCR_NOCRC (1 << 8) /* */
#define TCR_PAD_EN (1 << 7) /* enable padding to add upto 64byte */
#define TCR_FORCOL (1 << 2) /* force collision */
#define TCR_LOOP (1 << 1) /* loopback */
#define TCR_TXEN (1 << 0) /* */
/****************************************/
/* bank 0 EPH status register: offset=2 */
#define ESR_TXUNRN (1 << 15) /* tx underrun */
#define ESR_LINKOK (1 << 14) /* */
#define ESR_CTR_ROL (1 << 12) /* roll over 4bit counter */
#define ESR_EXC_DEF (1 << 11) /* excessive deferral */
#define ESR_LOST_CARR (1 << 10) /* */
#define ESR_LOTCAL (1 << 9) /* late collision detected */
#define ESR_TX_DEFR (1 << 7) /* tx deferred */
#define ESR_LTX_BRD (1 << 6) /* last tx was a broadcast */
#define ESR_SQET (1 << 5) /* signal quality error test */
#define ESR_16COL (1 << 4) /* reached 16 collisions */
#define ESR_LTX_MULT (1 << 3) /* last tx was a multicast */
#define ESR_MULT_COL (1 << 2) /* detected multiple collision */
#define ESR_SNGL_COL (1 << 1) /* detected single collision */
#define ESR_TX_SUC (1 << 0) /* last tx was successfully */
/*********************************************/
/* bank 0 recieve control register: offset=4 */
#define RCR_SOFTRST (1 << 15) /* */
#define RCR_FILT_CAR (1 << 14) /* filter carrier */
#define RCR_ABORT_ENB (1 << 13) /* enable abort of receive when collision occurs */
// PLL gain can be changed!
#define RCR_STRIP_CRC (1 << 9) /* */
#define RCR_RXEN (1 << 8) /* */
#define RCR_ALMUL (1 << 2) /* accept all multicast frames */
#define RCR_PRMS (1 << 1) /* promiscuous mode */
#define RCR_RX_ABORT (1 << 0) /* */
/*************************************/
/* bank 0 counter register: offset=6 */
#define CTR_TX_EXC_DEFFERED_MASK (0x0f << 12)
#define CTR_TX_DEFFERED_MASK (0x0f << 8)
#define CTR_MULTIPLE_COLLISION_COUNT_MASK (0x0f << 4)
#define CTR_SINGLE_COLLSION_COUNT_MASK (0x0f << 0)
/************************************************/
/* bank 0 memory infromation register: offset=8 */
#define MIR_AVALI_FREE_MEMORY_MASK (0xff00 << 8)
#define MIR_MEMORY_SIZE_MASK (0x00ff << 0)
/****************************************************/
/* bank 0 receive/phy control register: offset=0x0a */
#define RPCR_SPEED (1 << 13) /* */
#define RPCR_DPLX (1 << 12) /* */
#define RPCR_ANEG (1 << 11) /* auto negotiation */
#define RPCR_LS2A (1 << 7) /* LED signal secelt */
#define RPCR_LS1A (1 << 6) /* LED signal secelt */
#define RPCR_LS0A (1 << 5) /* LED signal secelt */
#define LEDA_LINK (0x0 << 5)
#define RPCR_LS2B (1 << 4) /* LED signal secelt */
#define RPCR_LS1B (1 << 3) /* LED signal secelt */
#define RPCR_LS0B (1 << 2) /* LED signal secelt */
#define LEDB_ACTIVITY (0x10)
/*******************************************/
/* bank 1 configuration register: offset=0 */
#define CFG_EPHPOWEREN (1 << 15) /* EPH low power mode: active Low */
#define CFG_NOWAIT (1 << 12) /* no wait */
#define CFG_GPCNTRL (1 << 10) /* general purpose port control */
#define CFG_EXTPHY (1 << 9) /* enable external phy */
/******************************************/
/* bank 1 base address register: offset=2 */
// none
/****************************************/
/* bank 1 individual register: offset=4 */
// none
/*********************************************/
/* bank 1 general purpose register: offset=a */
// none
/*************************************/
/* bank 1 control register: offset=c */
#define CTL_RX_BAD (1 << 14) /* bad crc */
#define CTL_AUTO (1 << 11) /* after tx completion, release TX pages */
#define CTL_LE_EN (1 << 7) /* enable link error */
#define CTL_CR_EN (1 << 6) /* enable counter rollover */
#define CTL_TE_EN (1 << 5) /* enable tx error */
#define CTL_EEPROM (1 << 2) /* eeprom select */
#define CTL_RELOAD (1 << 1) /* reload from eeprom */
#define CTL_STORE (1 << 0) /* store to eeprom */
/*****************************************/
/* bank 2 MMU command register: offset=0 */
#define MMU_CMD_MASK (0x00e0)
#define MMU_CMD_SIZE_MASK (0x07)
#define MMU_CMD_SET(cmd) ((cmd & MMU_CMD_SIZE_MASK) << 5)
#define MMU_BUSY (1 << 0)
/*
* MMU commands
*/
#define MMU_CMD_NOP (0 << 5) /* no op */
#define MMU_CMD_TX_ALLOC (1 << 5) /* allocate tx mem */
#define MMU_CMD_RESET_MMU (2 << 5) /* reset */
#define MMU_CMD_RX_FIFO_FLASH (3 << 5) /* remove frame from top of rx fifo */
#define MMU_CMD_RX_FIFO_RELEASE (4 << 5) /* remove and release top of rx fifo */
#define MMU_CMD_RELEASE_PACKET (5 << 5) /* release specific packet */
#define MMU_CMD_TX_FIFO_ENQUEUE (6 << 5) /* enqueue packet # into tx fifo */
#define MMU_CMD_TX_FIFO_RESET (7 << 5) /* reset tx fifos */
/*******************************************/
/* bank 2 packet number register: offset=2. bit6 masked */
#define TX_PACKET_NUM_MASK (0x7f)
/* bank 2 allocation result register: offset=3 */
#define TX_ALLOCATION_FAILED (1 << 7)
#define ALLOCATED_PACKET_NUM_MASK (0x7f)
/*************************************/
/* bank 2 RX+TX FIFO register: offset=4 */
#define RX_FIFO_EMPTY (1 << 7)
#define RX_FIFO_NUMBER_MASK (0x7f)
/* bank 2 TX FIFO register: offset=5 */
#define TX_FIFO_EMPTY (1 << 7)
#define TX_FIFO_NUMBER_MASK (0x7f)
/*****************************************/
/* bank 2 pointer register: offset=6 */
#define PR_RCV (1 << 15) /* */
#define PR_AUTO_INC (1 << 14) /* */
#define PR_READ (1 << 13) /* */
#define PR_ETEN (1 << 12) /* */
#define PR_NOTEMPTY (1 << 11) /* */
#define PR_POINTER_MASK (0x07ff) /* */
/* bank 2 data register: 0x08 to 0x0b */
// none
/*************************************************/
/* bank 2 interrupt status register: offset=0x0c */
/*************************************************/
/* bank 2 interrupt status register: offset=0x0c */
#define ISR_MD_INT (1 << 7) /* MII register 18 changed */
#define ISR_ERX_INT (1 << 6) /* early rx interrupt*/
#define ISR_EPH_INT (1 << 5) /* ethernet protocol handler interrupt */
#define ISR_RX_OVERRUN_INT (1 << 4) /* rx overrun */
#define ISR_ALLOC_INT (1 << 3) /* successful mmu tx allocation */
#define ISR_TX_EMPTY_INT (1 << 2) /* tx fifo empty */
#define ISR_TX_INT (1 << 1) /* underrun, sqe err, lost carrier, late col 16 col */
#define ISR_RX_INT (1 << 0) /* */
/***********************************************/
/* bank 2 interrupt mask register: offset=0x0d */
#define IMR_MD_INT (1 << 7)
#define IMR_ERX_INT (1 << 6)
#define IMR_EPH_INT (1 << 5)
#define IMR_RX_OVERRUN_INT (1 << 4)
#define IMR_ALLOC_INT (1 << 3)
#define IMR_TX_EMPTY_INT (1 << 2)
#define IMR_TX_INT (1 << 1)
#define IMR_RX_INT (1 << 0)
/***************************************************/
/* bank 3 multicast table registers: offset=0 to 7 */
// none
/**************************************************/
/* bank 3 management interface register: offset=8 */
#define MIR_MSK_CRS100 (1 << 15) /* disable crs100 detection in tx half dplx */
#define MIR_MASK (0x000f)
#define MIR_MDOE (1 << 3) /* MDO enabled */
#define MIR_MDOZ (0 << 3) /* MDO Hi-Z */
#define MIR_MCLK (1 << 2) /* mii management inut */
#define MIR_MCLK_L (0)
#define MIR_MCLK_H (1)
#define MIR_MCLK_CYCLE (3)
#define MIR_MDI (1 << 1) /* mii management clock */
#define MIR_MDO (1 << 0) /* enable mii management output */
#define MIR_MDO_ZERO (0 << 0) /* Write 0 */
#define MIR_MDO_ONE (1 << 0) /* Write 1 */
#define RESERVED_MIR_VALUE (0x3330)
/*****************************************/
/* bank 3 revision register: offset=0x0a */
/* chip id
* SMC91C92 =>3
* SMC91C94 =>4
* SMC91C95 =>5
* SMC91C100 =>7
* SMC91C111 =>9
*
* revision id
* A => 0x00
* B => 0x01
*/
#define RR_CHIP_MASK (0xf0)
#define RR_REV_MASK (0x0f)
/******************************************/
/* bank 3 early RCV register: offset=0x0c */
#define ERR_RX_DISCARD (1 << 7) /* discard the current rx frame */
#define ERR_ERX_THRESHOLD_MASK (0x01f) /* threshold of erx interrupt, multipled by 64 * n */
/********************************************/
/* bank 7 external registers: offset=0 to 7 */
// none
/*****************************************************
* mac related definitions
*****************************************************/
/*
* internal buffers
*/
/* additional 6 byte frame header => rounded up to 32 byte */
#define RX_BUFF_SIZE (2048 + 32)
#define RX_CIRCULAR_BUFFERS (4)
/*****************************************************
* io reg related definitions
*****************************************************/
typedef volatile struct LAN91C111
{
union
{
struct /* BANK 0 */
{
UINT16 TCR_0;
UINT16 EPH_0;
UINT16 RCR_0;
UINT16 COUNTER_0;
UINT16 MIR_0;
UINT16 RPCR_0;
UINT16 RESERVED_0;
};
struct /* BANK 1 */
{
UINT16 CONFIG_1;
UINT16 BASE_1;
union
{
struct
{
UINT16 IA01_1;
UINT16 IA23_1;
UINT16 IA45_1;
};
struct
{
#ifdef EL
UINT8 IA0_1;
UINT8 IA1_1;
UINT8 IA2_1;
UINT8 IA3_1;
UINT8 IA4_1;
UINT8 IA5_1;
#endif
#ifdef EB
UINT8 IA1_1;
UINT8 IA0_1;
UINT8 IA3_1;
UINT8 IA2_1;
UINT8 IA5_1;
UINT8 IA4_1;
#endif
};
};
UINT16 GENERAL_1;
UINT16 CONTROL_1;
};
struct /* BANK 2 */
{
UINT16 MMU_2;
union
{
UINT16 PNR_2;
struct
{
#ifdef EL
UINT8 PNRLO_2;
UINT8 PNRHI_2;
#endif
#ifdef EB
UINT8 PNRHI_2;
UINT8 PNRLO_2;
#endif
};
};
union
{
UINT16 FIFO_2;
struct {
#ifdef EL
UINT8 FIFOLO_2;
UINT8 FIFOHI_2;
#endif
#ifdef EB
UINT8 FIFOHI_2;
UINT8 FIFOLO_2;
#endif
};
};
UINT16 POINTERS_2;
union
{
UINT16 DATA_2;
struct {
#ifdef EL
UINT8 DATALO_2;
UINT8 DATAHI_2;
#endif
#ifdef EB
UINT8 DATAHI_2;
UINT8 DATALO_2;
#endif
};
};
UINT16 DATA2_2;
union
{
UINT16 INTERRUPT_2;
struct
{
#ifdef EL
UINT8 INTMASKLO_2;
UINT8 INTMASKHI_2;
#endif
#ifdef EB
UINT8 INTMASKHI_2;
UINT8 INTMASKLO_2;
#endif
};
};
};
struct /* BANK 3 */
{
UINT16 MT01_3;
UINT16 MT23_3;
UINT16 MT45_3;
UINT16 MT67_3;
UINT16 MGMT_3;
UINT16 REVISION_3;
UINT16 ERCV_3;
};
};
UINT16 BANK;
} LAN91C111;
/* The SMS device is actually a little-endian format device, for
EB accesses to its data port, bytes must be swapped since the
packets are a stream of bytes, and not 16-bit quantities */
#ifdef EB
#define __SWAP16(X) ( (((X)&0xFF)<<8) | (((X)>>8)&0xFF) )
#else
#define __SWAP16(X) X
#endif
/*****************************************************
* app related definitions
*****************************************************/
enum { MMU_ALLOC_OK = 0, MMU_ALLOC_BUSY, MMU_ALLOC_FAILED };
enum { MMU_NOWAIT = 0, MMU_WAIT };
/************************************************************************
* Constant Definitions
*************************************************************************/
enum
{
LAN91C111_0_MINOR_DEVICE = 0,
/******* ADD NEW MINOR DEVICES JUST BEFORE THIS LINE ONLY ********/
LAN91C111_MINOR_DEVICE
};
/************************************************************************
* Macro Definitions
*************************************************************************/
#define IF_ERROR( completion, function ) \
{ \
completion = function ; \
if ( completion != OK ) \
{ \
return( completion ) ; \
} \
}
/* Global driver states - the numbers are arbitrary */
#define LAN91C111_DRIVER_IS_STOPPED (0x42)
#define LAN91C111_DRIVER_IS_STARTED (0x44)
/************************************************************************
* Type Definitions
*************************************************************************/
/*
* Network device statistics.
*/
typedef struct net_device_stats
{
unsigned long rx_packets; /* total packets received */
unsigned long tx_packets; /* total packets transmitted */
unsigned long rx_bytes; /* total bytes received */
unsigned long tx_bytes; /* total bytes transmitted */
unsigned long rx_errors; /* bad packets received */
unsigned long tx_errors; /* packet transmit problems */
unsigned long multicast; /* multicast packets received */
unsigned long broadcast; /* broadcast packets received */
unsigned long collisions;
unsigned long tx_timeout_errors;
/* detailed rx_errors: */
unsigned long rx_align_error;
unsigned long rx_badcrc;
unsigned long rx_toolong;
unsigned long rx_tooshort;
/* not chip dependent error */
unsigned long rx_zero_length_errors;
unsigned long rx_buffer_length_errors;
/* detailed tx_errors */
unsigned long tx_under_run;
unsigned long tx_lost_carrier;
unsigned long tx_late_collision;
unsigned long tx_signal_quality;
unsigned long tx_16_collisions;
unsigned long tx_multiple_collisions;
unsigned long tx_single_collision;
} t_net_device_stats ;
/* Device context for a SMS LAN controller */
typedef struct LAN91C111_device
{
UINT32 NextRxBuffer;
UINT32 rx_buffer_addr[RX_CIRCULAR_BUFFERS];
UINT8 rx_buffer_pool[(RX_BUFF_SIZE * RX_CIRCULAR_BUFFERS) + 32];
t_mac_addr PhysicalAddress;
/* network statistics */
t_net_device_stats status ;
} t_LAN91C111_device ;
/* Transmit status bits */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -