ZG2100 Network interface source

Committer:
donatien
Date:
Fri Aug 06 10:46:03 2010 +0000
Revision:
4:e00281c7453d
Parent:
1:3a7c15057192

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:b802fc31f1db 1
donatien 0:b802fc31f1db 2 /*
donatien 0:b802fc31f1db 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
donatien 0:b802fc31f1db 4
donatien 0:b802fc31f1db 5 Permission is hereby granted, free of charge, to any person obtaining a copy
donatien 0:b802fc31f1db 6 of this software and associated documentation files (the "Software"), to deal
donatien 0:b802fc31f1db 7 in the Software without restriction, including without limitation the rights
donatien 0:b802fc31f1db 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
donatien 0:b802fc31f1db 9 copies of the Software, and to permit persons to whom the Software is
donatien 0:b802fc31f1db 10 furnished to do so, subject to the following conditions:
donatien 0:b802fc31f1db 11
donatien 0:b802fc31f1db 12 The above copyright notice and this permission notice shall be included in
donatien 0:b802fc31f1db 13 all copies or substantial portions of the Software.
donatien 0:b802fc31f1db 14
donatien 0:b802fc31f1db 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
donatien 0:b802fc31f1db 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
donatien 0:b802fc31f1db 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
donatien 0:b802fc31f1db 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
donatien 0:b802fc31f1db 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
donatien 0:b802fc31f1db 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
donatien 0:b802fc31f1db 21 THE SOFTWARE.
donatien 0:b802fc31f1db 22 */
donatien 0:b802fc31f1db 23
donatien 0:b802fc31f1db 24 #include "netCfg.h"
donatien 0:b802fc31f1db 25 #if NET_ZG2100
donatien 0:b802fc31f1db 26
donatien 0:b802fc31f1db 27 #include "zg_defs.h"
donatien 0:b802fc31f1db 28 #include "zg_net.h"
donatien 0:b802fc31f1db 29 #include "zg_drv.h"
donatien 0:b802fc31f1db 30
donatien 0:b802fc31f1db 31 #include "lwip/opt.h"
donatien 0:b802fc31f1db 32
donatien 0:b802fc31f1db 33 #include "lwip/def.h"
donatien 0:b802fc31f1db 34 #include "lwip/pbuf.h"
donatien 0:b802fc31f1db 35 #include "lwip/sys.h"
donatien 0:b802fc31f1db 36 #include "lwip/stats.h"
donatien 0:b802fc31f1db 37 #include "netif/etharp.h"
donatien 0:b802fc31f1db 38
donatien 0:b802fc31f1db 39 #include "string.h"
donatien 0:b802fc31f1db 40
donatien 1:3a7c15057192 41 #ifdef __LWIP_DEBUG
donatien 1:3a7c15057192 42 #undef __LWIP_DEBUG
donatien 1:3a7c15057192 43 #endif
donatien 0:b802fc31f1db 44 //#define __DEBUG
donatien 0:b802fc31f1db 45 #include "dbg/dbg.h"
donatien 0:b802fc31f1db 46
donatien 0:b802fc31f1db 47 #define IFNAME0 'w'
donatien 0:b802fc31f1db 48 #define IFNAME1 'l'
donatien 0:b802fc31f1db 49
donatien 0:b802fc31f1db 50 //void hexdump(byte* buffer, int size);
donatien 1:3a7c15057192 51 #define hexdump(x,y)
donatien 0:b802fc31f1db 52
donatien 0:b802fc31f1db 53 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)
donatien 0:b802fc31f1db 54 struct netif* zg_netif;
donatien 0:b802fc31f1db 55
donatien 0:b802fc31f1db 56 //To be called by Lwip
donatien 0:b802fc31f1db 57 static err_t zg_output(struct netif *netif, struct pbuf *p) //Transfer an ethernet frame : convert into ZG frame & TX it
donatien 0:b802fc31f1db 58 {
donatien 1:3a7c15057192 59 DBG("\r\nOut packet\r\n");
donatien 0:b802fc31f1db 60
donatien 0:b802fc31f1db 61 while( zg_send_is_busy() )
donatien 0:b802fc31f1db 62 {
donatien 0:b802fc31f1db 63 zg_process(); //Ugly but prevents lwip from feeding other packets
donatien 0:b802fc31f1db 64 }
donatien 0:b802fc31f1db 65 #if ETH_PAD_SIZE
donatien 0:b802fc31f1db 66 pbuf_header(p, -ETH_PAD_SIZE); //Drop padding word
donatien 0:b802fc31f1db 67 #endif
donatien 0:b802fc31f1db 68
donatien 0:b802fc31f1db 69 ZG_ETH_HDR* eth_hdr = (ZG_ETH_HDR*) p->payload;
donatien 0:b802fc31f1db 70
donatien 0:b802fc31f1db 71 ZG_TX_HDR* tx_hdr = (ZG_TX_HDR*)fifo_buf;
donatien 0:b802fc31f1db 72 memset((void*)tx_hdr, 0, sizeof(ZG_TX_HDR));
donatien 0:b802fc31f1db 73
donatien 0:b802fc31f1db 74 //Convert headers properly
donatien 0:b802fc31f1db 75 tx_hdr->zero = HTODS( 0 );
donatien 0:b802fc31f1db 76 memcpy( tx_hdr->dest, eth_hdr->dest, ZG_MACADDR_LEN );
donatien 0:b802fc31f1db 77 memcpy( tx_hdr->snap, snap, ZG_SNAP_LEN );
donatien 1:3a7c15057192 78 tx_hdr->type = eth_hdr->type; //Lwip has already put the type in BE
donatien 0:b802fc31f1db 79
donatien 1:3a7c15057192 80 DBG("\r\nEth header\r\n");
donatien 1:3a7c15057192 81 hexdump((byte*)eth_hdr, sizeof(ZG_ETH_HDR));
donatien 0:b802fc31f1db 82
donatien 1:3a7c15057192 83 DBG("\r\nZg header\r\n");
donatien 1:3a7c15057192 84 hexdump((byte*)tx_hdr, sizeof(ZG_TX_HDR));
donatien 0:b802fc31f1db 85
donatien 0:b802fc31f1db 86 //Open TX fifo & send header
donatien 0:b802fc31f1db 87 zg_send_start();
donatien 0:b802fc31f1db 88 zg_send( (byte*)tx_hdr, sizeof(ZG_TX_HDR) );
donatien 0:b802fc31f1db 89
donatien 0:b802fc31f1db 90 //Send remaining payload of this buf
donatien 0:b802fc31f1db 91 zg_send( (byte*)(((byte*)p->payload) + sizeof(ZG_ETH_HDR)), (p->len - sizeof(ZG_ETH_HDR)) );
donatien 0:b802fc31f1db 92
donatien 0:b802fc31f1db 93 while(p->next != NULL)
donatien 0:b802fc31f1db 94 {
donatien 0:b802fc31f1db 95 p = p->next;
donatien 0:b802fc31f1db 96 zg_send((byte*)p->payload, p->len);
donatien 1:3a7c15057192 97 //FIX: Watchout, p content MUST be preserved for proper TCP functionality!!!
donatien 0:b802fc31f1db 98 }
donatien 0:b802fc31f1db 99
donatien 0:b802fc31f1db 100 zg_send_end();
donatien 0:b802fc31f1db 101
donatien 0:b802fc31f1db 102 #if ETH_PAD_SIZE
donatien 0:b802fc31f1db 103 pbuf_header(p, ETH_PAD_SIZE); //Reclaim padding word
donatien 0:b802fc31f1db 104 #endif
donatien 0:b802fc31f1db 105
donatien 0:b802fc31f1db 106 LINK_STATS_INC(link.xmit);
donatien 0:b802fc31f1db 107 return ERR_OK;
donatien 0:b802fc31f1db 108 }
donatien 0:b802fc31f1db 109
donatien 0:b802fc31f1db 110 //Callback from zg_drv
donatien 0:b802fc31f1db 111 void zg_on_input(byte* buf, int len) //On reception of a ZG frame : convert into Eth frame & feed lwip
donatien 0:b802fc31f1db 112 {
donatien 0:b802fc31f1db 113 struct pbuf *frame, *p; //Lwip buffers
donatien 0:b802fc31f1db 114 byte* eth_buf; //Position of the Ethernet packet buffer
donatien 0:b802fc31f1db 115 int eth_len; //Length of this buffer
donatien 0:b802fc31f1db 116 ZG_ETH_HDR eth_hdr_data; //Temporary buffer
donatien 0:b802fc31f1db 117 ZG_ETH_HDR* eth_hdr = &eth_hdr_data; //just to remain consistent in notations
donatien 0:b802fc31f1db 118 memset((void*)eth_hdr, 0, sizeof(ZG_ETH_HDR));
donatien 0:b802fc31f1db 119
donatien 1:3a7c15057192 120 DBG("\r\nIncoming packet\r\n");
donatien 1:3a7c15057192 121 hexdump(buf, len);
donatien 0:b802fc31f1db 122
donatien 0:b802fc31f1db 123 ZG_RX_HDR* rx_hdr = (ZG_RX_HDR*)buf;
donatien 0:b802fc31f1db 124
donatien 0:b802fc31f1db 125 memcpy( eth_hdr->dest, rx_hdr->dest, ZG_MACADDR_LEN );
donatien 0:b802fc31f1db 126 memcpy( eth_hdr->src, rx_hdr->src, ZG_MACADDR_LEN );
donatien 0:b802fc31f1db 127 eth_hdr->type = rx_hdr->type; //Lwip will convert the type in LE
donatien 0:b802fc31f1db 128
donatien 1:3a7c15057192 129 DBG("\r\nZg header\r\n");
donatien 1:3a7c15057192 130 hexdump((byte*)rx_hdr, sizeof(ZG_RX_HDR));
donatien 0:b802fc31f1db 131
donatien 1:3a7c15057192 132 DBG("\r\nEth header\r\n");
donatien 1:3a7c15057192 133 hexdump((byte*)eth_hdr, sizeof(ZG_ETH_HDR));
donatien 0:b802fc31f1db 134
donatien 0:b802fc31f1db 135 //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
donatien 0:b802fc31f1db 136 eth_buf = buf + sizeof(ZG_RX_HDR) - sizeof(ZG_ETH_HDR);
donatien 0:b802fc31f1db 137 eth_len = len - sizeof(ZG_RX_HDR) + sizeof(ZG_ETH_HDR);
donatien 0:b802fc31f1db 138 memcpy( eth_buf, (void*)eth_hdr, sizeof(ZG_ETH_HDR) );
donatien 0:b802fc31f1db 139
donatien 0:b802fc31f1db 140 //Filter on packet type
donatien 0:b802fc31f1db 141
donatien 0:b802fc31f1db 142 switch (htons(eth_hdr->type)) {
donatien 0:b802fc31f1db 143 //IP or ARP packet
donatien 0:b802fc31f1db 144 case ETHTYPE_IP:
donatien 0:b802fc31f1db 145 case ETHTYPE_ARP:
donatien 0:b802fc31f1db 146 break; //OK
donatien 0:b802fc31f1db 147 default:
donatien 0:b802fc31f1db 148 return; //We do not know how to handle this
donatien 0:b802fc31f1db 149 }
donatien 0:b802fc31f1db 150
donatien 1:3a7c15057192 151 #if ETH_PAD_SIZE
donatien 1:3a7c15057192 152 eth_len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
donatien 1:3a7c15057192 153 #endif
donatien 1:3a7c15057192 154
donatien 1:3a7c15057192 155 //Now we can pass this nice ethernet packet to lwip
donatien 0:b802fc31f1db 156 //Allocate a buffer
donatien 0:b802fc31f1db 157 frame = pbuf_alloc(PBUF_RAW, eth_len, PBUF_POOL);
donatien 0:b802fc31f1db 158 if(frame == NULL)
donatien 0:b802fc31f1db 159 {
donatien 0:b802fc31f1db 160 //Out of memory
donatien 0:b802fc31f1db 161 return;
donatien 0:b802fc31f1db 162 }
donatien 0:b802fc31f1db 163 p = frame;
donatien 0:b802fc31f1db 164
donatien 1:3a7c15057192 165 #if ETH_PAD_SIZE
donatien 1:3a7c15057192 166 pbuf_header(frame, -ETH_PAD_SIZE); /* drop the padding word */
donatien 1:3a7c15057192 167 #endif
donatien 1:3a7c15057192 168
donatien 0:b802fc31f1db 169 //Copy buffer into lwip memory pool
donatien 0:b802fc31f1db 170 while( eth_len > 0 )
donatien 0:b802fc31f1db 171 {
donatien 0:b802fc31f1db 172 memcpy(p->payload, eth_buf, p->len);
donatien 0:b802fc31f1db 173 eth_buf += p->len;
donatien 0:b802fc31f1db 174 eth_len -= p->len;
donatien 0:b802fc31f1db 175 p = p->next;
donatien 0:b802fc31f1db 176 if( p == NULL )
donatien 0:b802fc31f1db 177 {
donatien 0:b802fc31f1db 178 //Should not happen
donatien 0:b802fc31f1db 179 break;
donatien 0:b802fc31f1db 180 }
donatien 0:b802fc31f1db 181 }
donatien 1:3a7c15057192 182
donatien 0:b802fc31f1db 183 if ( ethernet_input(frame, zg_netif) != ERR_OK ) //Pass the frame to lwip
donatien 0:b802fc31f1db 184 {
donatien 0:b802fc31f1db 185 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
donatien 0:b802fc31f1db 186 pbuf_free(frame);
donatien 0:b802fc31f1db 187 frame = NULL;
donatien 0:b802fc31f1db 188 }
donatien 0:b802fc31f1db 189 }
donatien 0:b802fc31f1db 190
donatien 0:b802fc31f1db 191
donatien 0:b802fc31f1db 192 err_t zg_net_init(struct netif *netif) {
donatien 0:b802fc31f1db 193 LWIP_ASSERT("netif != NULL", (netif != NULL));
donatien 0:b802fc31f1db 194
donatien 1:3a7c15057192 195 memset(netif, 0, sizeof(struct netif));
donatien 1:3a7c15057192 196
donatien 1:3a7c15057192 197 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 1500/*ZG_FIFO_BUF_SIZE*10*/);
donatien 0:b802fc31f1db 198
donatien 0:b802fc31f1db 199 /* maximum transfer unit */
donatien 1:3a7c15057192 200 netif->mtu = 1500;//ZG_FIFO_BUF_SIZE;
donatien 0:b802fc31f1db 201
donatien 0:b802fc31f1db 202 /* set MAC hardware address length */
donatien 0:b802fc31f1db 203 netif->hwaddr_len = ETHARP_HWADDR_LEN;
donatien 0:b802fc31f1db 204
donatien 0:b802fc31f1db 205 /* set MAC hardware address */
donatien 0:b802fc31f1db 206 if( !zg_data_mask.mac_addr ) //Get MAC addr from chip if not known yet
donatien 0:b802fc31f1db 207 {
donatien 0:b802fc31f1db 208 zg_mgmt_get_param(ZG_FIFO_MGMT_PARM_MACAD);
donatien 0:b802fc31f1db 209 }
donatien 0:b802fc31f1db 210
donatien 0:b802fc31f1db 211 memcpy(netif->hwaddr, zg_data.mac_addr, ETHARP_HWADDR_LEN);
donatien 0:b802fc31f1db 212
donatien 0:b802fc31f1db 213 /* device capabilities */
donatien 0:b802fc31f1db 214 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
donatien 1:3a7c15057192 215 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP;
donatien 0:b802fc31f1db 216
donatien 0:b802fc31f1db 217 netif->state = NULL;
donatien 0:b802fc31f1db 218
donatien 0:b802fc31f1db 219 netif->name[0] = IFNAME0;
donatien 0:b802fc31f1db 220 netif->name[1] = IFNAME1;
donatien 0:b802fc31f1db 221
donatien 0:b802fc31f1db 222 /* We directly use etharp_output() here to save a function call.
donatien 0:b802fc31f1db 223 * You can instead declare your own function an call etharp_output()
donatien 0:b802fc31f1db 224 * from it if you have to do some checks before sending (e.g. if link
donatien 0:b802fc31f1db 225 * is available...) */
donatien 0:b802fc31f1db 226 netif->output = etharp_output;
donatien 0:b802fc31f1db 227 netif->linkoutput = zg_output;
donatien 0:b802fc31f1db 228
donatien 0:b802fc31f1db 229 zg_netif = netif;
donatien 0:b802fc31f1db 230
donatien 0:b802fc31f1db 231 return ERR_OK;
donatien 0:b802fc31f1db 232 }
donatien 0:b802fc31f1db 233
donatien 0:b802fc31f1db 234 #endif