?? ne2kif.c
字號:
* 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 = ENCR_PAGE2 | ENCR_NODMA | ENCR_START; isr = NE_IMR; isr &= ~ENISR_RX; NE_CR = ENCR_PAGE0 | ENCR_NODMA | ENCR_START; NE_IMR = isr; NE_ISR = ENISR_RDC; /* Amount to send */ NE_RBCR0 = packetLength & 0xff; NE_RBCR1 = packetLength >> 8; /* Address on NIC to store */ NE_RSAR0 = 0x00; NE_RSAR1 = NE_START_PG; /* Write command to start */ NE_CR = 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 = temp_dw; } ne2k_outpad(padLength); /* Wait for remote dma to complete - ISR Bit 6 clear if busy */ while((u8_t)(NE_ISR & ENISR_RDC) == 0 ); /* clear RDC */ NE_ISR = ENISR_RDC; /* Issue the transmit command.(start local dma) */ NE_TPSR = NE_START_PG; NE_TBCR0 = packetLength & 0xff; NE_TBCR1 = packetLength >> 8; /* Start transmission (and shut off remote dma) */ NE_CR = ENCR_PAGE0 | ENCR_NODMA | ENCR_TRANS | ENCR_START; /* reopen receive interrupt */ NE_CR = ENCR_PAGE2 | ENCR_NODMA | ENCR_START; isr = NE_IMR; isr |= ENISR_RX; NE_CR = ENCR_PAGE0 | ENCR_NODMA | ENCR_START; NE_IMR = 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 = ENISR_RDC; NE_RBCR1 = 0x0f; /* See controller manual , use send packet command */ NE_CR = 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){ struct ethernetif *ethernetif; /* 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 */ p = etharp_output(netif, ipaddr, p); /* network hardware address obtained? */ if (p == NULL) { /* 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);}/* * 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: q = etharp_ip_input(netif, p); pbuf_header(p, -14); netif->input(p, netif); break; case ETHTYPE_ARP: q = 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 + -