low_level_init() 底層硬件初始化 這裏進行不一樣平臺對應的操做可能不一樣,目的就是爲了初始化網卡收發,便於接收發送網絡數據緩存
static void low_level_init(struct netif *netif) { /* set MAC hardware address length */ netif->hwaddr_len = ETHARP_HWADDR_LEN; //6 字節 /* set MAC hardware address */ netif->hwaddr[0] = MACaddr[0]; netif->hwaddr[1] = MACaddr[1]; netif->hwaddr[2] = MACaddr[2]; netif->hwaddr[3] = MACaddr[3]; netif->hwaddr[4] = MACaddr[4]; netif->hwaddr[5] = MACaddr[5]; /* maximum transfer unit */ netif->mtu = 1500; //mtu 值 /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; /* Initialize Tx Descriptors list: Chain Mode */ ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); /* Initialize Rx Descriptors list: Chain Mode */ ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); /* Enable Ethernet Rx interrrupt */ { int i; for(i=0; i<ETH_RXBUFNB; i++) { ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE); } } #ifdef CHECKSUM_BY_HARDWARE /* Enable the checksum insertion for the Tx frames */ { int i; for(i=0; i<ETH_TXBUFNB; i++) { ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull); } } #endif /* Enable MAC and DMA transmission and reception */ ETH_Start(); }
1網絡
void ETH_Start(void) { /* Enable transmit state machine of the MAC for transmission on the MII */ ETH_MACTransmissionCmd(ENABLE); /* Flush Transmit FIFO */ ETH_FlushTransmitFIFO(); /* Enable receive state machine of the MAC for reception from the MII */ ETH_MACReceptionCmd(ENABLE); /* Start DMA transmission */ ETH_DMATransmissionCmd(ENABLE); /* Start DMA reception */ ETH_DMAReceptionCmd(ENABLE); }
最後一個參數併發
/*******************流程接收以太網幀。使用這個函數,而不是 直接調用ip_input ARP幀穿過etharp ethernetif_input,併發 訪問的ARP緩存保護 **************/ err_t ethernet_input(struct pbuf *p, struct netif *netif) { struct eth_hdr* ethhdr; /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethernet_input: dest:%02x:%02x:%02x:%02x:%02x:%02x, src:%02x:%02x:%02x:%02x:%02x:%02x, type:%2hx\n", (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2], (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], (unsigned)htons(ethhdr->type))); switch (htons(ethhdr->type)) { /* IP packet? */ case ETHTYPE_IP: #if ETHARP_TRUST_IP_MAC /* update ARP table */ etharp_ip_input(netif, p); #endif /* ETHARP_TRUST_IP_MAC */ /* skip Ethernet header */ if(pbuf_header(p, -(s16_t)sizeof(struct eth_hdr))) { LWIP_ASSERT("Can't move over header in packet", 0); pbuf_free(p); p = NULL; } else { /* pass to IP layer */ ip_input(p, netif); } break; case ETHTYPE_ARP: /* pass p to ARP module */ etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); break; #if PPPOE_SUPPORT case ETHTYPE_PPPOEDISC: /* PPP Over Ethernet Discovery Stage */ pppoe_disc_input(netif, p); break; case ETHTYPE_PPPOE: /* PPP Over Ethernet Session Stage */ pppoe_data_input(netif, p); break; #endif /* PPPOE_SUPPORT */ default: ETHARP_STATS_INC(etharp.proterr); ETHARP_STATS_INC(etharp.drop); pbuf_free(p); p = NULL; break; } /* This means the pbuf is freed or consumed, so the caller doesn't have to free it again */ return ERR_OK; }