1 /**
2 * @file
3 * Ethernet Interface Skeleton
4 *
5 */
6
7 /*
8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without modification,
12 * are permitted provided that the following conditions are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31 * OF SUCH DAMAGE.
32 *
33 * This file is part of the lwIP TCP/IP stack.
34 *
35 * Author: Adam Dunkels <adam@sics.se>
36 *
37 */
38
39 /*
40 * This file is a skeleton for developing Ethernet network interface
41 * drivers for lwIP. Add code to the low_level functions and do a
42 * search-and-replace for the word "ethernetif" to replace it with
43 * something that better describes your network interface.
44 */
45
46 #include "common/bk_include.h"
47
48 #include "lwip/opt.h"
49 #include "lwip/def.h"
50 #include "lwip/mem.h"
51 #include "lwip/pbuf.h"
52 #include "lwip/sys.h"
53 #include <lwip/stats.h>
54 #include <lwip/snmp.h>
55 #ifdef CONFIG_IPV6
56 #include <lwip/ethip6.h>
57 #endif
58
59 #include "ethernetif.h"
60
61 #include <stdio.h>
62 #include <string.h>
63
64 #include "netif/etharp.h"
65
66 #include "lwip_netif_address.h"
67
68 #include "bk_drv_model.h"
69 #include <os/mem.h>
70
71 #include <os/os.h>
72
73 /* Define those to better describe your network interface. */
74 #define IFNAME0 'e'
75 #define IFNAME1 'n'
76
77 #include "bk_uart.h"
78 #include "bk_wifi_netif.h"
79 #include "bk_private/bk_wifi.h"
80
81 //TODO should use registered callback here!!!
82 extern int ke_l2_packet_tx(unsigned char *buf, int len, int flag);
83 extern int bmsg_tx_sender(struct pbuf *p, uint32_t vif_idx);
84 #if CONFIG_WIFI6_CODE_STACK
85 extern int bmsg_special_tx_sender(struct pbuf *p, uint32_t vif_idx);
86 #endif
87 /* Forward declarations. */
88 void ethernetif_input(int iface, struct pbuf *p);
89
90 /**
91 * In this function, the hardware should be initialized.
92 * Called from ethernetif_init().
93 *
94 * @param netif the already initialized lwip network interface structure
95 * for this ethernetif
96 */
97
98 const char wlan_name[][6] =
99 {
100 "wlan0\0",
101 "wlan1\0",
102 "wlan2\0",
103 "wlan3\0",
104 };
low_level_init(struct netif * netif)105 static void low_level_init(struct netif *netif)
106 {
107 void *vif = netif->state;
108 u8 *macptr = wifi_netif_vif_to_mac(vif);
109 int vif_index = wifi_netif_vif_to_vifid(vif);
110
111 #if LWIP_NETIF_HOSTNAME
112 /* Initialize interface hostname */
113 netif->hostname = (char*)&wlan_name[vif_index];
114 #endif /* LWIP_NETIF_HOSTNAME */
115
116 /* set MAC hardware address length */
117 LWIP_LOGI("enter low level!\r\n");
118 LWIP_LOGI("mac %2x:%2x:%2x:%2x:%2x:%2x\r\n", macptr[0], macptr[1], macptr[2],
119 macptr[3], macptr[4], macptr[5]);
120
121 netif->hwaddr_len = ETHARP_HWADDR_LEN;
122 os_memcpy(netif->hwaddr, macptr, ETHARP_HWADDR_LEN);
123 /* maximum transfer unit */
124 netif->mtu = 1500;
125 /* device capabilities */
126 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
127 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
128 #ifdef LWIP_IGMP
129 netif->flags |= NETIF_FLAG_IGMP;
130 #endif
131 #if defined (LWIP_IPV6_MLD) && (LWIP_IPV6_MLD == 1)
132 netif->flags |= NETIF_FLAG_MLD6;
133 #endif
134 LWIP_LOGI("leave low level!\r\n");
135 }
136
137 /**
138 * This function should do the actual transmission of the packet. The packet is
139 * contained in the pbuf that is passed to the function. This pbuf
140 * might be chained.
141 *
142 * @param netif the lwip network interface structure for this ethernetif
143 * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
144 * @return ERR_OK if the packet could be sent
145 * an err_t value if the packet couldn't be sent
146 *
147 * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
148 * strange results. You might consider waiting for space in the DMA queue
149 * to become availale since the stack doesn't retry to send a packet
150 * dropped because of memory failure (except for the TCP timers).
151 */
low_level_output(struct netif * netif,struct pbuf * p)152 static err_t low_level_output(struct netif *netif, struct pbuf *p)
153 {
154 int ret;
155 err_t err = ERR_OK;
156 uint8_t vif_idx = wifi_netif_vif_to_vifid(netif->state);
157 #if !CONFIG_HARMONY_LWIP
158 #if CONFIG_WIFI6_CODE_STACK
159 //LWIP_LOGI("output:%x\r\n", p);
160 extern bool special_arp_flag;
161 if(special_arp_flag)
162 {
163 ret = bmsg_special_tx_sender(p, (uint32_t)vif_idx);
164 special_arp_flag = false;
165 }
166 else
167 #endif
168 #endif
169 {
170 ret = bmsg_tx_sender(p, (uint32_t)vif_idx);
171 }
172 if(0 != ret)
173 {
174 err = ERR_TIMEOUT;
175 }
176
177 return err;
178 }
179
180 /**
181 * This function should be called when a packet is ready to be read
182 * from the interface. It uses the function low_level_input() that
183 * should handle the actual reception of bytes from the network
184 * interface. Then the type of the received packet is determined and
185 * the appropriate input function is called.
186 *
187 * @param netif the lwip network interface structure for this ethernetif
188 */
189 void
ethernetif_input(int iface,struct pbuf * p)190 ethernetif_input(int iface, struct pbuf *p)
191 {
192 struct eth_hdr *ethhdr;
193 struct netif *netif;
194 void *vif;
195
196 if (p->len <= SIZEOF_ETH_HDR) {
197 pbuf_free(p);
198 return;
199 }
200
201 vif = wifi_netif_vifid_to_vif(iface);
202 netif = (struct netif *)wifi_netif_get_vif_private_data(vif);
203 if(!netif) {
204 //LWIP_LOGI("ethernetif_input no netif found %d\r\n", iface);
205 pbuf_free(p);
206 p = NULL;
207 return;
208 }
209
210 /* points to packet payload, which starts with an Ethernet header */
211 ethhdr = p->payload;
212
213 if( (memcmp(netif->hwaddr,ethhdr->src.addr,NETIF_MAX_HWADDR_LEN)==0) && (htons(ethhdr->type) !=ETHTYPE_ARP) )
214 {
215 LWIP_DEBUGF(ETHARP_DEBUG ,("ethernet_input frame is my send,drop it\r\n"));
216 pbuf_free(p);
217 return;
218 }
219
220 switch (htons(ethhdr->type))
221 {
222 /* IP or ARP packet? */
223 case ETHTYPE_IP:
224 case ETHTYPE_ARP:
225 #ifdef CONFIG_IPV6
226 case ETHTYPE_IPV6:
227 wlan_set_multicast_flag();
228 #endif
229 #if PPPOE_SUPPORT
230 /* PPPoE packet? */
231 case ETHTYPE_PPPOEDISC:
232 case ETHTYPE_PPPOE:
233 #endif /* PPPOE_SUPPORT */
234 /* full packet send to tcpip_thread to process */
235 if (netif->input(p, netif) != ERR_OK) // ethernet_input
236 {
237 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\r\n"));
238 pbuf_free(p);
239 p = NULL;
240 }
241 break;
242 #if CONFIG_HARMONY_LWIP
243 /* ETHTYPE_EAPOL */
244 case 0x888EU:
245 #else
246 case ETHTYPE_EAPOL:
247 #endif
248 ke_l2_packet_tx(p->payload, p->len, iface);
249 pbuf_free(p);
250 p = NULL;
251 break;
252
253 default:
254 pbuf_free(p);
255 p = NULL;
256 break;
257 }
258
259 }
260
261 /**
262 * Should be called at the beginning of the program to set up the
263 * network interface. It calls the function low_level_init() to do the
264 * actual setup of the hardware.
265 *
266 * This function should be passed as a parameter to netif_add().
267 *
268 * @param netif the lwip network interface structure for this ethernetif
269 * @return ERR_OK if the loopif is initialized
270 * ERR_MEM if private data couldn't be allocated
271 * any other err_t on error
272 */
273 err_t
ethernetif_init(struct netif * netif)274 ethernetif_init(struct netif *netif)
275 {
276 LWIP_ASSERT("netif != NULL", (netif != NULL));
277
278 /*
279 * Initialize the snmp variables and counters inside the struct netif.
280 * The last argument should be replaced with your link speed, in units
281 * of bits per second.
282 */
283 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
284
285 netif->name[0] = IFNAME0;
286 netif->name[1] = IFNAME1;
287 /* We directly use etharp_output() here to save a function call.
288 * You can instead declare your own function an call etharp_output()
289 * from it if you have to do some checks before sending (e.g. if link
290 * is available...) */
291 netif->output = etharp_output;
292 netif->linkoutput = low_level_output;
293 #ifdef CONFIG_IPV6
294 netif->output_ip6 = ethip6_output;
295 #endif
296
297 /* initialize the hardware */
298 low_level_init(netif);
299
300 return ERR_OK;
301 }
302
303 /**
304 * Should be called at the beginning of the program to set up the
305 * network interface. It calls the function low_level_init() to do the
306 * actual setup of the hardware.
307 *
308 * This function should be passed as a parameter to netifapi_netif_add().
309 *
310 * @param netif the lwip network interface structure for this ethernetif
311 * @return ERR_OK if the loopif is initialized
312 * ERR_MEM if private data couldn't be allocated
313 * any other err_t on error
314 */
lwip_netif_init(struct netif * netif)315 err_t lwip_netif_init(struct netif *netif)
316 {
317 LWIP_ASSERT("netif != NULL", (netif != NULL));
318
319 /*
320 * Initialize the snmp variables and counters inside the struct netif.
321 * The last argument should be replaced with your link speed, in units
322 * of bits per second.
323 */
324 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
325
326 netif->name[0] = IFNAME0;
327 netif->name[1] = IFNAME1;
328 /* We directly use etharp_output() here to save a function call.
329 * You can instead declare your own function an call etharp_output()
330 * from it if you have to do some checks before sending (e.g. if link
331 * is available...) */
332 netif->output = etharp_output;
333 netif->linkoutput = low_level_output;
334 #ifdef CONFIG_IPV6
335 netif->output_ip6 = ethip6_output;
336 #endif
337
338 /* initialize the hardware */
339 low_level_init(netif);
340 return ERR_OK;
341 }
342
lwip_netif_uap_init(struct netif * netif)343 err_t lwip_netif_uap_init(struct netif *netif)
344 {
345 LWIP_ASSERT("netif != NULL", (netif != NULL));
346
347 //netif->state = NULL;
348 netif->name[0] = 'u';
349 netif->name[1] = 'a';
350 /* We directly use etharp_output() here to save a function call.
351 * You can instead declare your own function an call etharp_output()
352 * from it if you have to do some checks before sending (e.g. if link
353 * is available...) */
354 netif->output = etharp_output;
355 netif->linkoutput = low_level_output;
356
357 /* initialize the hardware */
358 low_level_init(netif);
359
360 return ERR_OK;
361 }
362
363 // eof
364