?? ne2kif.c
字號:
/*
*********************************************************************************************************
* lwIP TCP/IP Stack
* port for uC/OS-II RTOS on TIC6711 DSK
*
* File : tcp_ip.c
* By : ZengMing @ DEP,Tsinghua University,Beijing,China
* Reference: YangYe's source code for SkyEye project
*********************************************************************************************************
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include <lwip/stats.h>
#include "netif/etharp.h"
#include "netif/ne2kif.h"
/* define this to use QDMA, which is much faster! */
#define QDMA_Enabled
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 't'
struct ne2k_if {
struct eth_addr *ethaddr; //MAC Address
};
struct netif *ne2k_if_netif;
/*----------------------------------------------------------------------------------------
****************************************************************************************
----------------------------------------------------------------------------------------*/
/*
* ethernetif_init():
*
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
*/
err_t ne2k_init(struct netif *netif)
{
struct ne2k_if *ne2k_if;
ne2k_if = mem_malloc(sizeof(struct ne2k_if));//MAC Address
if (ne2k_if == NULL)
{
LWIP_DEBUGF(NETIF_DEBUG,("ne2k_init: out of memory!\n"));
return ERR_MEM;
}
netif->state = ne2k_if;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = ne2k_output;
netif->linkoutput = low_level_output;
ne2k_if->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
low_level_init(netif);
etharp_init();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
return ERR_OK;
}
/**
* arp_timer.
*/
static void arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
}
/**
* Initialize the ne2k ethernet chip, resetting the interface and getting the ethernet
* address.
*/
static void low_level_init(struct netif * netif)
{
u16_t i;
struct ne2k_if *ne2k_if;
ne2k_if = netif->state;
// the meaning of "netif->state" can be defined in drivers, here for MAC address!
netif->hwaddr_len=6;
netif->mtu = 1500;
netif->flags = NETIF_FLAG_BROADCAST;
// ---------- start -------------
*(u32_t *)EMIF_CE2 = 0x11D4C714; // Set CE2 to 16bits mode,
// AX88796 required no less than 160ns period
i = EN_RESET; i++; //this instruction let NE2K chip soft reset
DSK6713_waitusec(20000);//wait 20ms //added for DSK6713 2005.10.21
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
EN0_DCFG = (u8_t) 0x01;
/* Clear the remote byte count registers. */
EN0_RCNTHI = (u8_t) 0x00; /* MSB remote byte count reg */
EN0_RCNTLO = (u8_t) 0x00; /* LSB remote byte count reg */
/* RX configuration reg Monitor mode (no packet receive) */
EN0_RXCR = (u8_t) ENRXCR_MON;
/* TX configuration reg set internal loopback mode */
EN0_TXCR = (u8_t) ENTXCR_LOOP;
EN0_TPSR = (u8_t) 0x40; //發(fā)送緩沖首地址 大小為6頁,剛好是1個最大包
//為0x40-0x46
EN0_STARTPG = (u8_t) 0x46 ; /* 接收緩沖 47。Starting page of ring buffer. First page of Rx ring buffer 46h*/
EN0_BOUNDARY = (u8_t) 0x46 ; /* Boundary page of ring buffer 0x46*/
EN0_STOPPG = (u8_t) 0x80 ; /* Ending page of ring buffer ,0x80*/
EN0_ISR = (u8_t) 0xff; /* clear the all flag bits in EN0_ISR */
EN0_IMR = (u8_t) 0x00; /* Disable all Interrupt */
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
EN1_CURR = (u8_t) 0x47; /* keep curr=boundary+1 means no new packet */
EN1_PAR0 = (u8_t)0x12;// MAC_addr.addr[0]; //自定義的mac地址
EN1_PAR1 = (u8_t)0x34;// MAC_addr.addr[1];
EN1_PAR2 = (u8_t)0x56;// MAC_addr.addr[2];
EN1_PAR3 = (u8_t)0x78;// MAC_addr.addr[3];
EN1_PAR4 = (u8_t)0x9a;// MAC_addr.addr[4];
EN1_PAR5 = (u8_t)0xe0;// MAC_addr.addr[5];
/* make up an address. */
ne2k_if->ethaddr->addr[0] = (u8_t) 0x12;//MAC_addr.addr[0];
ne2k_if->ethaddr->addr[1] = (u8_t) 0x34;//MAC_addr.addr[1];
ne2k_if->ethaddr->addr[2] = (u8_t) 0x56;//MAC_addr.addr[2];
ne2k_if->ethaddr->addr[3] = (u8_t) 0x78;//MAC_addr.addr[3];
ne2k_if->ethaddr->addr[4] = (u8_t) 0x9a;//MAC_addr.addr[4];
ne2k_if->ethaddr->addr[5] = (u8_t) 0xe0;//MAC_addr.addr[5];
/* Initialize the multicast list to reject-all.
If we enable multicast the higher levels can do the filtering.
<multicast filter mask array (8 bytes)> */
EN1_MAR0 = (u8_t) 0x00;
EN1_MAR1 = (u8_t) 0x00;
EN1_MAR2 = (u8_t) 0x00;
EN1_MAR3 = (u8_t) 0x00;
EN1_MAR4 = (u8_t) 0x00;
EN1_MAR5 = (u8_t) 0x00;
EN1_MAR6 = (u8_t) 0x00;
EN1_MAR7 = (u8_t) 0x00;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
EN0_TXCR = (u8_t) 0x00; //E0 //TCR
EN0_RXCR = (u8_t) 0x44; //CC //RCR
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
EN0_ISR = (u8_t) 0xff; // clear the all flag bits in EN0_ISR
ne2k_if_netif = netif;
}
/*----------------------------------------------------------------------------------------
****************************************************************************************
----------------------------------------------------------------------------------------*/
/*
* ethernetif_output():
*
* This function is called by the TCP/IP stack when an IP packet
* should be sent. It calls the function called low_level_output() to
* do the actual transmission of the packet.
*
*/
static err_t
ne2k_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr)
{
/* resolve hardware address, then send (or queue) packet */
return etharp_output(netif, ipaddr, p);
}
/*
* low_level_output():
*
* Should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
*/
static err_t low_level_output(struct netif * netif, struct pbuf *p)
{
struct pbuf *q;
u16_t packetLength,remote_Addr,Count;
u8_t *buf;
packetLength = p->tot_len - ETH_PAD_SIZE; //05 01 millin
if ((packetLength) < 64) packetLength = 64; //add pad by the AX88796 automatically
// turn off RX int
EN0_IMR = (u8_t) (ENISR_OVER);
/* We should already be in page 0, but to be safe... */
EN_CMD = (u8_t) (EN_PAGE0 + EN_START + EN_NODMA);
// clear the RDC bit
EN0_ISR = (u8_t) ENISR_RDC;
remote_Addr = (u16_t)(TX_START_PG<<8);
/*
* Write packet to ring buffers.
*/
for(q = p; q != NULL; q = q->next) {
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
Count = q->len;
buf = q->payload;
if (q == p){
buf += ETH_PAD_SIZE;
Count -= ETH_PAD_SIZE;//Pad in Eth_hdr struct
}
// Write data to AX88796
remote_Addr = write_AX88796(buf, remote_Addr, Count);
} //for
/* Just send it, and does not check */
while (EN_CMD & EN_TRANS);
EN0_TPSR = (u8_t) TX_START_PG;
EN0_TCNTLO = (u8_t) (packetLength & 0xff);
EN0_TCNTHI = (u8_t) (packetLength >> 8);
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_TRANS + EN_START);
EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
#if LINK_STATS
lwip_stats.link.xmit++;
#endif /* LINK_STATS */
return ERR_OK;
}
/**
* write_AX88796.
*/
u16_t write_AX88796(u8_t * buf, u16_t remote_Addr, u16_t Count)
{
#ifndef QDMA_Enabled
u16_t loop;
#endif
/* AX88796. */
EN0_RCNTLO = (u8_t) ( Count & 0xff);
EN0_RCNTHI = (u8_t) ( Count >> 8);
EN0_RSARLO = (u8_t) ( remote_Addr & 0xff);
EN0_RSARHI = (u8_t) ( remote_Addr >> 8);
EN_CMD = (u8_t) (EN_RWRITE + EN_START + EN_PAGE0);
// Add for next loop...
remote_Addr += Count;
Count = (Count + 1) >> 1; // Turn to 16bits count. <Must add 1 first!>
#ifdef QDMA_Enabled
*(u32_t *)QDMA_SRC = (u32_t) buf;
*(u32_t *)QDMA_DST = (u32_t) &EN_DATA;
*(u32_t *)QDMA_CNT = (u32_t) Count;
*(u32_t *)QDMA_IDX = 0x00000000;
*(u32_t *)QDMA_S_OPT = 0x29000001;
#else
for (loop=0;loop < Count ;loop++){
EN_DATA = *(u16_t *)buf;
buf += 2;
}
#endif //QDMA_Enabled
while ((EN0_ISR & ENISR_RDC) == 0);
EN0_ISR = (u8_t) ENISR_RDC;
return remote_Addr;
}
/*----------------------------------------------------------------------------------------
****************************************************************************************
----------------------------------------------------------------------------------------*/
/*
* ethernetif_input():
*
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface.
*
*/
static void
ne2k_input(struct netif *netif)
{
struct ne2k_if *ne2k_if;
struct eth_hdr *ethhdr;
struct pbuf *p;
ne2k_if = netif->state;
/* move received packet into a new pbuf */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -