ZG2100 Network interface source
Embed:
(wiki syntax)
Show/hide line numbers
zg_net.c
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_ZG2100 00026 00027 #include "zg_defs.h" 00028 #include "zg_net.h" 00029 #include "zg_drv.h" 00030 00031 #include "lwip/opt.h" 00032 00033 #include "lwip/def.h" 00034 #include "lwip/pbuf.h" 00035 #include "lwip/sys.h" 00036 #include "lwip/stats.h" 00037 #include "netif/etharp.h" 00038 00039 #include "string.h" 00040 00041 #ifdef __LWIP_DEBUG 00042 #undef __LWIP_DEBUG 00043 #endif 00044 //#define __DEBUG 00045 #include "dbg/dbg.h" 00046 00047 #define IFNAME0 'w' 00048 #define IFNAME1 'l' 00049 00050 //void hexdump(byte* buffer, int size); 00051 #define hexdump(x,y) 00052 00053 const char snap[ZG_SNAP_LEN] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 }; //Snap word, see IEEE 802-2001 10.3 Subnetwork Access Protocol (p. 23 ~ 29) 00054 struct netif* zg_netif; 00055 00056 //To be called by Lwip 00057 static err_t zg_output(struct netif *netif, struct pbuf *p) //Transfer an ethernet frame : convert into ZG frame & TX it 00058 { 00059 DBG("\r\nOut packet\r\n"); 00060 00061 while( zg_send_is_busy() ) 00062 { 00063 zg_process(); //Ugly but prevents lwip from feeding other packets 00064 } 00065 #if ETH_PAD_SIZE 00066 pbuf_header(p, -ETH_PAD_SIZE); //Drop padding word 00067 #endif 00068 00069 ZG_ETH_HDR* eth_hdr = (ZG_ETH_HDR*) p->payload; 00070 00071 ZG_TX_HDR* tx_hdr = (ZG_TX_HDR*)fifo_buf; 00072 memset((void*)tx_hdr, 0, sizeof(ZG_TX_HDR)); 00073 00074 //Convert headers properly 00075 tx_hdr->zero = HTODS( 0 ); 00076 memcpy( tx_hdr->dest, eth_hdr->dest, ZG_MACADDR_LEN ); 00077 memcpy( tx_hdr->snap, snap, ZG_SNAP_LEN ); 00078 tx_hdr->type = eth_hdr->type; //Lwip has already put the type in BE 00079 00080 DBG("\r\nEth header\r\n"); 00081 hexdump((byte*)eth_hdr, sizeof(ZG_ETH_HDR)); 00082 00083 DBG("\r\nZg header\r\n"); 00084 hexdump((byte*)tx_hdr, sizeof(ZG_TX_HDR)); 00085 00086 //Open TX fifo & send header 00087 zg_send_start(); 00088 zg_send( (byte*)tx_hdr, sizeof(ZG_TX_HDR) ); 00089 00090 //Send remaining payload of this buf 00091 zg_send( (byte*)(((byte*)p->payload) + sizeof(ZG_ETH_HDR)), (p->len - sizeof(ZG_ETH_HDR)) ); 00092 00093 while(p->next != NULL) 00094 { 00095 p = p->next; 00096 zg_send((byte*)p->payload, p->len); 00097 //FIX: Watchout, p content MUST be preserved for proper TCP functionality!!! 00098 } 00099 00100 zg_send_end(); 00101 00102 #if ETH_PAD_SIZE 00103 pbuf_header(p, ETH_PAD_SIZE); //Reclaim padding word 00104 #endif 00105 00106 LINK_STATS_INC(link.xmit); 00107 return ERR_OK; 00108 } 00109 00110 //Callback from zg_drv 00111 void zg_on_input(byte* buf, int len) //On reception of a ZG frame : convert into Eth frame & feed lwip 00112 { 00113 struct pbuf *frame, *p; //Lwip buffers 00114 byte* eth_buf; //Position of the Ethernet packet buffer 00115 int eth_len; //Length of this buffer 00116 ZG_ETH_HDR eth_hdr_data; //Temporary buffer 00117 ZG_ETH_HDR* eth_hdr = ð_hdr_data; //just to remain consistent in notations 00118 memset((void*)eth_hdr, 0, sizeof(ZG_ETH_HDR)); 00119 00120 DBG("\r\nIncoming packet\r\n"); 00121 hexdump(buf, len); 00122 00123 ZG_RX_HDR* rx_hdr = (ZG_RX_HDR*)buf; 00124 00125 memcpy( eth_hdr->dest, rx_hdr->dest, ZG_MACADDR_LEN ); 00126 memcpy( eth_hdr->src, rx_hdr->src, ZG_MACADDR_LEN ); 00127 eth_hdr->type = rx_hdr->type; //Lwip will convert the type in LE 00128 00129 DBG("\r\nZg header\r\n"); 00130 hexdump((byte*)rx_hdr, sizeof(ZG_RX_HDR)); 00131 00132 DBG("\r\nEth header\r\n"); 00133 hexdump((byte*)eth_hdr, sizeof(ZG_ETH_HDR)); 00134 00135 //Since the ZG_ETH_HDR header is smaller than the ZG_RX_HDR one, we can copy the new header before the payload to get a full ethernet packet 00136 eth_buf = buf + sizeof(ZG_RX_HDR) - sizeof(ZG_ETH_HDR); 00137 eth_len = len - sizeof(ZG_RX_HDR) + sizeof(ZG_ETH_HDR); 00138 memcpy( eth_buf, (void*)eth_hdr, sizeof(ZG_ETH_HDR) ); 00139 00140 //Filter on packet type 00141 00142 switch (htons(eth_hdr->type)) { 00143 //IP or ARP packet 00144 case ETHTYPE_IP: 00145 case ETHTYPE_ARP: 00146 break; //OK 00147 default: 00148 return; //We do not know how to handle this 00149 } 00150 00151 #if ETH_PAD_SIZE 00152 eth_len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ 00153 #endif 00154 00155 //Now we can pass this nice ethernet packet to lwip 00156 //Allocate a buffer 00157 frame = pbuf_alloc(PBUF_RAW, eth_len, PBUF_POOL); 00158 if(frame == NULL) 00159 { 00160 //Out of memory 00161 return; 00162 } 00163 p = frame; 00164 00165 #if ETH_PAD_SIZE 00166 pbuf_header(frame, -ETH_PAD_SIZE); /* drop the padding word */ 00167 #endif 00168 00169 //Copy buffer into lwip memory pool 00170 while( eth_len > 0 ) 00171 { 00172 memcpy(p->payload, eth_buf, p->len); 00173 eth_buf += p->len; 00174 eth_len -= p->len; 00175 p = p->next; 00176 if( p == NULL ) 00177 { 00178 //Should not happen 00179 break; 00180 } 00181 } 00182 00183 if ( ethernet_input(frame, zg_netif) != ERR_OK ) //Pass the frame to lwip 00184 { 00185 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); 00186 pbuf_free(frame); 00187 frame = NULL; 00188 } 00189 } 00190 00191 00192 err_t zg_net_init(struct netif *netif) { 00193 LWIP_ASSERT("netif != NULL", (netif != NULL)); 00194 00195 memset(netif, 0, sizeof(struct netif)); 00196 00197 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 1500/*ZG_FIFO_BUF_SIZE*10*/); 00198 00199 /* maximum transfer unit */ 00200 netif->mtu = 1500;//ZG_FIFO_BUF_SIZE; 00201 00202 /* set MAC hardware address length */ 00203 netif->hwaddr_len = ETHARP_HWADDR_LEN; 00204 00205 /* set MAC hardware address */ 00206 if( !zg_data_mask.mac_addr ) //Get MAC addr from chip if not known yet 00207 { 00208 zg_mgmt_get_param(ZG_FIFO_MGMT_PARM_MACAD); 00209 } 00210 00211 memcpy(netif->hwaddr, zg_data.mac_addr, ETHARP_HWADDR_LEN); 00212 00213 /* device capabilities */ 00214 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ 00215 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP; 00216 00217 netif->state = NULL; 00218 00219 netif->name[0] = IFNAME0; 00220 netif->name[1] = IFNAME1; 00221 00222 /* We directly use etharp_output() here to save a function call. 00223 * You can instead declare your own function an call etharp_output() 00224 * from it if you have to do some checks before sending (e.g. if link 00225 * is available...) */ 00226 netif->output = etharp_output; 00227 netif->linkoutput = zg_output; 00228 00229 zg_netif = netif; 00230 00231 return ERR_OK; 00232 } 00233 00234 #endif
Generated on Tue Jul 12 2022 19:42:13 by 1.7.2