Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of F7_Ethernet by
ethernetif.c
00001 /** 00002 * @file 00003 * Ethernet Interface Skeleton 00004 * 00005 */ 00006 00007 /* 00008 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00009 * All rights reserved. 00010 * 00011 * Redistribution and use in source and binary forms, with or without modification, 00012 * are permitted provided that the following conditions are met: 00013 * 00014 * 1. Redistributions of source code must retain the above copyright notice, 00015 * this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright notice, 00017 * this list of conditions and the following disclaimer in the documentation 00018 * and/or other materials provided with the distribution. 00019 * 3. The name of the author may not be used to endorse or promote products 00020 * derived from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00023 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00025 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00026 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00027 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00028 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00029 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00030 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00031 * OF SUCH DAMAGE. 00032 * 00033 * This file is part of the lwIP TCP/IP stack. 00034 * 00035 * Author: Adam Dunkels <adam@sics.se> 00036 * 00037 */ 00038 00039 /* 00040 * This file is a skeleton for developing Ethernet network interface 00041 * drivers for lwIP. Add code to the low_level functions and do a 00042 * search-and-replace for the word "ethernetif" to replace it with 00043 * something that better describes your network interface. 00044 */ 00045 00046 #include "lwip/opt.h" 00047 00048 #if 0 /* don't build, this is only a skeleton, see previous comment */ 00049 00050 #include "lwip/def.h" 00051 #include "lwip/mem.h" 00052 #include "lwip/pbuf.h" 00053 #include <lwip/stats.h> 00054 #include <lwip/snmp.h> 00055 #include "netif/etharp.h" 00056 #include "netif/ppp_oe.h" 00057 00058 /* Define those to better describe your network interface. */ 00059 #define IFNAME0 'e' 00060 #define IFNAME1 'n' 00061 00062 /** 00063 * Helper struct to hold private data used to operate your ethernet interface. 00064 * Keeping the ethernet address of the MAC in this struct is not necessary 00065 * as it is already kept in the struct netif. 00066 * But this is only an example, anyway... 00067 */ 00068 struct ethernetif { 00069 struct eth_addr *ethaddr; 00070 /* Add whatever per-interface state that is needed here. */ 00071 }; 00072 00073 /* Forward declarations. */ 00074 static void ethernetif_input(struct netif *netif); 00075 00076 /** 00077 * In this function, the hardware should be initialized. 00078 * Called from ethernetif_init(). 00079 * 00080 * @param netif the already initialized lwip network interface structure 00081 * for this ethernetif 00082 */ 00083 static void 00084 low_level_init(struct netif *netif) 00085 { 00086 struct ethernetif *ethernetif = netif->state; 00087 00088 /* set MAC hardware address length */ 00089 netif->hwaddr_len = ETHARP_HWADDR_LEN; 00090 00091 /* set MAC hardware address */ 00092 netif->hwaddr[0] = ; 00093 ... 00094 netif->hwaddr[5] = ; 00095 00096 /* maximum transfer unit */ 00097 netif->mtu = 1500; 00098 00099 /* device capabilities */ 00100 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ 00101 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; 00102 00103 /* Do whatever else is needed to initialize interface. */ 00104 } 00105 00106 /** 00107 * This function should do the actual transmission of the packet. The packet is 00108 * contained in the pbuf that is passed to the function. This pbuf 00109 * might be chained. 00110 * 00111 * @param netif the lwip network interface structure for this ethernetif 00112 * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) 00113 * @return ERR_OK if the packet could be sent 00114 * an err_t value if the packet couldn't be sent 00115 * 00116 * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to 00117 * strange results. You might consider waiting for space in the DMA queue 00118 * to become availale since the stack doesn't retry to send a packet 00119 * dropped because of memory failure (except for the TCP timers). 00120 */ 00121 00122 static err_t 00123 low_level_output(struct netif *netif, struct pbuf *p) 00124 { 00125 struct ethernetif *ethernetif = netif->state; 00126 struct pbuf *q; 00127 00128 initiate transfer(); 00129 00130 #if ETH_PAD_SIZE 00131 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ 00132 #endif 00133 00134 for(q = p; q != NULL; q = q->next) { 00135 /* Send the data from the pbuf to the interface, one pbuf at a 00136 time. The size of the data in each pbuf is kept in the ->len 00137 variable. */ 00138 send data from(q->payload, q->len); 00139 } 00140 00141 signal that packet should be sent(); 00142 00143 #if ETH_PAD_SIZE 00144 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ 00145 #endif 00146 00147 LINK_STATS_INC(link.xmit); 00148 00149 return ERR_OK; 00150 } 00151 00152 /** 00153 * Should allocate a pbuf and transfer the bytes of the incoming 00154 * packet from the interface into the pbuf. 00155 * 00156 * @param netif the lwip network interface structure for this ethernetif 00157 * @return a pbuf filled with the received packet (including MAC header) 00158 * NULL on memory error 00159 */ 00160 static struct pbuf * 00161 low_level_input(struct netif *netif) 00162 { 00163 struct ethernetif *ethernetif = netif->state; 00164 struct pbuf *p, *q; 00165 u16_t len; 00166 00167 /* Obtain the size of the packet and put it into the "len" 00168 variable. */ 00169 len = ; 00170 00171 #if ETH_PAD_SIZE 00172 len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ 00173 #endif 00174 00175 /* We allocate a pbuf chain of pbufs from the pool. */ 00176 p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); 00177 00178 if (p != NULL) { 00179 00180 #if ETH_PAD_SIZE 00181 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ 00182 #endif 00183 00184 /* We iterate over the pbuf chain until we have read the entire 00185 * packet into the pbuf. */ 00186 for(q = p; q != NULL; q = q->next) { 00187 /* Read enough bytes to fill this pbuf in the chain. The 00188 * available data in the pbuf is given by the q->len 00189 * variable. 00190 * This does not necessarily have to be a memcpy, you can also preallocate 00191 * pbufs for a DMA-enabled MAC and after receiving truncate it to the 00192 * actually received size. In this case, ensure the tot_len member of the 00193 * pbuf is the sum of the chained pbuf len members. 00194 */ 00195 read data into(q->payload, q->len); 00196 } 00197 acknowledge that packet has been read(); 00198 00199 #if ETH_PAD_SIZE 00200 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ 00201 #endif 00202 00203 LINK_STATS_INC(link.recv); 00204 } else { 00205 drop packet(); 00206 LINK_STATS_INC(link.memerr); 00207 LINK_STATS_INC(link.drop); 00208 } 00209 00210 return p; 00211 } 00212 00213 /** 00214 * This function should be called when a packet is ready to be read 00215 * from the interface. It uses the function low_level_input() that 00216 * should handle the actual reception of bytes from the network 00217 * interface. Then the type of the received packet is determined and 00218 * the appropriate input function is called. 00219 * 00220 * @param netif the lwip network interface structure for this ethernetif 00221 */ 00222 static void 00223 ethernetif_input(struct netif *netif) 00224 { 00225 struct ethernetif *ethernetif; 00226 struct eth_hdr *ethhdr; 00227 struct pbuf *p; 00228 00229 ethernetif = netif->state; 00230 00231 /* move received packet into a new pbuf */ 00232 p = low_level_input(netif); 00233 /* no packet could be read, silently ignore this */ 00234 if (p == NULL) return; 00235 /* points to packet payload, which starts with an Ethernet header */ 00236 ethhdr = p->payload; 00237 00238 switch (htons(ethhdr->type)) { 00239 /* IP or ARP packet? */ 00240 case ETHTYPE_IP: 00241 case ETHTYPE_ARP: 00242 #if PPPOE_SUPPORT 00243 /* PPPoE packet? */ 00244 case ETHTYPE_PPPOEDISC: 00245 case ETHTYPE_PPPOE: 00246 #endif /* PPPOE_SUPPORT */ 00247 /* full packet send to tcpip_thread to process */ 00248 if (netif->input(p, netif)!=ERR_OK) 00249 { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); 00250 pbuf_free(p); 00251 p = NULL; 00252 } 00253 break; 00254 00255 default: 00256 pbuf_free(p); 00257 p = NULL; 00258 break; 00259 } 00260 } 00261 00262 /** 00263 * Should be called at the beginning of the program to set up the 00264 * network interface. It calls the function low_level_init() to do the 00265 * actual setup of the hardware. 00266 * 00267 * This function should be passed as a parameter to netif_add(). 00268 * 00269 * @param netif the lwip network interface structure for this ethernetif 00270 * @return ERR_OK if the loopif is initialized 00271 * ERR_MEM if private data couldn't be allocated 00272 * any other err_t on error 00273 */ 00274 err_t 00275 ethernetif_init(struct netif *netif) 00276 { 00277 struct ethernetif *ethernetif; 00278 00279 LWIP_ASSERT("netif != NULL", (netif != NULL)); 00280 00281 ethernetif = mem_malloc(sizeof(struct ethernetif)); 00282 if (ethernetif == NULL) { 00283 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n")); 00284 return ERR_MEM; 00285 } 00286 00287 #if LWIP_NETIF_HOSTNAME 00288 /* Initialize interface hostname */ 00289 netif->hostname = "lwip"; 00290 #endif /* LWIP_NETIF_HOSTNAME */ 00291 00292 /* 00293 * Initialize the snmp variables and counters inside the struct netif. 00294 * The last argument should be replaced with your link speed, in units 00295 * of bits per second. 00296 */ 00297 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); 00298 00299 netif->state = ethernetif; 00300 netif->name[0] = IFNAME0; 00301 netif->name[1] = IFNAME1; 00302 /* We directly use etharp_output() here to save a function call. 00303 * You can instead declare your own function an call etharp_output() 00304 * from it if you have to do some checks before sending (e.g. if link 00305 * is available...) */ 00306 netif->output = etharp_output; 00307 netif->linkoutput = low_level_output; 00308 00309 ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); 00310 00311 /* initialize the hardware */ 00312 low_level_init(netif); 00313 00314 return ERR_OK; 00315 } 00316 00317 #endif /* 0 */
Generated on Tue Jul 12 2022 21:19:01 by
1.7.2
