Dependents:   TimeZoneDemo EthernetJackTestCode MMEx_Challenge ntp_mem ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers eth_drv.cpp Source File

eth_drv.cpp

00001 
00002 /*
00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
00004  
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011  
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014  
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 */
00023 
00024 #include "netCfg.h"
00025 #if NET_ETH
00026 
00027 #include "mbed.h"
00028 
00029 Ethernet *pEth = NULL;
00030 #ifdef __cplusplus
00031 extern "C" {
00032 #endif
00033 
00034 #include "lwip/opt.h"
00035 
00036 #include "lwip/def.h"
00037 #include "lwip/pbuf.h"
00038 #include "lwip/sys.h"
00039 #include "lwip/stats.h"
00040 #include "netif/etharp.h"
00041 #include "string.h"
00042 
00043 //#include "eth_drv.h"
00044 
00045 #define IFNAME0 'E'
00046 #define IFNAME1 'X'
00047 
00048 #define min(x,y) (((x)<(y))?(x):(y))
00049 
00050 struct netif* eth_netif;
00051 
00052 static err_t eth_output(struct netif *netif, struct pbuf *p) {
00053   #if ETH_PAD_SIZE
00054     pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
00055   #endif
00056 
00057   do {
00058     pEth->write((const char *)p->payload, p->len);
00059   } while((p = p->next)!=NULL);
00060 
00061   pEth->send();
00062 
00063   #if ETH_PAD_SIZE
00064     pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
00065   #endif
00066   
00067   LINK_STATS_INC(link.xmit);
00068   return ERR_OK;
00069 }
00070 
00071 /*
00072 void show(char *buf, int size) {
00073     printf("Destination:  %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
00074             buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
00075     printf("Source: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
00076             buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
00077   
00078     printf("Type %hd\n", htons((short)buf[12]));
00079     
00080    // hexview(buf, size);
00081 }
00082 */
00083 
00084 void eth_poll() {
00085   struct eth_hdr *ethhdr;
00086   struct pbuf *frame, *p;
00087   int len, read;
00088 
00089   while((len = pEth->receive()) != 0) {
00090       frame = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
00091       if(frame == NULL) {
00092           return;
00093       }
00094       p = frame;
00095       /* no packet could be read, silently ignore this */
00096       if (p == NULL) return;
00097       do {
00098          read = pEth->read((char *)p->payload, p->len);
00099          p = p->next;
00100       } while(p != NULL && read != 0);
00101            
00102       #if ETH_PAD_SIZE
00103           pbuf_header(p, ETH_PAD_SIZE);
00104       #endif
00105 
00106       ethhdr = (struct eth_hdr *)(frame->payload);
00107       
00108      // show((char*)ethhdr, 13);
00109       
00110       /*
00111       switch(htons(ethhdr->type)) {
00112           
00113           case ETHTYPE_IP:
00114               etharp_ip_input(gnetif, frame);
00115               pbuf_header(frame, -((s16_t) sizeof(struct eth_hdr)));
00116               gnetif->input(frame, gnetif);
00117               break;
00118           
00119           case ETHTYPE_ARP:
00120               etharp_arp_input(gnetif, (struct eth_addr *)(gnetif->hwaddr), frame);
00121               break;
00122           
00123           default:
00124               break;
00125       }*/
00126       
00127       
00128       
00129       //ethernet_input(frame, gnetif);
00130       
00131       switch (htons(ethhdr->type)) {
00132       /* IP or ARP packet? */
00133       case ETHTYPE_IP:
00134       case ETHTYPE_ARP:
00135       #if PPPOE_SUPPORT
00136       /* PPPoE packet? */
00137       case ETHTYPE_PPPOEDISC:
00138       case ETHTYPE_PPPOE:
00139       #endif /* PPPOE_SUPPORT */
00140       /* full packet send to tcpip_thread to process */
00141         //if (netif->input(p, gnetif)!=ERR_OK)
00142         if (ethernet_input(frame, eth_netif)!=ERR_OK)
00143         { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
00144           pbuf_free(frame);
00145           frame = NULL;
00146         }
00147         break;
00148 
00149       default:
00150         pbuf_free(frame);
00151         frame = NULL;
00152         break;
00153       }
00154       
00155       /* pbuf_free(frame); */
00156   }
00157 
00158   
00159  
00160   
00161 }
00162 
00163 err_t eth_init(struct netif *netif) {
00164   LWIP_ASSERT("netif != NULL", (netif != NULL));
00165   
00166   NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 0x2EA);
00167   
00168   /* maximum transfer unit */
00169   netif->mtu = 0x2EA;
00170   
00171   /* device capabilities */
00172   /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
00173   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP;
00174 
00175   netif->state = NULL;
00176   eth_netif = netif;
00177 
00178   netif->name[0] = IFNAME0;
00179   netif->name[1] = IFNAME1;
00180 
00181   /* We directly use etharp_output() here to save a function call.
00182    * You can instead declare your own function an call etharp_output()
00183    * from it if you have to do some checks before sending (e.g. if link
00184    * is available...) */
00185   netif->output          = etharp_output;
00186   netif->linkoutput      = eth_output;
00187 
00188   if (!pEth) pEth = new Ethernet(); // only create Ethernet object if required
00189 
00190   return ERR_OK;
00191 }
00192 
00193 void eth_free()
00194 {
00195   if(pEth)
00196     delete pEth;
00197   pEth = NULL;
00198 }
00199 
00200 void eth_address(char* mac) {
00201     pEth->address(mac);
00202 }
00203 
00204 Ethernet* eth_interface() {
00205     return pEth;
00206 }    
00207 
00208 #ifdef __cplusplus
00209 };
00210 #endif
00211 
00212 #endif