📄 dec21140.c
字号:
/***********************************************************************/
/* */
/* MODULE: net/dec21140.c */
/* DATE: 98/11/19 */
/* PURPOSE: Ethernet driver for the DEC D21140 */
/* */
/*---------------------------------------------------------------------*/
/* */
/* Copyright 1991 - 1997, Integrated Systems, Inc. */
/* ALL RIGHTS RESERVED */
/* */
/* Permission is hereby granted to licensees of Integrated Systems, */
/* Inc. products to use or abstract this computer program for the */
/* sole purpose of implementing a product based on Integrated */
/* Systems, Inc. products. No other rights to reproduce, use, */
/* or disseminate this computer program, whether in part or in */
/* whole, are granted. */
/* */
/* Integrated Systems, Inc. makes no representation or warranties */
/* with respect to the performance of this computer program, and */
/* specifically disclaims any responsibility for any damages, */
/* special or consequential, connected with the use of this program. */
/* */
/***********************************************************************/
#include "dec21140.h"
#include <tm1/tmInterrupts.h>
#include <tm1/mmio.h>
#include <ops/custom_defs.h>
#include <pna.h>
#include <sys_conf.h>
/***********************************************************************/
/* General Definitions */
/***********************************************************************/
#define UCHAR unsigned char
#define USHORT unsigned short
#define ULONG unsigned long
#define REG8(addr) *((volatile UCHAR *) addr)
#define REG16(addr) *((volatile USHORT *) addr)
#define REG32(addr) *((volatile ULONG *) addr)
#define LOOP_PER_NS 4
#define NSDELAY(nsec) {\
volatile int nx = 0;\
volatile int loop = (int)(nsec*LOOP_PER_NS);\
for (nx = 0; nx < loop; nx++);\
}
/*---------------------------------------------------------------------*/
/* Defines for MII PHY access */
/*---------------------------------------------------------------------*/
#define MII_REG_BMSR 0x1
#define MII_REG_PHYIDR1 0x2
#define MII_REG_ANLPAR 0x5
#define MII_REG_PAR 0x19
#define MII_WRITE ((ULONG)(0x00002000))
#define MII_READ ((ULONG)(0x00044000))
#define MII_WRITE_TS ((ULONG)(0x00042000))
#define MII_CLOCK ((ULONG)(0x00010000))
#define MII_DATA_IN ((ULONG)(0x00080000))
#define MII_WRITE_DATA ((ULONG)(0x00020000))
#define MII_READ_FRAME ((ULONG)(0x60000000))
#define MII_PRE ((ULONG)(0xFFFFFFFF))
#define MII_READ_DATA_MASK MII_DATA_IN
#define MII_WRITE_DATA_POSITION 17
#define REG_ADDR_ALIGN 18
#define MII_DATA_IN_POSITION 19
#define PHY_ADDR_ALIGN 23
#define MII_LINK_STATUS 0x4
/*---------------------------------------------------------------------*/
/* Bit 3 of BMSR indicates PHYS is able to perform auto negotiation. */
/*---------------------------------------------------------------------*/
#define MII_AUTO_NEGO_COMP 0x8
/*---------------------------------------------------------------------*/
/* After auto negotiation bit 8 (100BASE TX) and 6 (10BASE TX) of */
/* ANLPAR indicates that remote link supports full duplex. */
/*---------------------------------------------------------------------*/
#define MII_REMOTE_LINK_DUPLEX 0x140
/*---------------------------------------------------------------------*/
/* Bit 6 of PAR indicates current operational speed. 1==10, 0==100 */
/*---------------------------------------------------------------------*/
#define MII_LINK_SPD 0x40
#define MAX_LINK_TOUT 60 /* 6 second maximum link timeout */
/*---------------------------------------------------------------------*/
/* Possible lan speeds. */
/*---------------------------------------------------------------------*/
#define MBPS10 10000000
#define MBPS100 100000000
#define lanType DEC_21140_ID
/***********************************************************************/
/* Macro Definitions */
/***********************************************************************/
#define DN 8
#define WrPciCfg32(addr, val) pci_write_config_dword(0, DN, 0, addr, val)
#define WrPciCfg16(addr, val) pci_write_config_word(0, DN, 0, addr, val)
#define WrPciCfg8(addr, val) pci_write_config_byte(0, DN, 0, addr, val)
#define RdPciCfg32(addr) pci_read_config_dword(0, DN, 0, addr)
#define RdPciCfg16(addr) pci_read_config_word(0, DN, 0, addr)
#define RdPciCfg8(addr) pci_read_config_byte(0, DN, 0, addr)
/*---------------------------------------------------------------------*/
/* Ethernet hardware addr, and selection of whether to use 10BaseT */
/* or AUI interface for the LAN. Both of these variables are hardcoded*/
/* here, but when the same binary should run on a variety of machines */
/* (each with e.g. their own hardware address), then their values */
/* should be read from e.g a flash file at startup, in function */
/* 'lanInit'. */
/*---------------------------------------------------------------------*/
static UCHAR EtherHwAddr[6] = {0x00, 0x40, 0x05, 0xA4, 0x6D, 0xF8 };
#define Lan10BaseT 1
/*---------------------------------------------------------------------*/
/* Symbol & Macro definitions */
/*---------------------------------------------------------------------*/
#define LAN_IP 0x0800 /* IP type */
#define LAN_ARP 0x0806 /* ARP type */
#define LAN_RARP 0x8035 /* RARP type */
#define TRUE 1
#define FALSE 0
#ifndef NULL
#define NULL 0
#endif
#define ALIGN(addr, bndry) (void *)((addr + bndry - 1) & ~(bndry - 1))
/*---------------------------------------------------------------------*/
/* Structure for accessing Ethernet address as both words and bytes. */
/*---------------------------------------------------------------------*/
typedef union
{
UCHAR byte[BSP_LAN1_HWALEN];
struct
{
USHORT word1;
USHORT word2;
USHORT word3;
} a;
} LAN_HWA;
#define word1 a.word1
#define word2 a.word2
#define word3 a.word3
/***********************************************************************/
/* Global Variable Definitions */
/***********************************************************************/
/*---------------------------------------------------------------------*/
/* TRANSMIT HEADERS */
/*---------------------------------------------------------------------*/
/* When the driver is given a message to transmit, it must prepend an */
/* Ethernet header (fields "daddr", "saddr", and "type"). The transmit */
/* header structure provides a place to put this information. The */
/* transmit header also contains a pointer to the msg block triplet */
/* and a field indicating how many descriptors will be required to */
/* transmit the frame. */
/* */
/* When ni_send() is called, a transmit header is taken from the free */
/* list (pointed to by TxHdrFreeHead), and filled in with the info for */
/* the frame. Then it is put into a queue of headers awaiting */
/* transmission. TxHdrOutHead and TxHdrOutTail point to the head and */
/* tail of this list. */
/* */
/* TxFillDesc() takes the queued headers and sets up Lan buffer */
/* descriptors to point to the actual data buffers. A header will */
/* only be placed in the transmit descriptor ring when there are */
/* enough descriptors available to accomodate the entire message. This */
/* is to prevent partial frames from being sent. */
/* */
/* TxNumHdrs holds the number of transmit headers. It is set to be */
/* the same as the number of transmit buffer descriptors. Since an */
/* outgoing message will always require at least 2 descriptors (1 for */
/* the transmit header plus at least one for the message), there will */
/* be enough headers to allow queueing messages even if the buffer */
/* descriptor ring is full. */
/*---------------------------------------------------------------------*/
typedef volatile struct TxHdr
{
LAN_HWA daddr; /* Ethernet destination address */
LAN_HWA saddr; /* Ethernet source address */
USHORT type; /* IP, ARP, or RARP */
UCHAR fill[34]; /* fills struct to 64 bytes */
mblk_t *msg_ptr; /* ptr to rest of msg (triplet) */
ULONG num_desc; /* # of descriptors required */
ULONG NoRetFlag; /* TRUE: don't return *msg_ptr */
volatile struct TxHdr *next; /* ptr to next hdr in free list */
} LAN_TX_HDR;
/*---------------------------------------------------------------------*/
/* Define transmit headers & transmission related variables */
/*---------------------------------------------------------------------*/
LAN_TX_HDR *TxHdrFreeHead; /* free list of transmit headers*/
LAN_TX_HDR *TxHdrOutHead; /* head of hdrs awaiting descs */
LAN_TX_HDR *TxHdrOutTail; /* tail of hdrs awaiting descs */
/*---------------------------------------------------------------------*/
/* Define Transmit Descriptors */
/*---------------------------------------------------------------------*/
static LAN_BUFF_DESC *TxNewBD; /* ptr to next Tx desc to Xmit */
static LAN_BUFF_DESC *TxUsedBD; /* ptr to next Tx desc to reclm */
static ULONG TxFreeDesc; /* # free transmit descs */
static int enet_nis, enet_ais, enet_se, enet_ri, enet_ti;
static int enet_rwt, enet_tjt, enet_unf, enet_ru, enet_rps;
static int SROM_programmed = 1;
/*---------------------------------------------------------------------*/
/* RECEIVE BUFFERS */
/*---------------------------------------------------------------------*/
/* The driver maintains a pool of buffers into which incoming Ethernet */
/* packets are placed. The LAN's receive buffer descriptors are set */
/* to point to a group of these, and extras are kept in a free list. */
/* When a packet is received, a message block header is allocated from */
/* pNA and the receive buffer is taken from the LAN's circular list */
/* and attached to the message block header. Then the entire thing */
/* is given to pNA via the "announce packet" call. RxBufAttach() */
/* replenishes the LAN's circular list with buffers from the free */
/* list, if they are available. */
/* */
/* NOTE(1): Receive buffers are aligned on cache line boundaries. */
/* NOTE(2): The order of the fields is fixed by the Lan chip. */
/*---------------------------------------------------------------------*/
typedef volatile struct RxPkt
{
LAN_HWA daddr; /* Ethernet destination address */
LAN_HWA saddr; /* Ethernet source address */
USHORT type; /* IP, ARP, or RARP */
UCHAR data[1500]; /* frame data */
UCHAR crc[4]; /* lan chip generated */
UCHAR fill[14]; /* fills struct to 1536 bytes */
volatile struct RxPkt *next;
} LAN_RX_BUF;
/*---------------------------------------------------------------------*/
/* Define Receive Buffer headers and free list pointer */
/*---------------------------------------------------------------------*/
static LAN_RX_BUF *RxBufFreeHead; /* head of free list */
/*---------------------------------------------------------------------*/
/* Define Receive Descriptors & receive related variables */
/*---------------------------------------------------------------------*/
static LAN_BUFF_DESC *RxNextBD; /* ptr to next Rx desc to be full */
static LAN_BUFF_DESC *RxUsedBD; /* ptr to next Rx desc needing buf */
/*---------------------------------------------------------------------*/
/* Holds the number of transmit descriptors and headers. */
/*---------------------------------------------------------------------*/
static ULONG TxNumDesc;
static LAN_BUFF_DESC *TxDesc;
static ULONG TxNumHdrs;
static LAN_TX_HDR *TxHeaders;
/*---------------------------------------------------------------------*/
/* Holds the number of receive descriptors and buffers. */
/*---------------------------------------------------------------------*/
static int RxNumDesc;
static LAN_BUFF_DESC *RxDesc;
static int RxNumBufs;
static LAN_RX_BUF *RxBuffers;
/*---------------------------------------------------------------------*/
/* Miscellaneous Variables */
/*---------------------------------------------------------------------*/
static ULONG MissedFrames; /* # of receive frames missed */
static long IfNum; /* Interface # (pNA+ assigned) */
static LAN_HWA OurAddress; /* Our Ethernet address */
static struct ni_funcs NiFuncs; /* pNA+ func (esballoc,freemsg) */
/*---------------------------------------------------------------------*/
/* LAN speed, 10 or 100 Mbps. Default is 10. */
/*---------------------------------------------------------------------*/
static ULONG lan_spd = MBPS10;
static long (*Announce)(ULONG type, void *ptr, ULONG size, long if_num);
static UCHAR FlushFlag; /* True if tx buff descs being flushed */
/*---------------------------------------------------------------------*/
/* MIB-Related Variables */
/*---------------------------------------------------------------------*/
static long ifadminstatus;
static long InUnknownProtos;
static long InOctets, OutOctets;
static long InUcastPkts, OutUcastPkts;
static long innucastpkts, outnucastpkts;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -