📄 ne2kif.c
字号:
NE_CURR = convert_8(RX_START_PG); /* RX_CURR_PG; Current memory page = RX_CURR_PG ? */ NE_CR = convert_8(ENCR_PAGE0 + ENCR_NODMA) ; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */ Delay(100); NE_RCR = convert_8(ENRCR_RXCONFIG); /* rx on(broadcasts, no multicast,errors 04*/ NE_TCR = convert_8(ENTCR_TXCONFIG); /* xmit on. */ NE_ISR = 0xff; /* Individual bits are cleared by writing a "1" into it. */ NE_IMR = convert_8(ENISR_ALL); /* INTerrupt mask reg */ NE_CR = convert_8(ENCR_PAGE0 + ENCR_NODMA + ENCR_START); net2k_int_init();}/* * 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_tlow_level_output(struct netif *netif, struct pbuf *p){ struct pbuf *q; u8_t isr; u8_t chain; u8_t * tr_ptr; u16_t tr_len, temp_dw; u16_t padLength,packetLength; /* Set up to transfer the packet contents to the NIC RAM. */ padLength = 0; packetLength = p->tot_len; /* packetLength muse >=64 (see 802.3) */ if ((p->tot_len) < 64) { padLength = 64 - (p->tot_len); packetLength = 64; } /* don't close nic,just close receive interrupt */ NE_CR = convert_8(ENCR_PAGE2 | ENCR_NODMA | ENCR_START); isr = convert_8(NE_IMR); isr &= ~ENISR_RX; NE_CR = convert_8(ENCR_PAGE0 | ENCR_NODMA | ENCR_START); NE_IMR = convert_8(isr); NE_ISR = convert_8(ENISR_RDC); /* Amount to send */ NE_RBCR0 = convert_8(packetLength & 0xff); NE_RBCR1 = convert_8(packetLength >> 8); /* Address on NIC to store */ NE_RSAR0 = 0x00; NE_RSAR1 = convert_8(NE_START_PG); /* Write command to start */ NE_CR = convert_8(ENCR_PAGE0 | ENCR_RWRITE | ENCR_START); /* write packet to ring buffers. */ for(q = p, chain = 0; q != NULL; q = q->next) { if(chain == 1) { if(((q->len-1) & 0x01) && (q->next != NULL)) { tr_len = q->len - 2; tr_ptr = ((u8_t*)q->payload) + 1; temp_dw = *(((u8_t *)q->payload) + q->len - 1); temp_dw += *(u8_t *)(q->next->payload) << 8; chain = 1; } else { tr_len = q->len - 1; tr_ptr = ((u8_t*)q->payload) + 1; chain = 0; } } else { if((q->len & 0x01) && (q->next != NULL)) { tr_len = q->len - 1; tr_ptr = (u8_t*)q->payload; temp_dw = *(((u8_t *)q->payload) + q->len - 1); temp_dw += *(u8_t *)(q->next->payload) << 8; chain = 1; } else { tr_len = q->len; tr_ptr = (u8_t*)q->payload; chain = 0; } } ne2k_copyout(tr_len, tr_ptr); if (chain == 1) NE_DATAW = convert_16(temp_dw); } ne2k_outpad(padLength); /* Wait for remote dma to complete - ISR Bit 6 clear if busy */ while((u8_t)(convert_8(NE_ISR) & ENISR_RDC) == 0 ); /* clear RDC */ NE_ISR = convert_8(ENISR_RDC); /* Issue the transmit command.(start local dma) */ NE_TPSR = convert_8(NE_START_PG); NE_TBCR0 = convert_8(packetLength & 0xff); NE_TBCR1 = convert_8(packetLength >> 8); /* Start transmission (and shut off remote dma) */ NE_CR = convert_8(ENCR_PAGE0 | ENCR_NODMA | ENCR_TRANS | ENCR_START); /* reopen receive interrupt */ NE_CR = convert_8(ENCR_PAGE2 | ENCR_NODMA | ENCR_START); isr = convert_8(NE_IMR); isr |= ENISR_RX; NE_CR = convert_8(ENCR_PAGE0 | ENCR_NODMA | ENCR_START); NE_IMR = convert_8(isr);#ifdef LINK_STATS lwip_stats.link.xmit++;#endif /* LINK_STATS */ return ERR_OK;}/* * low_level_input(): * * Should allocate a pbuf and transfer the bytes of the incoming * packet from the interface into the pbuf. * */static struct pbuf *low_level_input(struct netif *netif){ struct pbuf *p, *q; u16_t packetLength, len; u8_t PDHeader[18]; /* Temp storage for ethernet headers */ u8_t * payload; NE_ISR = convert_8(ENISR_RDC); NE_RBCR1 = convert_8(0x0f); /* See controller manual , use send packet command */ NE_CR = convert_8(ENCR_PAGE0 | ENCR_RREAD | ENCR_RWRITE | ENCR_START); /* get the first 18 bytes from nic */ ne2k_copyin(18,PDHeader); /* Store real length, set len to packet length - header */ packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 )); /* verify if the packet is an IP packet or ARP packet */ if((PDHeader[3]>0x06)||(PDHeader[16] != 8)||(PDHeader[17] != 0 && PDHeader[17] != 6)) { ne2k_discard(packetLength-14); return NULL; } /* We allocate a pbuf chain of pbufs from the pool. */ p = pbuf_alloc(PBUF_RAW, packetLength, PBUF_POOL); if (p != NULL) { /* We iterate over the pbuf chain until we have read the entire packet into the pbuf. */ /* This assumes a minimum pbuf size of 14 ... a good assumption */ memcpy(p->payload, PDHeader + 4, 14); for(q = p; q != NULL; q = q->next) { /* Read enough bytes to fill this pbuf in the chain. The available data in the pbuf is given by the q->len variable. */ payload = q->payload; len = q->len; if (q == p) { payload += 14; len -=14; } ne2k_copyin(len,payload); }#ifdef LINK_STATS lwip_stats.link.recv++;#endif /* LINK_STATS */ } else { /* no more PBUF resource, Discard packet in buffer. */ ne2k_discard(packetLength-14);#ifdef LINK_STATS lwip_stats.link.memerr++; lwip_stats.link.drop++;#endif /* LINK_STATS */ } 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_tethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr){#if 0 struct ethernetif *ethernetif; err_t ret; /* struct pbuf *q; struct eth_hdr *ethhdr; struct eth_addr *dest, mcastaddr; struct ip_addr *queryaddr; err_t err; u8_t i; */ ethernetif = netif->state; /* resolve the link destination hardware address */ ret = etharp_output(netif, p, ipaddr); /* network hardware address obtained? */ if (ret != ERR_OK) { /* we cannot tell if the packet was sent: the packet could */ /* have been queued on an ARP entry that was already pending. */ return ERR_OK; } /* send out the packet */ return low_level_output(netif, p);#endif /*for the new lwip 1.3.0, etharp_output has been modified and will send out the packet by itself, so no need to call low_level_output again*/ return etharp_output(netif, p, ipaddr);}/* * 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 voidethernetif_input(struct netif *netif){ struct ethernetif *ethernetif; struct eth_hdr *ethhdr; struct pbuf *p, *q; ethernetif = netif->state; p = low_level_input(netif); if (p == NULL) return;#ifdef LINK_STATS lwip_stats.link.recv++;#endif /* LINK_STATS */ ethhdr = p->payload; q = NULL; switch (htons(ethhdr->type)) { case ETHTYPE_IP: etharp_ip_input(netif, p); pbuf_header(p, -14); netif->input(p, netif); break; case ETHTYPE_ARP: etharp_arp_input(netif, ethernetif->ethaddr, p); break; default: pbuf_free(p); p = NULL; break; } if (q != NULL) { low_level_output(netif, q); pbuf_free(q); q = NULL; }}static voidarp_timer(void *arg){ etharp_tmr(); sys_timeout(ARP_TMR_INTERVAL, 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_tethernetif_init(struct netif *netif){ struct ethernetif *ethernetif; ethernetif = mem_malloc(sizeof(struct ethernetif)); if (ethernetif == NULL) { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n")); return ERR_MEM; } netif->state = ethernetif; netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; netif->output = ethernetif_output; netif->linkoutput = low_level_output; ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); low_level_init(netif); etharp_init(); sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); return ERR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -