📄 ne2kif_bak.c
字号:
*/static err_t low_level_send(struct RTL8019if *rtl8019if,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 ); NE_ISR = ENISR_RDC; //clear 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; return ERR_OK;}/** * Read a packet into a pbuf chain. */static struct pbuf * low_level_receive(struct RTL8019if *rtl8019if){ u16_t packetLength,len; u8_t PDHeader[18]; // Temp storage for ethernet headers struct pbuf * p; struct pbuf * q; 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_LINK, 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 // avaliable data in the pbuf is given by the q->len variable. // read data into(q->payload, q->len); // First 14 bytes are already there, skip them payload = q->payload; len = q->len; if (q == p) { payload += 14; len -=14; } ne2k_copyin(len,payload); } } else { // no more PBUF resource, Discard packet in buffer. ne2k_discard(packetLength-14); } return p;}/*-----------------------------------------------------------------------------------*//* * 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. * */// WARNING: must close all interrupts during init!!!!/*-----------------------------------------------------------------------------------*/voidne2k_init(struct netif *netif){ struct RTL8019if *rtl8019if; rtl8019if = mem_malloc(sizeof(struct RTL8019if)); rtl8019if->ethaddr = mem_malloc(sizeof(struct eth_addr)); netif->state = rtl8019if; netif->name[0] = 'e'; netif->name[1] = 't'; netif->output = ne2k_send_packet; low_level_init(netif); etharp_init();}/** * Send a packet to the RTK8019as from a series of pbuf buffers. */err_t ne2k_send_packet(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr){ struct RTL8019if *rtl8019if; struct pbuf *q; struct eth_hdr *ethhdr; struct eth_addr *dest, mcastaddr; struct ip_addr *queryaddr; u8_t i; rtl8019if = netif->state; // Make room for Ethernet header. if(pbuf_header(p, 14) != 0) { // The pbuf_header() call shouldn't fail, but we allocate an extra pbuf just in case. q = pbuf_alloc(PBUF_LINK, 14, PBUF_RAM); if(q == NULL) return ERR_MEM; pbuf_chain(q, p); p = q; } // Construct Ethernet header. Start with looking up deciding which // MAC address to use as a destination address. Broadcasts and // multicasts are special, all other addresses are looked up in the // ARP table. queryaddr = ipaddr; if(ip_addr_isany(ipaddr) || ip_addr_isbroadcast(ipaddr, &(netif->netmask))) { dest = (struct eth_addr *)ðbroadcast; } else if(ip_addr_ismulticast(ipaddr)) { // Hash IP multicast address to MAC address. mcastaddr.addr[0] = 0x01; mcastaddr.addr[1] = 0x0; mcastaddr.addr[2] = 0x5e; mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; mcastaddr.addr[4] = ip4_addr3(ipaddr); mcastaddr.addr[5] = ip4_addr4(ipaddr); dest = &mcastaddr; } else { if(ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) { // Use destination IP address if the destination is on // the same subnet as we are. queryaddr = ipaddr; } else { // Otherwise we use the default router as the address to send // the Ethernet frame to. */ queryaddr = &(netif->gw); } dest = arp_lookup(queryaddr); } // If the arp_lookup() didn't find an address, we send out an ARP // query for the IP address. if(dest == NULL) { q = etharp_query(netif, rtl8019if->ethaddr, queryaddr); if(q != NULL) { low_level_send(rtl8019if, q); pbuf_free(q); return ERR_ARP; } return ERR_MEM; } ethhdr = p->payload; for(i = 0; i < 6; i++) { ethhdr->dest.addr[i] = dest->addr[i]; ethhdr->src.addr[i] = rtl8019if->ethaddr->addr[i]; } ethhdr->type = htons(ETHTYPE_IP); return low_level_send(rtl8019if, p); }/** * Read a packet, clearing overflows. */void ne2k_recv_packet(struct netif *netif){ struct eth_hdr *ethhdr; struct RTL8019if *rtl8019if; struct pbuf *p; rtl8019if = netif->state;// PRINT("start get a packet in ne2k_receive_packet\n "); p = low_level_receive(rtl8019if);// PRINT("got a packet from low_level_receive\n"); if(p == NULL) return; ethhdr = p->payload; switch(htons(ethhdr->type)) { case ETHTYPE_IP: etharp_ip_input(netif, p); pbuf_header(p, -14); netif->input(p, netif); break; case ETHTYPE_ARP: p = etharp_arp_input(netif, rtl8019if->ethaddr, p); if(p != NULL) { low_level_send(rtl8019if, p); pbuf_free(p); } break; default: pbuf_free(p); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -