📄 drv8139.c
字号:
/****************************************************************************
* 文件名称?8139.c
* 文件说明?realtek8139网口芯片的pSOS驱动程序的源程序,包括NI接口,对8139芯片的操做,
* pSOS的pNA+模块通过NI接口使用本驱动程序收发网络数据。
***************************************************************************/
#include "rtl8139.h"
#include <_null.h>
#include <tmlib/dprintf.h>
#include <tm1/mmio.h>
#define _8139_DEBUG 0
//---------------------------------------------------------------------
// Symbol & Macro definitions
//---------------------------------------------------------------------
#define CR_BUFE 1 //receive buffer is empty
#define TSD_OWN 1 << 13 //trimedia owns descriptor
#define ISR_ROK 1 //receive ok
#define ISR_RER 1 << 1 //receive error
#define ISR_TOK 1 << 2 //transmit ok
#define ISR_TER 1 << 3 //transmit error
#define ISR_RXOVW 1 << 4 //receive buffer overflow
#define ISR_LNKCHG 1 << 5 //link change
#define ISR_FOVW 1 << 6 //receive fifo overflow
#define ISR_SERR 1 << 15 //PCI system error
#define ISR_NIS ISR_ROK|ISR_TOK //normal interrupt
#define ISR_AIS ISR_RER|ISR_TER|ISR_RXOVW|ISR_LNKCHG|ISR_FOVW|ISR_SERR //abnormal interrupt
#define LAN_IP 0x0800 /* IP type */
#define LAN_ARP 0x0806 /* ARP type */
#define LAN_RARP 0x8035 /* RARP type */
#define ALIGN(addr, bndry) (void *)((addr + bndry - 1) & ~(bndry - 1))
#define NUM_TX_DESC 4 //number of transmit descriptor
#define TX_BUF_SIZE 1792 //size of transmit buffer
//#define RECV_BUF_64K
#ifndef RECV_BUF_64K
#define RX_BUF_SIZE 32*1024 + 16 //size of receive buffer
#else
#define RX_BUF_SIZE 64*1024 + 16 //size of receive buffer
//#error "RECV_BUF_64K"
#endif
//---------------------------------------------------------------------
// Possible lan speeds.
//---------------------------------------------------------------------
#define MBPS10 10000000 //10M
#define MBPS100 100000000 //100M
#define LanType REALTEK_8139_ID
// 全局变量可被系统的主控任务引用
extern unsigned int H323StackCommandQue,H323StackResponseQue;
unsigned long DefGateWay = DEFAULT_GATEWAY ; //default gateway ip address
unsigned long LanIPaddr = DEFAULT_LAN_IP ; //local ip address
//add by zhengkun
static char ArpReqFlag = 0; //0:正常 1:停用别人 2:停用自己
static UCHAR HisMacAddr[6] = {0x00,0x00,0x00,0x00,0x00,0x00} ; //对方Mac地址
//---------------------------------------------------------------------
// The Ethernet hardware address can be changed in the startup dialog
//---------------------------------------------------------------------
UCHAR SelfAddr[6] = {0x01,0x02,0x03,0x04,0x05,0x06} ;//{0x00, 0xb0, 0xd0, 0x3c, 0xe3, 0xee};
static UCHAR Broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static UCHAR ArpPacket[64];//arp packet
//Structure for accessing Ethernet address as both words and bytes(hardware address).
typedef union
{
UCHAR byte[6];
struct
{
USHORT word1;
USHORT word2;
USHORT word3;
} a;
} LAN_HWA;
#define word1 a.word1
#define word2 a.word2
#define word3 a.word3
//TRANSMIT HEADERS
typedef volatile struct TxHdr // (64 bytes)
{
LAN_HWA daddr; //Ethernet destination address (6 bytes)
LAN_HWA saddr; //Ethernet source address (6 bytes)
USHORT type; //IP, ARP, or RARP (2 bytes)
UCHAR fill[34]; //fills struct to 64 bytes (34 bytes)
mblk_t *msg_ptr; //ptr to rest of msg (triplet) (4 bytes)
ULONG len; //# of descriptors required (4 bytes)
ULONG NoRetFlag; //TRUE: don't return *msg_ptr (4 bytes)
volatile struct TxHdr *next; //ptr to next hdr in free list (4 bytes)
} LAN_TX_HDR;
//Define transmit headers & transmission related variables
static LAN_TX_HDR *TxHdrFreeHead; //free list of transmit headers
static LAN_TX_HDR *TxHdrOutHead; //head of hdrs awaiting descs
static LAN_TX_HDR *TxHdrOutTail; //tail of hdrs awaiting descs
//Define Transmit Descriptors
static UCHAR *TxDesc[NUM_TX_DESC];
static USHORT CurDescId; //# Tx desc
//Holds the number of transmit descriptors and headers.
static ULONG TxNumHdrs;
static ULONG TxFreeHdrs;
static LAN_TX_HDR *TxHeaders;
unsigned int g_SendCount;
unsigned int myvideo_send_flag = 1;
//------------------------------------------------------------------------------
// add for support multicast by hanrui[2004-06-01]:
#define MULTICAST_ADDR_NUM 17
typedef struct tagMultiAddr
{
LAN_HWA addr ;
int is_used ;// 0: free; 1: used.
}MULTI_ADDR ;
MULTI_ADDR g_multi_addr[MULTICAST_ADDR_NUM] ;
//------------------------------------------------------------------------------
//RECEIVE BUFFERS
typedef volatile struct RxPkt // (1536 bytes)
{
LAN_HWA daddr; //Ethernet destination address (6 bytes)
LAN_HWA saddr; //Ethernet source address (6 bytes)
USHORT type; //IP, ARP, or RARP (2 bytes)
UCHAR fill1[2]; // (2 bytes)
UCHAR data[1500]; //frame data (1500 bytes)
UCHAR crc[4]; //lan chip generated (4 bytes)
UCHAR fill2[12]; //fills struct to 1536 bytes (12 bytes)
volatile struct RxPkt *next;
} LAN_RX_BUF;
//Define Receive Descriptors & receive related variables
static UCHAR *RxRing;
static USHORT RxOffset;
static ULONG RxNumHdrs;
static ULONG RxFreeHdrs;
static LAN_RX_BUF *RxHeaders;
static LAN_RX_BUF *RxPktFreeHead;
static LAN_RX_BUF *RxPktList; /* Rx Packet pool */
static LAN_RX_BUF *RecvPkt;
static int FreeRxPktCount;
static int recvpacket = 0;
extern unsigned long dtpq_id; //add by huangzhiqiang
extern UInt32 WaitSemaphore_Protocol;
int bLanCheck = 0;
int bFirst = 1;
//Miscellaneous Variables
static ULONG MissedFrames = 0; //#of receive frames missed
static long IfNum = 0; //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 int enet_nis = 0, enet_ais = 0, enet_rok = 0, enet_tok = 0, enet_rer = 0, enet_ter = 0;
static int enet_rxovw = 0, enet_fovw = 0, enet_timeout = 0, enet_serr = 0;
//MIB-Related Variables
static long ifadminstatus = 1;
static long InUnknownProtos = 0;
static long InOctets = 0;
static long OutOctets = 0;
static long InUcastPkts = 0;
static long OutUcastPkts = 0;
static long innucastpkts = 0;
static long outnucastpkts = 0;
static long InErrors = 0;
static long outerrors = 0;
static long lc_err = 0;
//---------------------------------------------------------------------
// Function Prototypes
//---------------------------------------------------------------------
static void bzero(UCHAR *ptr, int length);
static void LanPciInit(void);
static void LanInit(void);
static void InitBuffers(void);
static void LanChipReset(void);
//---------------------------------------------------------------------
// Ni interface routines
//---------------------------------------------------------------------
static long ni_init(void);
static long ni_send(char *hwa_p, char *pkb_p, USHORT len, USHORT type);
static void ni_isr(void);
static void ni_poll(void);
static ULONG ni_ioctl(long cmd, long *arg);
static void ni_pna_init(void);
//---------------------------------------------------------------------
// Packet reception processing routines
//---------------------------------------------------------------------
static void RxBufDetach(LAN_RX_BUF *env_ptr);
static void RxBufProc(UCHAR *RxPtr, USHORT length);
static void RxBufRcv(void);
static USHORT PacketOK(UCHAR *RecvBuf);
//---------------------------------------------------------------------
// Packet transmission processing routines
//---------------------------------------------------------------------
static void TxFillDesc(void);
static void TxBufAttach(LAN_TX_HDR *TxHdr);
//enable_tm_sdram_access and IE
static void enable_tm_sdram_access_ie();
//---------------------------------------------------------------------
// Multicast support routines
//---------------------------------------------------------------------
static unsigned char lan_mcast_ref[64];
static ULONG lan_mcast_hash_idx(UCHAR *);
static long lan_add_mcast(UCHAR *);
static ULONG map_mcast(struct ni_map_mcast *mmap);
static long lan_del_mcast(UCHAR *);
static void DP_SEND_BUF(UCHAR *Buf, int Len);
static void DP_RECV_BUF(UCHAR *Buf, int Len);
static void DP_MSG_BUF(mblk_t *msgBlk);
USHORT cksum(USHORT *addr, unsigned int count)
{
register USHORT sum = 0;
while (count-- > 0)
sum += *addr++;
sum = (sum >> 16) + (sum & 0xFFFF); /* This can only wrap twice */
return (sum >> 16) + (sum & 0xFFFF);
}
USHORT in_cksum2(unsigned short *addr, int len)
{
register int nleft = len;
register unsigned short *w = addr;
register int sum = 0;
unsigned short answer =0;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(UCHAR *)(&answer) = *(UCHAR *)w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = (~sum) & 0xFFFF;
return(answer);
}
USHORT in_cksum1(unsigned short *addr, int count)
{
/* Compute Internet Checksum for "count" bytes
* beginning at location "addr".
*/
register int sum = 0;
register USHORT checksum = 0;
while( count > 1 ) {
/* This is the inner loop */
sum += *addr++;
count -= 2;
}
/* Add left-over byte, if any */
if( count > 0 )
sum += * (unsigned char *) addr;
/* Fold 32-bit sum to 16 bits */
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
checksum = ~sum;
return checksum;
}
USHORT in_cksum( UCHAR *buff,int len_ip_header)
{
USHORT word16,checksum;
ULONG sum=0;
USHORT i;
// make 16 bit words out of every two adjacent 8 bit words in the packet
// and add them up
for (i=0;i<len_ip_header;i=i+2){
word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
sum = sum + (ULONG) word16;
}
// take only 16 bits out of the 32 bit sum
while (sum>>16)
sum = (sum & 0xFFFF)+(sum >> 16);
// one's complement the result
// sum = ~sum;
checksum = (~sum) & 0xFFFF;
return (checksum);
}
/****************************************************************************
* function name: MakeArpPacket
* design date:2001-8-17,
* function description: make arp request packet
* call: no
* called: ni_poll
* input parameter: no
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
void MakeArpPacket()
{
int i;
for(i = 0; i < 6; i++)
{
ArpPacket[i] = Broadcast[i];
ArpPacket[i+6] = SelfAddr[i];
}
ArpPacket[12] = 0x08;
ArpPacket[13] = 0x06;
ArpPacket[14] = 0x00;
ArpPacket[15] = 0x01;
ArpPacket[16] = 0x08;
ArpPacket[17] = 0x00;
ArpPacket[18] = 0x06;
ArpPacket[19] = 0x04;
ArpPacket[20] = 0x00;
ArpPacket[21] = 0x01;
for(i = 0; i < 6; i++)
ArpPacket[i+22] = SelfAddr[i];
ArpPacket[28] = (LanIPaddr >> 24) & 0xff;
ArpPacket[29] = (LanIPaddr >> 16) & 0xff;
ArpPacket[30] = (LanIPaddr >> 8) & 0xff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -