📄 ethemu.c
字号:
memcpy (arp->ar_spa, &eNetOurIP, 4); (void) eeth_send((uchar *)et, (pkt - (uchar *)et) + ARP_HDR_SIZE); return; case ARPOP_REPLY: /* arp reply */ /* are we waiting for a reply */ if (!eNetArpWaitPacketIP || !eNetArpWaitPacketMAC) break;#ifdef ET_DEBUG printk("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n", arp->ar_data[0], arp->ar_data[1], arp->ar_data[2], arp->ar_data[3], arp->ar_data[4], arp->ar_data[5]);#endif return; default:#ifdef ET_DEBUG printk("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op));#endif return; } break; case PROT_IP: printk ("Got IP,len %d\n",len);#ifdef ET_DEBUG putstr ("Got IP\n");#endif if (len < IP_HDR_SIZE) { printk ("len bad %d < %d\n", len, IP_HDR_SIZE); return; } if (len < ntohs(ip->ip_len)) { printk("len bad %d < %d\n", len, ntohs(ip->ip_len)); return; } len = ntohs(ip->ip_len);#ifdef ET_DEBUG printk("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff);#endif if ((ip->ip_hl_v & 0xf0) != 0x40) { printk("not support version\n"); return; } if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */ printk("Can't deal w/ fragments\n"); return; } if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) { printk ("checksum bad\n"); return; } tmp = NetReadIP(&ip->ip_dst); if (eNetOurIP && tmp != eNetOurIP && tmp != 0xFFFFFFFF) { printk ("not for ours\n"); return; } /* * watch for ICMP host redirects * * There is no real handler code (yet). We just watch * for ICMP host redirect messages. In case anybody * sees these messages: please contact me * (wd@denx.de), or - even better - send me the * necessary fixes :-) * * Note: in all cases where I have seen this so far * it was a problem with the router configuration, * for instance when a router was configured in the * BOOTP reply, but the TFTP server was on the same * subnet. So this is probably a warning that your * configuration might be wrong. But I'm not really * sure if there aren't any other situations. */ if (ip->ip_p == IPPROTO_ICMP) { ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); printk (" ICMP Protocol\n"); switch (icmph->type) { case ICMP_REDIRECT: if (icmph->code != ICMP_REDIR_HOST) return; printk (" ICMP Host Redirect to "); print_IPaddr(icmph->un.gateway); //putc(' '); return;//#ifdef CONFIG_NET_PING //case ICMP_ECHO_REPLY: case ICMP_ECHO_REQUEST: /* * IP header OK. Pass the packet to the current handler. */ /* XXX point to ip packet */ //(*packetHandler)((uchar *)ip, 0, 0, 0); Icmp_Echo_Reply(inpkt, len); return;//#endif default: return; } } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ return; }#ifdef CONFIG_UDP_CHECKSUM if (ip->udp_xsum != 0) { ulong xsum; ushort *sumptr; ushort sumlen; xsum = ip->ip_p; xsum += (ntohs(ip->udp_len)); xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff; xsum += (ntohl(ip->ip_src) >> 0) & 0x0000ffff; xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff; xsum += (ntohl(ip->ip_dst) >> 0) & 0x0000ffff; sumlen = ntohs(ip->udp_len); sumptr = (ushort *) &(ip->udp_src); while (sumlen > 1) { ushort sumdata; sumdata = *sumptr++; xsum += ntohs(sumdata); sumlen -= 2; } if (sumlen > 0) { ushort sumdata; sumdata = *(unsigned char *) sumptr; sumdata = (sumdata << 8) & 0xff00; xsum += sumdata; } while ((xsum >> 16) != 0) { xsum = (xsum & 0x0000ffff) + ((xsum >> 16) & 0x0000ffff); } if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) { printk(" UDP wrong checksum %08x %08x\n", xsum, ntohs(ip->udp_xsum)); return; } }#endif /* * IP header OK. Pass the packet to the current handler. */ (*packetHandler)((uchar *)ip +IP_HDR_SIZE, ntohs(ip->udp_dst), ntohs(ip->udp_src), ntohs(ip->udp_len) - 8); break; }}/*************************************************************************************///// newwork emulator end///*************************************************************************************//* function declaration ------------------------------------- */int eth_init(bd_t * bd);int eth_send(volatile void *, int);int eth_rx(void);void eth_halt(void);/* Initilize dm9000 board*/inteth_init(bd_t * bd){ ushort *len; printk(__FUNCTION__"()\n"); tx = rx = 0; len = (ushort *)&txrxbuff[tx]; *len = 0; /* see what we've got */ printk("operating at "); printk("100M full duplex "); printk("mode\n"); return 0;}/* Hardware start transmission. Send a packet to media from the upper layer.*/inteth_send(volatile void *packet, int length){ //char *data_ptr; uint i; uchar* p=(uchar *)packet; //u32 tmplen, //int tmo; printk(__FUNCTION__"()\n"); if (length<64) { for (i=length;i<64;i++) p[i]=0; length = 64; } eNetReceive((volatile uchar *)packet, length);#ifdef CONFIG_DM9000_DEBUG DM9000_DBG_T("eth_send: length: %d", length); for (i = 0; i < length; i++) { if (i % 8 == 0) DM9000_DBG("\nSend: %02x: ", i); DM9000_DBG("%02x ", ((unsigned char *) packet)[i]); } DM9000_DBG_D("\n");#endif /* Move data to DM9000 TX RAM */ //data_ptr = (char *) packet; //DM9000_outb(DM9000_MWCMD, DM9000_IO);#ifdef CONFIG_DM9000_USE_16BIT tmplen = (length + 1) / 2; for (i = 0; i < tmplen; i++) DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);#endif /* */ /* Set TX length to DM9000 */ //DM9000_iow(DM9000_TXPLL, length & 0xff); //DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff); /* Issue TX polling command */ printk("transmit done\n"); return 0;}/* Stop the interface. The interface is stopped when it is brought.*/voideth_halt(void){ printk(__FUNCTION__"()\n"); //putc('!');}inteeth_send(volatile void *packet, int length){ ushort *len = (ushort *)&txrxbuff[tx]; uchar *p = (uchar *)packet; uint i; if (length<64) { for (i=length;i<64;i++) p[i]=0; length = 64; } *len = length; if (tx+2+length <= NETBUFFSIZE) { memcpy(&txrxbuff[tx+2],p,length); } else if (tx+2 >= NETBUFFSIZE) { memcpy(txrxbuff,p,length); } else { memcpy(&txrxbuff[tx+2],p,NETBUFFSIZE-tx-2); memcpy(txrxbuff,&p[NETBUFFSIZE-tx-2],length-(NETBUFFSIZE-tx-2)); } tx = (tx + 2 + length)&(NETBUFFSIZE-1); len = (ushort *)&txrxbuff[tx]; *len = 0; return length;}/* Received a packet and pass to upper layer*/inteth_rx(void){ u8 *rdptr = (u8 *) NetRxPackets[0]; u16 RxLen = 0; ushort *p = (ushort *)&txrxbuff[rx]; printk(__FUNCTION__"()\n"); /* Check packet ready or not */ RxLen = *p; if (RxLen == 0) { return 0; } if (rx+2 >= NETBUFFSIZE) { memcpy(rdptr,txrxbuff,RxLen); } else if (rx+2+RxLen <= NETBUFFSIZE) { memcpy(rdptr,&txrxbuff[rx+2],RxLen); } else { memcpy(rdptr,&txrxbuff[rx+2],NETBUFFSIZE-rx-2); memcpy(&rdptr[NETBUFFSIZE-rx-2],txrxbuff,rx+2+RxLen-NETBUFFSIZE); } rx = (rx + 2 + RxLen)&(NETBUFFSIZE-1); /* Pass to upper layer */#ifdef CONFIG_DM9000_DEBUG //DM9000_DBG("passing packet to upper layer\n"); DM9000_DBG("length: %d", RxLen); for (i = 0; i < RxLen; i++) { if (i % 8 == 0) DM9000_DBG("\nRecv: %02x: ", i); DM9000_DBG("%02x ", rdptr[i]); } DM9000_DBG("\n"); //printk(__FUNCTION__"():passing packet to upper layer\n");#endif //putc('<'); NetReceive(NetRxPackets[0], RxLen); return RxLen; return 0;}#endif /* CONFIG_DRIVER_DM9000 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -