📄 ne2kif.c
字号:
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
EN0_RCNTLO = (u8_t) (packetLength & 0xff);
EN0_RCNTHI = (u8_t) (packetLength >> 8);
EN0_RSARLO = (u8_t) 4; /* See controller manual , use send packet command */
EN0_RSARHI = (u8_t) this_frame; /* See controller manual , use send packet command */
EN_CMD = (u8_t) (EN_PAGE0 + EN_RREAD + EN_START);
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, packetLength+ETH_PAD_SIZE, PBUF_POOL); /* length of buf */
// change from PBUF_LINK
if(p != NULL) {
/* We iterate over the pbuf chain until we have read the entire
packet into the pbuf. */
for(q = p; q != NULL; q= q->next){
/* Read enough bytes to fill this pbuf in the chain. The
avaliable data in the pbuf is given by the q->len
variable. */
payload = q->payload;
len = q->len;
if (q == p){ // if first buf...
payload += ETH_PAD_SIZE;
len -= ETH_PAD_SIZE;//Pad in Eth_hdr struct
}
Count = len;
buf = payload;
if ( (Count & 0x0001) ) flag1 = 1;
Count = Count>>1;
for(loop=0;loop < Count;loop++) {
rd_tmp = EN_DATA ;
*buf++ = (u8_t)(rd_tmp & 0x00ff) ;
*buf++ = (u8_t)(rd_tmp >> 8) ;
}
if ( flag1==1 ) *buf++ = *(unsigned char *)(Base_ADDR+0x10) ;
#if LINK_STATS
lwip_stats.link.recv++;
#endif /* LINK_STATS */
}//for
} else { // p == NULL
/* no more PBUF resource, Discard packet in buffer. */
Count = packetLength;
if ( (Count & 0x0001) ) flag1 = 1; Count = Count>>1;
for(loop=0;loop < Count;loop++) rd_tmp = EN_DATA;
if ( flag1==1 ) rd_tmp = *(unsigned char *)(Base_ADDR+0x10);
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif /* LINK_STATS */
}
next_frame = PDHeader[1];
EN0_BOUNDARY = (u8_t) (next_frame-1);
EN0_ISR = (u8_t) ENISR_RDC;
return p;
}
/*
* 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);
}
/*
* 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;
//p = low_level_input(ne2k_if);
/* move received packet into a new pbuf */
p = low_level_input(netif);
/* no packet could be read, silently ignore this */
if (p == NULL) return;
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
#if LINK_STATS
lwip_stats.link.recv++;
#endif /* LINK_STATS */
switch(htons(ethhdr->type)) {
/* IP packet? */
case ETHTYPE_IP:
/* update ARP table */
etharp_ip_input(netif, p);
/* skip Ethernet header */
pbuf_header(p, -(14+ETH_PAD_SIZE));
/* pass to network layer */
netif->input(p, netif);
break;
case ETHTYPE_ARP:
/* pass p to ARP module */
etharp_arp_input(netif, ne2k_if->ethaddr, p);
break;
default:
pbuf_free(p);
p = NULL;
break;
}
}
/*-----------------------------------------------------------------------------------*/
static void
arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
}
/*
* 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;
}
/*-----------------------------------------------------------------------------------*/
void ne2k_rx_err(void)
{
u8_t curr;
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
EN0_BOUNDARY = (u8_t) curr-1;
}
/*-----------------------------------------------------------------------------------*/
void ne2k_rx(void)
{
u8_t curr,bnry;
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
bnry = (u8_t) EN0_BOUNDARY + 1;//millin + 1
if (bnry >= RX_STOP_PG)
bnry = RX_START_PG;
while(curr != bnry){
ne2k_input(ne2k_if_netif);
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
bnry = (u8_t) EN0_BOUNDARY + 1; //millin +1
}
}
/* -----------------------------
* void ne2k_isr(void)
* can be int 4 5 6 or 7
* ----------------------------*/
void
ne2k_isr(void)
{
DSP_C6x_Save();
OSIntEnter();
if (OSIntNesting == 1)
{
OSTCBCur->OSTCBStkPtr = (OS_STK *) DSP_C6x_GetCurrentSP();
}
/* You can enable Interrupt again here,
if want to use nested interrupt..... */
//------------------------------------------------------------
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
//outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
EN0_IMR = (u8_t) 0x00;//close
// ram overflow interrupt
if (EN0_ISR & ENISR_OVER) {
EN0_ISR = (u8_t) ENISR_OVER; // clear interrupt
}
// error transfer interrupt ,NIC abort tx due to excessive collisions
if (EN0_ISR & ENISR_TX_ERR) {
EN0_ISR = (u8_t) ENISR_TX_ERR; // clear interrupt
//temporarily do nothing
}
// Rx error , reset BNRY pointer to CURR (use SEND PACKET mode)
if (EN0_ISR & ENISR_RX_ERR) {
EN0_ISR = (u8_t) ENISR_RX_ERR; // clear interrupt
ne2k_rx_err();
}
//got packet with no errors
if (EN0_ISR & ENISR_RX) {
EN0_ISR = (u8_t) ENISR_RX;
ne2k_rx();
}
//Transfer complelte, do nothing here
if (EN0_ISR & ENISR_TX){
EN0_ISR = (u8_t) ENISR_TX; // clear interrupt
}
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
EN0_ISR = (u8_t) 0xff; // clear ISR
EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
//(ENISR_OVER + ENISR_RX + ENISR_TX + ENISR_TX_ERR);
//open nic for next packet
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
if (led_stat & 0x04) {LED3_on;}
else {LED3_off;}
//--------------------------------------------------------
OSIntExit();
DSP_C6x_Resume();
asm (" nop 5"); //important!
// this can avoid a stack error when compile with the optimization!
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -