?? ne2kif.c
字號:
//yangye , 2003-1-21
//ne2k driver for lwip(OS independent)
#include "debug.h"
#include "opt.h"
#include "def.h"
#include "ip.h"
#include "mem.h"
#include "pbuf.h"
#include "sys.h"
#include "cc.h"
#include "ne2kif.h"
#include "etharp.h"
#include "../uhal/uhal.h"
#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v))
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
#define __arch_getb(a) (*(volatile unsigned char *)(a))
#define __arch_getl(a) (*(volatile unsigned int *)(a))
#define outb(v,a) __arch_putb(v,a)
#define inb(a) __arch_getb(a)
//struct eth_hdr *ethhdr1;
struct RTL8019if {
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
};
// qhy const struct eth_addr ethbroadcast = {0xff,0xff,0xff,0xff,0xff,0xff};
const struct eth_addr ethbroadcast = {0xff,0xff,0xff,0xff,0xff,0xff};
struct netif *rtl8019if_netif; //points to the real netif ,used by ne2k_isr
static void ne2k_copyin(u16_t count, u8_t *buf);
static void ne2k_copyout(u16_t count, u8_t *buf);
static void ne2k_discard(u16_t count);
void ne2k_isr(void);
void qhyne2k(void);
static void low_level_init(struct netif * netif);
static struct pbuf * low_level_receive(struct RTL8019if *rtl8019if);
static err_t low_level_send(struct RTL8019if *rtl8019if,struct pbuf *p);
INT8U AA,BB,CC;
//INT8U TEMPHEAD[20];
//u8_t PDHeader[18];
/*
* Read the specified number of bytes from the device DMA port into
* the supplied buffer.
*/
static void ne2k_copyin(u16_t count, u8_t *buf)
{
while(count--) {
*buf++ = inb(NE_DMA);
}
}
/*
* Write the specified number of bytes from the device DMA port into
* the supplied buffer.
*/
static void ne2k_copyout(u16_t count, u8_t *buf)
{
while(count--) {
outb(*buf++,NE_DMA);
}
}
/*
* Pull the specified number of bytes from the device DMA port,
* and throw them away.
*/
static void ne2k_discard(u16_t count)
{
u8_t tmp;
while(count--) {
tmp = inb(NE_DMA);
}
}
void qhyne2k(void)
{
outb(0xff,NE_ISR);
}
// void NICISR(void) interrupt
void ne2k_isr(void)
{
u8_t isr,curr,bnry;
struct netif *netif;
//close nic
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
//uHALr_printf("QHY NE2K INTERUPT NE_CR=%x\n",inb(NE_CR));
//in PAGE0
isr = inb(NE_ISR);
//uHALr_printf("NE_ISR=%x\n",isr);
// ram overflow interrupt
if (isr & ISR_OVW) {
outb(ISR_OVW,NE_ISR); // clear interrupt
// ne2k_overflowProcess(); //yangye :no overflow now
}
// error transfer interrupt ,NIC abort tx due to excessive collisions
if (isr & ISR_TXE) {
outb(ISR_TXE,NE_ISR); // clear interrupt
//temporarily do nothing
}
// Rx error , reset BNRY pointer to CURR (use SEND PACKET mode)
if (isr & ISR_RXE) {
outb(ISR_RXE,NE_ISR); // clear interrupt
outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP,NE_CR);
curr = inb(NE_CURR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
outb(curr, NE_BNRY);
}
//got packet with no errors
if (isr & ISR_PRX) {
// uHALr_printf("aaaaaaaaaaaaaa is isr_prx\n");
outb(ISR_PRX, NE_ISR); // clear interrupt
outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
curr = inb(NE_CURR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
bnry = inb(NE_BNRY);
//yangye 2003-1-21
//get more than one packet until receive buffer is empty
while(curr != bnry){
// uHALr_printf("aaaaaaaaaaaaaa is isr_prx\n");
ne2k_recv_packet(rtl8019if_netif);
//uHALr_printf("bbbbbbbbbbbbbbbb is \n");
outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
curr = inb(NE_CURR);
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
bnry = inb(NE_BNRY);
}
}
//Transfer complelte, do nothing here
if( isr & ISR_PTX){
uHALr_printf("ne2k_isr: is ISR_PTX\n");
outb(ISR_PTX, NE_ISR); // clear interrupt
}
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
outb(0xff, NE_ISR); // clear ISR
//open nic for next packet
outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);
// uHALr_printf("the progame is NE2000CARD INTERUPTT \n");
}
/**
* Initialize the rtk8019as, resetting the interface and getting the ethernet
* address.
*/
static void SetRegPage(u8_t PageIdx)
{
u8_t temp;
temp=inb(NE_CR);
temp=(temp&0x3b)|(PageIdx<<6);
outb(temp,NE_CR);
}
static void low_level_init(struct netif * netif)
{
u8_t i;
struct RTL8019if *rtl8019if;
u8_t mac_addr[6];
outb(0x22, NE_CR);
rtl8019if = netif->state;
netif->hwaddr_len=6;
netif->hwaddr[0]=0x03;
netif->hwaddr[1]=0x01;
netif->hwaddr[2]=0x00;
netif->hwaddr[3]=0xea;
netif->hwaddr[4]=0x48;
netif->hwaddr[5]=0xf3;
netif->mtu=1500;
//netif->hwaddr_len=6;
//yangye 2003-1-21
//get mac addr from ne2k PROM
//ft! sim_ne2k not support dma read now!
//hack : manual write mac addr
//{
mac_addr[0] = 0x03;
mac_addr[1] = 0x01;
mac_addr[2] = 0x00;
mac_addr[3] = 0xea;
mac_addr[4] = 0x48;
mac_addr[5] = 0xf3;
//}
//to do: add dam read for sim_ne2k
/* make up an address. */
rtl8019if->ethaddr->addr[0] = mac_addr[0];
rtl8019if->ethaddr->addr[1] = mac_addr[1];
rtl8019if->ethaddr->addr[2] = mac_addr[2];
rtl8019if->ethaddr->addr[3] = mac_addr[3];
rtl8019if->ethaddr->addr[4] = mac_addr[4];
rtl8019if->ethaddr->addr[5] = mac_addr[5];
uHALr_printf("\nISEN2000MACADDR\n");
/*
* Initialize physical device
*/
//write and read 0x1f to reset the nic
outb(0, NE_RESET);
inb(NE_RESET);
for(i=0; i < 40; i++) //delay at least 10ms
;
//in PAGE0
outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP, NE_CR);
/* FIFO threshold = 8 bytes, normal operation, 8-bit byte write DMA, BOS=0 */
outb(DCR_LS | DCR_FIFO8, NE_DCR);
outb(0, NE_RBCR0);
outb(0, NE_RBCR1);
#if 0 //yangye: don't use in skyeye , maybe later
/*
* Promicuous receive(receive all the packets), including bad packets.
*/
outb(RCR_AB | RCR_AM | RCR_SEP | RCR_PRO, NE_RCR);
#else
/*
* Allow broadcast packets, in addition to packets unicast to us.
* Multicast packets that match MAR filter bits will also be
* allowed in.
*/
outb(RCR_AB, NE_RCR);
#endif
//Place the SNIC in LOOPBACK mode 1 or 2 (Transmit Configuration Register e 02H or 04H)
outb(TCR_LOOP_INT, NE_TCR);
outb(XMIT_START >> 8, NE_TPSR);
outb(RECV_START >> 8, NE_PSTART);
outb(RECV_START >> 8, NE_BNRY);
outb(RECV_STOP >> 8, NE_PSTOP);
//in PAGE1
outb(CMD_PAGE1 | CMD_NODMA | CMD_STOP, NE_CR);
outb(RECV_START >> 8, NE_CURR);
/*
* Set physical address here.(not use 93c46)
*/
//SetRegPage(1);
outb(0x03, NE_PAR0);
outb(0x01, NE_PAR1);
outb(0x00, NE_PAR2);
outb(0xea, NE_PAR3);
outb(0x48, NE_PAR4);
outb(0xf3, NE_PAR5);
//Clear multicast filters.(reject all multicast)
//outb(0, NE_MAR0); outb(0, NE_MAR1);
//outb(0, NE_MAR2); outb(0, NE_MAR3);
//outb(0, NE_MAR4); outb(0, NE_MAR5);
//outb(0, NE_MAR6); outb(0, NE_MAR7);
//select PAGE0 and start the nic
outb(CMD_PAGE0 | CMD_NODMA | CMD_RUN, NE_CR);
//set Interrupt mask reg
outb(ISR_OVW | ISR_TXE | ISR_PTX | ISR_PRX, NE_IMR);
outb(TCR_LOOP_NONE, NE_TCR);
//clear all interrupts
outb(0xff, NE_ISR);
//enable at91 int 16 for sim_ne2k
//enbale_net_irq;
rtl8019if_netif = netif;
}
/*
* Function to do the actual writing of a packet into the devices
* transmit buffer. INT is disable during the function!!!!
*/
static err_t
low_level_send(struct RTL8019if *rtl8019if,struct pbuf *p)
{
struct pbuf *q;
u8_t isr;
u16_t padLength,packetLength;
/*
* Set up to transfer the packet contents to the NIC RAM.
*/
padLength = 0;
packetLength = p->tot_len;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -