• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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