ZG2100 Network interface source

Committer:
donatien
Date:
Fri Jul 09 15:37:23 2010 +0000
Revision:
0:b802fc31f1db
Child:
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 0:b802fc31f1db 41 //#define __DEBUG
donatien 0:b802fc31f1db 42 #include "dbg/dbg.h"
donatien 0:b802fc31f1db 43
donatien 0:b802fc31f1db 44 #define IFNAME0 'w'
donatien 0:b802fc31f1db 45 #define IFNAME1 'l'
donatien 0:b802fc31f1db 46
donatien 0:b802fc31f1db 47 //void hexdump(byte* buffer, int size);
donatien 0:b802fc31f1db 48
donatien 0:b802fc31f1db 49 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 50 struct netif* zg_netif;
donatien 0:b802fc31f1db 51
donatien 0:b802fc31f1db 52 //To be called by Lwip
donatien 0:b802fc31f1db 53 static err_t zg_output(struct netif *netif, struct pbuf *p) //Transfer an ethernet frame : convert into ZG frame & TX it
donatien 0:b802fc31f1db 54 {
donatien 0:b802fc31f1db 55 // DBG("\r\nOut packet\r\n");
donatien 0:b802fc31f1db 56
donatien 0:b802fc31f1db 57 while( zg_send_is_busy() )
donatien 0:b802fc31f1db 58 {
donatien 0:b802fc31f1db 59 zg_process(); //Ugly but prevents lwip from feeding other packets
donatien 0:b802fc31f1db 60 }
donatien 0:b802fc31f1db 61 #if ETH_PAD_SIZE
donatien 0:b802fc31f1db 62 pbuf_header(p, -ETH_PAD_SIZE); //Drop padding word
donatien 0:b802fc31f1db 63 #endif
donatien 0:b802fc31f1db 64
donatien 0:b802fc31f1db 65 ZG_ETH_HDR* eth_hdr = (ZG_ETH_HDR*) p->payload;
donatien 0:b802fc31f1db 66
donatien 0:b802fc31f1db 67 ZG_TX_HDR* tx_hdr = (ZG_TX_HDR*)fifo_buf;
donatien 0:b802fc31f1db 68 memset((void*)tx_hdr, 0, sizeof(ZG_TX_HDR));
donatien 0:b802fc31f1db 69
donatien 0:b802fc31f1db 70 //Convert headers properly
donatien 0:b802fc31f1db 71 tx_hdr->zero = HTODS( 0 );
donatien 0:b802fc31f1db 72 memcpy( tx_hdr->dest, eth_hdr->dest, ZG_MACADDR_LEN );
donatien 0:b802fc31f1db 73 memcpy( tx_hdr->snap, snap, ZG_SNAP_LEN );
donatien 0:b802fc31f1db 74 tx_hdr->type = eth_hdr->type; //Lwip as already put the type in BE
donatien 0:b802fc31f1db 75
donatien 0:b802fc31f1db 76 //DBG("\r\nEth header\r\n");
donatien 0:b802fc31f1db 77 //hexdump((byte*)eth_hdr, sizeof(ZG_ETH_HDR));
donatien 0:b802fc31f1db 78
donatien 0:b802fc31f1db 79 //DBG("\r\nZg header\r\n");
donatien 0:b802fc31f1db 80 //hexdump((byte*)tx_hdr, sizeof(ZG_TX_HDR));
donatien 0:b802fc31f1db 81
donatien 0:b802fc31f1db 82 //Open TX fifo & send header
donatien 0:b802fc31f1db 83 zg_send_start();
donatien 0:b802fc31f1db 84 zg_send( (byte*)tx_hdr, sizeof(ZG_TX_HDR) );
donatien 0:b802fc31f1db 85
donatien 0:b802fc31f1db 86 //Send remaining payload of this buf
donatien 0:b802fc31f1db 87 zg_send( (byte*)(((byte*)p->payload) + sizeof(ZG_ETH_HDR)), (p->len - sizeof(ZG_ETH_HDR)) );
donatien 0:b802fc31f1db 88
donatien 0:b802fc31f1db 89 while(p->next != NULL)
donatien 0:b802fc31f1db 90 {
donatien 0:b802fc31f1db 91 p = p->next;
donatien 0:b802fc31f1db 92 zg_send((byte*)p->payload, p->len);
donatien 0:b802fc31f1db 93 }
donatien 0:b802fc31f1db 94
donatien 0:b802fc31f1db 95 zg_send_end();
donatien 0:b802fc31f1db 96
donatien 0:b802fc31f1db 97 #if ETH_PAD_SIZE
donatien 0:b802fc31f1db 98 pbuf_header(p, ETH_PAD_SIZE); //Reclaim padding word
donatien 0:b802fc31f1db 99 #endif
donatien 0:b802fc31f1db 100
donatien 0:b802fc31f1db 101 LINK_STATS_INC(link.xmit);
donatien 0:b802fc31f1db 102 return ERR_OK;
donatien 0:b802fc31f1db 103 }
donatien 0:b802fc31f1db 104
donatien 0:b802fc31f1db 105 //Callback from zg_drv
donatien 0:b802fc31f1db 106 void zg_on_input(byte* buf, int len) //On reception of a ZG frame : convert into Eth frame & feed lwip
donatien 0:b802fc31f1db 107 {
donatien 0:b802fc31f1db 108 struct pbuf *frame, *p; //Lwip buffers
donatien 0:b802fc31f1db 109 byte* eth_buf; //Position of the Ethernet packet buffer
donatien 0:b802fc31f1db 110 int eth_len; //Length of this buffer
donatien 0:b802fc31f1db 111 ZG_ETH_HDR eth_hdr_data; //Temporary buffer
donatien 0:b802fc31f1db 112 ZG_ETH_HDR* eth_hdr = &eth_hdr_data; //just to remain consistent in notations
donatien 0:b802fc31f1db 113 memset((void*)eth_hdr, 0, sizeof(ZG_ETH_HDR));
donatien 0:b802fc31f1db 114
donatien 0:b802fc31f1db 115 //DBG("\r\nIncoming packet\r\n");
donatien 0:b802fc31f1db 116 //hexdump(buf, len);
donatien 0:b802fc31f1db 117
donatien 0:b802fc31f1db 118 ZG_RX_HDR* rx_hdr = (ZG_RX_HDR*)buf;
donatien 0:b802fc31f1db 119
donatien 0:b802fc31f1db 120 memcpy( eth_hdr->dest, rx_hdr->dest, ZG_MACADDR_LEN );
donatien 0:b802fc31f1db 121 memcpy( eth_hdr->src, rx_hdr->src, ZG_MACADDR_LEN );
donatien 0:b802fc31f1db 122 eth_hdr->type = rx_hdr->type; //Lwip will convert the type in LE
donatien 0:b802fc31f1db 123
donatien 0:b802fc31f1db 124 //DBG("\r\nZg header\r\n");
donatien 0:b802fc31f1db 125 //hexdump((byte*)rx_hdr, sizeof(ZG_RX_HDR));
donatien 0:b802fc31f1db 126
donatien 0:b802fc31f1db 127 //DBG("\r\nEth header\r\n");
donatien 0:b802fc31f1db 128 //hexdump((byte*)eth_hdr, sizeof(ZG_ETH_HDR));
donatien 0:b802fc31f1db 129
donatien 0:b802fc31f1db 130 //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 131 eth_buf = buf + sizeof(ZG_RX_HDR) - sizeof(ZG_ETH_HDR);
donatien 0:b802fc31f1db 132 eth_len = len - sizeof(ZG_RX_HDR) + sizeof(ZG_ETH_HDR);
donatien 0:b802fc31f1db 133 memcpy( eth_buf, (void*)eth_hdr, sizeof(ZG_ETH_HDR) );
donatien 0:b802fc31f1db 134
donatien 0:b802fc31f1db 135 //Filter on packet type
donatien 0:b802fc31f1db 136
donatien 0:b802fc31f1db 137 switch (htons(eth_hdr->type)) {
donatien 0:b802fc31f1db 138 //IP or ARP packet
donatien 0:b802fc31f1db 139 case ETHTYPE_IP:
donatien 0:b802fc31f1db 140 case ETHTYPE_ARP:
donatien 0:b802fc31f1db 141 break; //OK
donatien 0:b802fc31f1db 142 default:
donatien 0:b802fc31f1db 143 return; //We do not know how to handle this
donatien 0:b802fc31f1db 144 }
donatien 0:b802fc31f1db 145
donatien 0:b802fc31f1db 146 //Now we can pass this nice ethnernet packet to lwip
donatien 0:b802fc31f1db 147 //Allocate a buffer
donatien 0:b802fc31f1db 148 frame = pbuf_alloc(PBUF_RAW, eth_len, PBUF_POOL);
donatien 0:b802fc31f1db 149 if(frame == NULL)
donatien 0:b802fc31f1db 150 {
donatien 0:b802fc31f1db 151 //Out of memory
donatien 0:b802fc31f1db 152 return;
donatien 0:b802fc31f1db 153 }
donatien 0:b802fc31f1db 154 p = frame;
donatien 0:b802fc31f1db 155
donatien 0:b802fc31f1db 156 //Copy buffer into lwip memory pool
donatien 0:b802fc31f1db 157 while( eth_len > 0 )
donatien 0:b802fc31f1db 158 {
donatien 0:b802fc31f1db 159 memcpy(p->payload, eth_buf, p->len);
donatien 0:b802fc31f1db 160 eth_buf += p->len;
donatien 0:b802fc31f1db 161 eth_len -= p->len;
donatien 0:b802fc31f1db 162 p = p->next;
donatien 0:b802fc31f1db 163 if( p == NULL )
donatien 0:b802fc31f1db 164 {
donatien 0:b802fc31f1db 165 //Should not happen
donatien 0:b802fc31f1db 166 break;
donatien 0:b802fc31f1db 167 }
donatien 0:b802fc31f1db 168 }
donatien 0:b802fc31f1db 169
donatien 0:b802fc31f1db 170 if ( ethernet_input(frame, zg_netif) != ERR_OK ) //Pass the frame to lwip
donatien 0:b802fc31f1db 171 {
donatien 0:b802fc31f1db 172 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
donatien 0:b802fc31f1db 173 pbuf_free(frame);
donatien 0:b802fc31f1db 174 frame = NULL;
donatien 0:b802fc31f1db 175 }
donatien 0:b802fc31f1db 176 }
donatien 0:b802fc31f1db 177
donatien 0:b802fc31f1db 178
donatien 0:b802fc31f1db 179 err_t zg_net_init(struct netif *netif) {
donatien 0:b802fc31f1db 180 LWIP_ASSERT("netif != NULL", (netif != NULL));
donatien 0:b802fc31f1db 181
donatien 0:b802fc31f1db 182 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 0x2EA/*ZG_FIFO_BUF_SIZE*10*/);
donatien 0:b802fc31f1db 183
donatien 0:b802fc31f1db 184 /* maximum transfer unit */
donatien 0:b802fc31f1db 185 netif->mtu = 0x2EA;//ZG_FIFO_BUF_SIZE;
donatien 0:b802fc31f1db 186
donatien 0:b802fc31f1db 187 /* set MAC hardware address length */
donatien 0:b802fc31f1db 188 netif->hwaddr_len = ETHARP_HWADDR_LEN;
donatien 0:b802fc31f1db 189
donatien 0:b802fc31f1db 190 /* set MAC hardware address */
donatien 0:b802fc31f1db 191 if( !zg_data_mask.mac_addr ) //Get MAC addr from chip if not known yet
donatien 0:b802fc31f1db 192 {
donatien 0:b802fc31f1db 193 zg_mgmt_get_param(ZG_FIFO_MGMT_PARM_MACAD);
donatien 0:b802fc31f1db 194 }
donatien 0:b802fc31f1db 195
donatien 0:b802fc31f1db 196 memcpy(netif->hwaddr, zg_data.mac_addr, ETHARP_HWADDR_LEN);
donatien 0:b802fc31f1db 197
donatien 0:b802fc31f1db 198 /* device capabilities */
donatien 0:b802fc31f1db 199 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
donatien 0:b802fc31f1db 200 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
donatien 0:b802fc31f1db 201
donatien 0:b802fc31f1db 202 netif->state = NULL;
donatien 0:b802fc31f1db 203
donatien 0:b802fc31f1db 204 netif->name[0] = IFNAME0;
donatien 0:b802fc31f1db 205 netif->name[1] = IFNAME1;
donatien 0:b802fc31f1db 206
donatien 0:b802fc31f1db 207 /* We directly use etharp_output() here to save a function call.
donatien 0:b802fc31f1db 208 * You can instead declare your own function an call etharp_output()
donatien 0:b802fc31f1db 209 * from it if you have to do some checks before sending (e.g. if link
donatien 0:b802fc31f1db 210 * is available...) */
donatien 0:b802fc31f1db 211 netif->output = etharp_output;
donatien 0:b802fc31f1db 212 netif->linkoutput = zg_output;
donatien 0:b802fc31f1db 213
donatien 0:b802fc31f1db 214 zg_netif = netif;
donatien 0:b802fc31f1db 215
donatien 0:b802fc31f1db 216 return ERR_OK;
donatien 0:b802fc31f1db 217 }
donatien 0:b802fc31f1db 218
donatien 0:b802fc31f1db 219 #endif