1 /** @file net.c
2 *
3 * @brief This file provides network porting code
4 *
5 * Copyright 2008-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11 #include "wifi.h"
12 #include <osa.h>
13 #include "netif_decl.h"
14 #include <wm_net.h>
15 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
16 #include <supp_events.h>
17 #endif
18
19 #define net_e(...) wmlog_e("net", ##__VA_ARGS__)
20
21 #if CONFIG_NET_DEBUG
22 #define net_d(...) wmlog("net", ##__VA_ARGS__)
23 #else
24 #define net_d(...)
25 #endif /* ! CONFIG_NET_DEBUG */
26
27 #if CONFIG_IPV6
28 #define IPV6_ADDR_STATE_TENTATIVE "Tentative"
29 #define IPV6_ADDR_STATE_PREFERRED "Preferred"
30 #define IPV6_ADDR_STATE_INVALID "Invalid"
31 #define IPV6_ADDR_STATE_VALID "Valid"
32 #define IPV6_ADDR_STATE_DEPRECATED "Deprecated"
33 #define IPV6_ADDR_TYPE_LINKLOCAL "Link-Local"
34 #define IPV6_ADDR_TYPE_GLOBAL "Global"
35 #define IPV6_ADDR_TYPE_UNIQUELOCAL "Unique-Local"
36 #define IPV6_ADDR_TYPE_SITELOCAL "Site-Local"
37 #define IPV6_ADDR_UNKNOWN "Unknown"
38 #endif
39
40 #if CONFIG_IPV6
41 #define DHCP_TIMEOUT (60 * 1000)
42 #else
43 #define DHCP_TIMEOUT (120 * 1000)
44 #endif
45
46 #ifdef RW610
47 #define TX_DATA_PAYLOAD_SIZE 1500
48 #else
49 // To do for other chips
50 #endif
51
52
53 /*******************************************************************************
54 * Definitions
55 ******************************************************************************/
56
57 enum netif_mac_filter_action
58 {
59 /** Delete a filter entry */
60 NET_IF_DEL_MAC_FILTER = 0,
61 /** Add a filter entry */
62 NET_IF_ADD_MAC_FILTER = 1
63 };
64
65 /*******************************************************************************
66 * Variables
67 ******************************************************************************/
68
69 /*******************************************************************************
70 * Prototypes
71 ******************************************************************************/
72
73 static int igmp_mac_filter(struct netif *netif, const struct in_addr *group, enum netif_mac_filter_action action);
74
75 #if CONFIG_IPV6
76 static int mld_mac_filter(struct netif *netif, const struct in6_addr *group, enum netif_mac_filter_action action);
77 #endif
78
79 static int (*net_internal_rx_callback)(struct net_if *iface, struct net_pkt *pkt);
nxp_wifi_internal_register_rx_cb(int (* rx_cb_fn)(struct net_if * iface,struct net_pkt * pkt))80 void nxp_wifi_internal_register_rx_cb(int (*rx_cb_fn)(struct net_if *iface, struct net_pkt *pkt))
81 {
82 net_internal_rx_callback = rx_cb_fn;
83 }
84
85 uint16_t g_data_nf_last;
86 uint16_t g_data_snr_last;
87
88 static t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
89
90 static struct net_mgmt_event_callback net_event_v4_cb;
91 #define DHCPV4_MASK (NET_EVENT_IPV4_DHCP_BOUND | NET_EVENT_IPV4_DHCP_STOP)
92 #define MCASTV4_MASK (NET_EVENT_IPV4_MADDR_ADD | NET_EVENT_IPV4_MADDR_DEL)
93
94 #if CONFIG_IPV6
95 static struct net_mgmt_event_callback net_event_v6_cb;
96 #define MCASTV6_MASK (NET_EVENT_IPV6_MADDR_ADD | NET_EVENT_IPV6_MADDR_DEL)
97 #define IPV6_MASK (NET_EVENT_IPV6_DAD_SUCCEED | NET_EVENT_IPV6_ADDR_ADD)
98 #endif
99
100 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
101 static struct net_mgmt_event_callback net_event_supp_cb;
102 #define NET_SUPP_MASK (NET_EVENT_SUPPLICANT_READY | NET_EVENT_SUPPLICANT_NOT_READY)
103 static bool g_supp_ready = 0;
104 #endif
105 interface_t g_mlan;
106 #if UAP_SUPPORT
107 interface_t g_uap;
108 #endif
109
110 static int net_wlan_init_done = 0;
111 OSA_TIMER_HANDLE_DEFINE(dhcp_timer);
112 static void dhcp_timer_cb(osa_timer_arg_t arg);
113 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
set_supp_ready_state(bool ready)114 static void set_supp_ready_state(bool ready)
115 {
116 g_supp_ready = ready;
117 }
118
get_supp_ready_state(void)119 bool get_supp_ready_state(void)
120 {
121 return g_supp_ready;
122 }
123 #endif
124
deliver_packet_above(struct net_pkt * p,int recv_interface)125 void deliver_packet_above(struct net_pkt *p, int recv_interface)
126 {
127 int err = 0;
128 /* points to packet payload, which starts with an Ethernet header */
129 struct net_eth_hdr *ethhdr = NET_ETH_HDR(p);
130
131 switch (htons(ethhdr->type))
132 {
133 case NET_ETH_PTYPE_IP:
134 #if CONFIG_IPV6
135 case NET_ETH_PTYPE_IPV6:
136 #endif
137 case NET_ETH_PTYPE_ARP:
138 case NET_ETH_PTYPE_EAPOL:
139 if (recv_interface >= MAX_INTERFACES_SUPPORTED)
140 {
141 while (true)
142 {
143 ;
144 }
145 }
146
147 if (net_internal_rx_callback == NULL)
148 {
149 net_e("Not registering rx callback");
150 (void)net_pkt_unref(p);
151 p = NULL;
152 break;
153 }
154 #if CONFIG_WIFI_SOFTAP_SUPPORT
155 /* full packet send to tcpip_thread to process */
156 if (recv_interface == WLAN_BSS_TYPE_UAP)
157 err = net_internal_rx_callback(g_uap.netif, p);
158 else
159 #endif
160 err = net_internal_rx_callback(g_mlan.netif, p);
161 if (err != 0)
162 {
163 net_e("Net input error");
164 (void)net_pkt_unref(p);
165 p = NULL;
166 }
167 break;
168 default:
169 /* drop the packet */
170 (void)net_pkt_unref(p);
171 p = NULL;
172 break;
173 }
174 }
175
176 #define MAX_RETRY_GEN_PKT 3
gen_pkt_from_data(t_u8 interface,t_u8 * payload,t_u16 datalen)177 static struct net_pkt *gen_pkt_from_data(t_u8 interface, t_u8 *payload, t_u16 datalen)
178 {
179 struct net_pkt *pkt = NULL;
180 t_u8 retry_cnt = MAX_RETRY_GEN_PKT;
181
182 retry:
183 /* We allocate a network buffer */
184 #if CONFIG_WIFI_SOFTAP_SUPPORT
185 if (interface == WLAN_BSS_TYPE_UAP)
186 pkt = net_pkt_rx_alloc_with_buffer(g_uap.netif, datalen, AF_INET, 0, K_NO_WAIT);
187 else
188 #endif
189 pkt = net_pkt_rx_alloc_with_buffer(g_mlan.netif, datalen, AF_INET, 0, K_NO_WAIT);
190
191 if (pkt == NULL)
192 {
193 if (retry_cnt)
194 {
195 retry_cnt--;
196 k_yield();
197 goto retry;
198 }
199 return NULL;
200 }
201
202 if (net_pkt_write(pkt, payload, datalen) < 0)
203 {
204 net_pkt_unref(pkt);
205 pkt = NULL;
206 }
207
208 return pkt;
209 }
210
211 #if CONFIG_WIFI_PKT_FWD
gen_tx_pkt_from_data(uint8_t interface,uint8_t * payload,uint16_t datalen)212 struct net_pkt *gen_tx_pkt_from_data(uint8_t interface, uint8_t *payload, uint16_t datalen)
213 {
214 struct net_pkt *pkt = NULL;
215 uint8_t retry_cnt = MAX_RETRY_GEN_PKT;
216
217 retry:
218 /* We allocate a network buffer */
219 #if CONFIG_WIFI_SOFTAP_SUPPORT
220 if (interface == WLAN_BSS_TYPE_UAP)
221 pkt = net_pkt_alloc_with_buffer(g_uap.netif, datalen, AF_INET, 0, K_NO_WAIT);
222 else
223 #endif
224 pkt = net_pkt_alloc_with_buffer(g_mlan.netif, datalen, AF_INET, 0, K_NO_WAIT);
225
226 if (pkt == NULL)
227 {
228 if (retry_cnt)
229 {
230 retry_cnt--;
231 k_yield();
232 goto retry;
233 }
234 return NULL;
235 }
236
237 if (net_pkt_write(pkt, payload, datalen) < 0)
238 {
239 net_pkt_unref(pkt);
240 pkt = NULL;
241 }
242
243 net_pkt_cursor_init(pkt);
244 return pkt;
245 }
246 #endif
247 #if CONFIG_TX_RX_ZERO_COPY
gen_pkt_from_data_for_zerocopy(t_u8 interface,t_u8 * payload,t_u16 datalen)248 static struct net_pkt *gen_pkt_from_data_for_zerocopy(t_u8 interface, t_u8 *payload, t_u16 datalen)
249 {
250 struct net_pkt *pkt = NULL;
251 t_u8 retry_cnt = MAX_RETRY_GEN_PKT;
252
253 retry:
254 /* We allocate a network buffer */
255 #if CONFIG_WIFI_SOFTAP_SUPPORT
256 if (interface == WLAN_BSS_TYPE_UAP)
257 pkt = net_pkt_rx_alloc_with_buffer(g_uap.netif, datalen, AF_INET, 0, K_NO_WAIT);
258 else
259 #endif
260 pkt = net_pkt_rx_alloc_with_buffer(g_mlan.netif, datalen, AF_INET, 0, K_NO_WAIT);
261
262 if (pkt == NULL)
263 {
264 if (retry_cnt)
265 {
266 retry_cnt--;
267 k_yield();
268 goto retry;
269 }
270 return NULL;
271 }
272
273 /* Reserve space for mlan_buffer */
274 net_pkt_memset(pkt, 0, sizeof(mlan_buffer));
275 net_buf_pull(pkt->frags, sizeof(mlan_buffer));
276 net_pkt_cursor_init(pkt);
277 if (net_pkt_write(pkt, payload, datalen - sizeof(mlan_buffer)) < 0)
278 {
279 net_pkt_unref(pkt);
280 pkt = NULL;
281 }
282
283 return pkt;
284 }
285 #endif
286
287 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
288 /** Check if packet is mgmt and try to consume it.
289 *
290 * Return MLAN_STATUS_RESOURCE if not intrest in it.
291 * Return MLAN_STATUS_SUCCESS if packet is consumed.
292 * Return MLAN_STATUS_FAILURE if error happens and needs to drop it.
293 */
process_mgmt_packet(t_u8 * data)294 static mlan_status process_mgmt_packet(t_u8 *data)
295 {
296 RxPD *rxpd = (RxPD *)(void *)data;
297 struct net_pkt *p = NULL;
298 t_u16 plen;
299
300 if (rxpd->bss_type != MLAN_BSS_TYPE_STA || rxpd->rx_pkt_type != PKT_TYPE_MGMT_FRAME)
301 {
302 return MLAN_STATUS_RESOURCE;
303 }
304
305 if (wlan_bypass_802dot11_mgmt_pkt(data) == MLAN_STATUS_SUCCESS)
306 {
307 return MLAN_STATUS_RESOURCE;
308 }
309
310 #if (CONFIG_TX_RX_ZERO_COPY) || (FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER)
311 plen = rxpd->rx_pkt_offset + rxpd->rx_pkt_length + sizeof(mlan_buffer);
312 p = gen_pkt_from_data_for_zerocopy(MLAN_BSS_TYPE_STA, data, plen);
313 #else
314 plen = rxpd->rx_pkt_offset + rxpd->rx_pkt_length;
315 p = gen_pkt_from_data(MLAN_BSS_TYPE_STA, data, plen);
316 #endif
317 if (!p)
318 {
319 net_d("process_mgmt_packet gen_pkt_from_data fail");
320 return MLAN_STATUS_FAILURE;
321 }
322
323 if (wifi_event_completion(WIFI_EVENT_MGMT_FRAME, WIFI_EVENT_REASON_SUCCESS, p) != WM_SUCCESS)
324 {
325 net_d("process_mgmt_packet send mgmt packet fail");
326 net_stack_buffer_free(p);
327 return MLAN_STATUS_FAILURE;
328 }
329
330 return MLAN_STATUS_SUCCESS;
331 }
332 #endif
333
process_data_packet(const t_u8 * rcvdata,const t_u16 datalen)334 static void process_data_packet(const t_u8 *rcvdata, const t_u16 datalen)
335 {
336 RxPD *rxpd = (RxPD *)(void *)((t_u8 *)rcvdata + INTF_HEADER_LEN);
337 mlan_bss_type recv_interface = (mlan_bss_type)(rxpd->bss_type);
338 t_u16 header_type;
339
340 if (rxpd->rx_pkt_type == PKT_TYPE_AMSDU)
341 {
342 Eth803Hdr_t *eth803hdr = (Eth803Hdr_t *)((t_u8 *)rxpd + rxpd->rx_pkt_offset);
343 /* If the AMSDU packet is unicast and is not for us, drop it */
344 if (memcmp(mlan_adap->priv[recv_interface]->curr_addr, eth803hdr->dest_addr, MLAN_MAC_ADDR_LENGTH) &&
345 ((eth803hdr->dest_addr[0] & 0x01) == 0))
346 {
347 return;
348 }
349 }
350
351 if (recv_interface == MLAN_BSS_TYPE_STA || recv_interface == MLAN_BSS_TYPE_UAP)
352 {
353 g_data_nf_last = rxpd->nf;
354 g_data_snr_last = rxpd->snr;
355 }
356
357 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
358 mlan_status status = process_mgmt_packet((t_u8 *)rcvdata + INTF_HEADER_LEN);
359 if (status != MLAN_STATUS_RESOURCE)
360 {
361 return;
362 }
363 #endif
364
365 t_u8 *payload = (t_u8 *)rxpd + rxpd->rx_pkt_offset;
366 #if CONFIG_TX_RX_ZERO_COPY
367 t_u16 header_len = INTF_HEADER_LEN + rxpd->rx_pkt_offset;
368 struct net_pkt *p = gen_pkt_from_data_for_zerocopy(recv_interface, (t_u8 *)rcvdata,
369 rxpd->rx_pkt_length + header_len + sizeof(mlan_buffer));
370 #else
371 struct net_pkt *p = gen_pkt_from_data(recv_interface, payload, rxpd->rx_pkt_length);
372 #endif
373 /* If there are no more buffers, we do nothing, so the data is
374 lost. We have to go back and read the other ports */
375 if (p == NULL)
376 {
377 return;
378 }
379
380 #if CONFIG_TX_RX_ZERO_COPY
381 /* Directly use rxpd from net_pkt */
382 rxpd = (RxPD *)(void *)(net_pkt_data(p) + INTF_HEADER_LEN);
383 /* Skip interface header and RxPD */
384 net_buf_pull(p->frags, header_len);
385 net_pkt_cursor_init(p);
386 #endif
387
388 /* points to packet payload, which starts with an Ethernet header */
389 struct net_eth_hdr *ethhdr = NET_ETH_HDR(p);
390
391 #if CONFIG_FILTER_LOCALLY_ADMINISTERED_AND_SELF_MAC_ADDR
392 /* TODO: port wifi_netif.c */
393 if ((ISLOCALLY_ADMINISTERED_ADDR(ethhdr->src.addr[0]) &&
394 (!memcmp(ðhdr->src.addr[3], &iw416_data.mac_addr[3], 3))) ||
395 (!memcmp(ðhdr->src.addr, &iw416_data.mac_addr[0], ETHARP_HWADDR_LEN)))
396 {
397 net_pkt_unref(p);
398 p = NULL;
399 return;
400 }
401 #endif
402
403 header_type = htons(ethhdr->type);
404
405 if (!memcmp(payload + SIZEOF_ETH_HDR, rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)))
406 {
407 struct eth_llc_hdr *ethllchdr = (struct eth_llc_hdr *)(void *)(payload + SIZEOF_ETH_HDR);
408
409 if (rxpd->rx_pkt_type == PKT_TYPE_AMSDU)
410 {
411 header_type = htons(ethllchdr->type);
412 }
413 else
414 {
415 /* Remove the LLC header if not the AMSDU packet */
416 ethhdr->type = ethllchdr->type;
417 (void)memmove(payload + SIZEOF_ETH_LLC_HDR, payload, SIZEOF_ETH_HDR);
418 net_buf_pull(p->frags, SIZEOF_ETH_LLC_HDR);
419 net_pkt_cursor_init(p);
420 header_type = htons(ethhdr->type);
421 }
422 }
423
424 switch (header_type)
425 {
426 case NET_ETH_PTYPE_IP:
427 #if CONFIG_IPV6
428 case NET_ETH_PTYPE_IPV6:
429 #endif
430 /* Unicast ARP also need do rx reorder */
431 case NET_ETH_PTYPE_ARP:
432 /* To avoid processing of unwanted udp broadcast packets, adding
433 * filter for dropping packets received on ports other than
434 * pre-defined ports.
435 */
436
437 if (recv_interface == MLAN_BSS_TYPE_STA || recv_interface == MLAN_BSS_TYPE_UAP)
438 {
439 int rv = wrapper_wlan_handle_rx_packet(datalen, rxpd, p, payload);
440 if (rv != WM_SUCCESS)
441 {
442 /* mlan was unsuccessful in delivering the
443 packet */
444
445 (void)net_pkt_unref(p);
446 }
447 }
448 else
449 {
450 deliver_packet_above(p, recv_interface);
451 }
452 p = NULL;
453 break;
454 case NET_ETH_PTYPE_EAPOL:
455 deliver_packet_above(p, recv_interface);
456 break;
457 default:
458 /* fixme: avoid pbuf allocation in this case */
459
460 (void)net_pkt_unref(p);
461 break;
462 }
463 }
464
465 /* Callback function called from the wifi module */
handle_data_packet(const t_u8 interface,const t_u8 * rcvdata,const t_u16 datalen)466 void handle_data_packet(const t_u8 interface, const t_u8 *rcvdata, const t_u16 datalen)
467 {
468 process_data_packet(rcvdata, datalen);
469 }
470
handle_amsdu_data_packet(t_u8 interface,t_u8 * rcvdata,t_u16 datalen)471 void handle_amsdu_data_packet(t_u8 interface, t_u8 *rcvdata, t_u16 datalen)
472 {
473 struct net_pkt *p = gen_pkt_from_data(interface, rcvdata, datalen);
474 if (p == NULL)
475 {
476 w_pkt_e("[amsdu] No pbuf available. Dropping packet");
477 return;
478 }
479
480 deliver_packet_above(p, interface);
481 }
482
handle_deliver_packet_above(t_void * rxpd,t_u8 interface,t_void * pkt)483 void handle_deliver_packet_above(t_void *rxpd, t_u8 interface, t_void *pkt)
484 {
485 struct net_pkt *p = (struct net_pkt *)pkt;
486
487 #if !CONFIG_WIFI_RX_REORDER
488 (void)rxpd;
489 deliver_packet_above(p, interface);
490 #else
491 RxPD *prxpd = (RxPD *)rxpd;
492 deliver_packet_above(prxpd, p, interface);
493 #endif
494 }
495
wrapper_net_is_ip_or_ipv6(const t_u8 * buffer)496 bool wrapper_net_is_ip_or_ipv6(const t_u8 *buffer)
497 {
498 struct net_eth_hdr *hdr = (struct net_eth_hdr *)buffer;
499 uint16_t type = ntohs(hdr->type);
500 if ((type == NET_ETH_PTYPE_IP) || type == NET_ETH_PTYPE_IPV6)
501 {
502 return true;
503 }
504 return false;
505 }
506
507 extern int retry_attempts;
508 #if CONFIG_WIFI_PKT_FWD
509 #define MAX_RETRY_PKT_FWD 3
510 #endif
nxp_wifi_internal_tx(const struct device * dev,struct net_pkt * pkt)511 int nxp_wifi_internal_tx(const struct device *dev, struct net_pkt *pkt)
512 {
513 int ret;
514 interface_t *if_handle = (interface_t *)dev->data;
515 t_u8 interface = if_handle->state.interface;
516 t_u16 net_pkt_len = net_pkt_get_len(pkt);
517 t_u32 pkt_len, outbuf_len;
518 t_u8 *wmm_outbuf = NULL;
519 #if CONFIG_WMM
520 t_u8 *payload = net_pkt_data(pkt);
521 t_u8 tid = 0;
522 int retry = 0;
523 t_u8 ra[MLAN_MAC_ADDR_LENGTH] = {0};
524 bool is_tx_pause = false;
525 t_u32 pkt_prio = WMM_AC_BE;
526 #endif
527
528 t_u16 mtu = net_if_get_mtu(net_pkt_iface(pkt));
529 #ifdef RW610
530 mtu = MIN(TX_DATA_PAYLOAD_SIZE, mtu);
531 #endif
532 if (net_pkt_len - ETH_HDR_LEN > mtu)
533 {
534 return -ENOMEM;
535 }
536
537 #if !UAP_SUPPORT
538 if (interface > WLAN_BSS_ROLE_STA)
539 {
540 return -ENOMEM;
541 }
542 #endif
543
544 #if CONFIG_WMM
545 if (net_pkt_len > ETH_HDR_LEN)
546 {
547 pkt_prio = wifi_wmm_get_pkt_prio(pkt, &tid);
548 if (pkt_prio == -WM_FAIL)
549 {
550 return -ENOMEM;
551 }
552 }
553
554 if (interface > WLAN_BSS_TYPE_UAP)
555 {
556 wifi_wmm_drop_no_media(interface);
557 return -ENOMEM;
558 }
559
560 if (wifi_tx_status == WIFI_DATA_BLOCK)
561 {
562 wifi_tx_block_cnt++;
563 return 0;
564 }
565
566 if (wifi_add_to_bypassq(interface, pkt, net_pkt_len) == WM_SUCCESS)
567 {
568 return 0;
569 }
570
571 wifi_wmm_da_to_ra(payload, ra);
572
573 do
574 {
575 if (retry != 0)
576 {
577 send_wifi_driver_tx_data_event(interface);
578 k_yield();
579 }
580 else
581 {
582 #if CONFIG_WIFI_PKT_FWD
583 if (interface == WLAN_BSS_TYPE_UAP)
584 {
585 retry = MAX_RETRY_PKT_FWD;
586 }
587 else
588 #endif
589 {
590 retry = retry_attempts;
591 }
592 }
593
594 wmm_outbuf = wifi_wmm_get_outbuf_enh(&outbuf_len, (mlan_wmm_ac_e)pkt_prio, interface, ra, &is_tx_pause);
595 ret = (wmm_outbuf == NULL) ? true : false;
596
597 /* uAP case doesn't need to delay to let powersave task run,
598 * as FW won't go into sleep mode when uAP enabled. And this
599 * delay will block uAP packet forward case */
600 #if CONFIG_WIFI_PKT_FWD
601 if (interface != WLAN_BSS_TYPE_UAP)
602 #endif
603 {
604 if (ret == true && is_tx_pause == true)
605 {
606 OSA_TimeDelay(1);
607 }
608 }
609 retry--;
610 } while (ret == true && retry > 0);
611
612 if (ret == true)
613 {
614 wifi_wmm_drop_retried_drop(interface);
615 return -ENOMEM;
616 }
617 #else
618 wmm_outbuf = wifi_get_outbuf((uint32_t *)(&outbuf_len));
619
620 if (wmm_outbuf == NULL)
621 {
622 return -ENOMEM;
623 }
624 #endif
625
626 pkt_len =
627 #if CONFIG_WMM
628 sizeof(mlan_linked_list) +
629 #endif
630 sizeof(TxPD) + INTF_HEADER_LEN;
631
632 #if CONFIG_TX_RX_ZERO_COPY
633 memset(wmm_outbuf, 0x00, pkt_len + ETH_HDR_LEN);
634 /* Save the ethernet header */
635 net_pkt_set_overwrite(pkt, false);
636 net_pkt_read(pkt, ((outbuf_t *)wmm_outbuf)->eth_header, ETH_HDR_LEN);
637 ((outbuf_t *)wmm_outbuf)->buffer = pkt;
638 /* Save the data payload pointer without ethernet header */
639 if (net_pkt_len > ETH_HDR_LEN)
640 {
641 ((outbuf_t *)wmm_outbuf)->payload = pkt->cursor.pos;
642 }
643 else
644 {
645 ((outbuf_t *)wmm_outbuf)->payload = NULL;
646 }
647 /* Driver will free this pbuf */
648 net_pkt_ref(pkt);
649 #else
650 assert(pkt_len + net_pkt_len <= outbuf_len);
651
652 memset(wmm_outbuf, 0x00, pkt_len);
653
654 if (net_pkt_read(pkt, wmm_outbuf + pkt_len, net_pkt_len))
655 return -EIO;
656 #endif
657 pkt_len += net_pkt_len;
658
659 ret = wifi_low_level_output(interface, wmm_outbuf, pkt_len
660 #if CONFIG_WMM
661 ,
662 pkt_prio, tid
663 #endif
664 );
665
666 if (ret == WM_SUCCESS)
667 {
668 ret = 0;
669 }
670 else if (ret == -WM_E_NOMEM)
671 {
672 net_e("Wifi Net NOMEM");
673 ret = -ENOMEM;
674 }
675 else if (ret == -WM_E_BUSY)
676 {
677 net_e("Wifi Net Busy");
678 ret = -ETIMEDOUT;
679 }
680 else
681 { /* Do Nothing */
682 }
683
684 return ret;
685 }
686
687 #if CONFIG_WIFI_PKT_FWD
net_wifi_packet_send(uint8_t interface,void * stack_buffer)688 int net_wifi_packet_send(uint8_t interface, void *stack_buffer)
689 {
690 if (interface == WLAN_BSS_TYPE_UAP)
691 return nxp_wifi_internal_tx(net_if_get_device((void *)g_uap.netif), (struct net_pkt *)stack_buffer);
692 else
693 return nxp_wifi_internal_tx(net_if_get_device((void *)g_mlan.netif), (struct net_pkt *)stack_buffer);
694 }
695 #endif
696
697 /* Below struct is used for creating IGMP IPv4 multicast list */
698 typedef struct group_ip4_addr
699 {
700 struct group_ip4_addr *next;
701 uint32_t group_ip;
702 } group_ip4_addr_t;
703
704 /* Head of list that will contain IPv4 multicast IP's */
705 static group_ip4_addr_t *igmp_ip4_list;
706
707 /* Callback called by net_mgmt to add or delete an entry in the multicast filter table */
igmp_mac_filter(struct netif * netif,const struct in_addr * group,enum netif_mac_filter_action action)708 static int igmp_mac_filter(struct netif *netif, const struct in_addr *group, enum netif_mac_filter_action action)
709 {
710 uint8_t mcast_mac[6];
711 int result;
712 int error;
713
714 /* IPv4 to MAC conversion as per section 6.4 of rfc1112 */
715 wifi_get_ipv4_multicast_mac(ntohl(group->s_addr), mcast_mac);
716 group_ip4_addr_t *curr, *prev;
717
718 switch (action)
719 {
720 case NET_IF_ADD_MAC_FILTER:
721 /* TCP/IP stack takes care of duplicate IP addresses and it always send
722 * unique IP address. Simply add IP to top of list*/
723 #if !CONFIG_MEM_POOLS
724 curr = (group_ip4_addr_t *)OSA_MemoryAllocate(sizeof(group_ip4_addr_t));
725 #else
726 curr = (group_ip4_addr_t *)OSA_MemoryPoolAllocate(buf_32_MemoryPool);
727 #endif
728 if (curr == NULL)
729 {
730 result = -WM_FAIL;
731 goto done;
732 }
733 curr->group_ip = group->s_addr;
734 curr->next = igmp_ip4_list;
735 igmp_ip4_list = curr;
736 /* Add multicast MAC filter */
737 error = wifi_add_mcast_filter(mcast_mac);
738 if (error == 0)
739 {
740 result = WM_SUCCESS;
741 }
742 else if (error == -WM_E_EXIST)
743 {
744 result = WM_SUCCESS;
745 }
746 else
747 {
748 /* In case of failure remove IP from list */
749 curr = igmp_ip4_list;
750 igmp_ip4_list = curr->next;
751 #if !CONFIG_MEM_POOLS
752 OSA_MemoryFree(curr);
753 #else
754 OSA_MemoryPoolFree(buf_32_MemoryPool, curr);
755 #endif
756 curr = NULL;
757 result = -WM_FAIL;
758 }
759 break;
760 case NET_IF_DEL_MAC_FILTER:
761 /* Remove multicast IP address from list */
762 curr = igmp_ip4_list;
763 prev = curr;
764 while (curr != NULL)
765 {
766 if (curr->group_ip == group->s_addr)
767 {
768 if (prev == curr)
769 {
770 igmp_ip4_list = curr->next;
771 #if !CONFIG_MEM_POOLS
772 OSA_MemoryFree(curr);
773 #else
774 OSA_MemoryPoolFree(buf_32_MemoryPool, curr);
775 #endif
776 }
777 else
778 {
779 prev->next = curr->next;
780 #if !CONFIG_MEM_POOLS
781 OSA_MemoryFree(curr);
782 #else
783 OSA_MemoryPoolFree(buf_32_MemoryPool, curr);
784 #endif
785 }
786 curr = NULL;
787 break;
788 }
789 prev = curr;
790 curr = curr->next;
791 }
792 /* Check if other IP is mapped to same MAC */
793 curr = igmp_ip4_list;
794 while (curr != NULL)
795 {
796 /* If other IP is mapped to same MAC than skip Multicast MAC removal */
797 if ((ntohl(curr->group_ip) & 0x7FFFFFU) == (ntohl(group->s_addr) & 0x7FFFFFU))
798 {
799 result = WM_SUCCESS;
800 goto done;
801 }
802 curr = curr->next;
803 }
804 /* Remove Multicast MAC filter */
805 error = wifi_remove_mcast_filter(mcast_mac);
806 if (error == 0)
807 {
808 result = WM_SUCCESS;
809 }
810 else
811 {
812 result = -WM_FAIL;
813 }
814 break;
815 default:
816 result = -WM_FAIL;
817 break;
818 }
819 done:
820 return result;
821 }
822
823 #if CONFIG_IPV6
824 /* Below struct is used for creating IGMP IPv6 multicast list */
825 typedef struct group_ip6_addr
826 {
827 struct group_ip6_addr *next;
828 uint32_t group_ip;
829 } group_ip6_addr_t;
830
831 /* Head of list that will contain IPv6 multicast IP's */
832 static group_ip6_addr_t *mld_ip6_list;
833
834 /* Callback called by net_mgmt to add or delete an entry in the IPv6 multicast filter table */
mld_mac_filter(struct netif * netif,const struct in6_addr * group,enum netif_mac_filter_action action)835 static int mld_mac_filter(struct netif *netif, const struct in6_addr *group, enum netif_mac_filter_action action)
836 {
837 uint8_t mcast_mac[6];
838 int result;
839 int error;
840
841 /* IPv6 to MAC conversion as per section 7 of rfc2464 */
842 wifi_get_ipv6_multicast_mac(ntohl(group->s6_addr32[3]), mcast_mac);
843 group_ip6_addr_t *curr, *prev;
844
845 switch (action)
846 {
847 case NET_IF_ADD_MAC_FILTER:
848 /* TCP/IP stack takes care of duplicate IP addresses and it always send
849 * unique IP address. Simply add IP to top of list*/
850 #if !CONFIG_MEM_POOLS
851 curr = (group_ip6_addr_t *)OSA_MemoryAllocate(sizeof(group_ip6_addr_t));
852 #else
853 curr = (group_ip6_addr_t *)OSA_MemoryPoolAllocate(buf_32_MemoryPool);
854 #endif
855 if (curr == NULL)
856 {
857 result = -WM_FAIL;
858 goto done;
859 }
860 curr->group_ip = group->s6_addr32[3];
861 curr->next = mld_ip6_list;
862 mld_ip6_list = curr;
863 /* Add multicast MAC filter */
864 error = wifi_add_mcast_filter(mcast_mac);
865 if (error == 0)
866 {
867 result = WM_SUCCESS;
868 }
869 else if (error == -WM_E_EXIST)
870 {
871 result = WM_SUCCESS;
872 }
873 else
874 {
875 /* In case of failure remove IP from list */
876 curr = mld_ip6_list;
877 mld_ip6_list = mld_ip6_list->next;
878 #if !CONFIG_MEM_POOLS
879 OSA_MemoryFree(curr);
880 #else
881 OSA_MemoryPoolFree(buf_32_MemoryPool, curr);
882 #endif
883 curr = NULL;
884 result = -WM_FAIL;
885 }
886 break;
887 case NET_IF_DEL_MAC_FILTER:
888 /* Remove multicast IP address from list */
889 curr = mld_ip6_list;
890 prev = curr;
891 while (curr != NULL)
892 {
893 if (curr->group_ip == group->s6_addr32[3])
894 {
895 if (prev == curr)
896 {
897 mld_ip6_list = curr->next;
898 #if !CONFIG_MEM_POOLS
899 OSA_MemoryFree(curr);
900 #else
901 OSA_MemoryPoolFree(buf_32_MemoryPool, curr);
902 #endif
903 }
904 else
905 {
906 prev->next = curr->next;
907 #if !CONFIG_MEM_POOLS
908 OSA_MemoryFree(curr);
909 #else
910 OSA_MemoryPoolFree(buf_32_MemoryPool, curr);
911 #endif
912 }
913 curr = NULL;
914 break;
915 }
916 prev = curr;
917 curr = curr->next;
918 }
919 /* Check if other IP is mapped to same MAC */
920 curr = mld_ip6_list;
921 while (curr != NULL)
922 {
923 /* If other IP is mapped to same MAC than skip Multicast MAC removal */
924 if ((ntohl(curr->group_ip) & 0xFFFFFF) == (ntohl(group->s6_addr32[3]) & 0xFFFFFF))
925 {
926 result = WM_SUCCESS;
927 goto done;
928 }
929 curr = curr->next;
930 }
931 /* Remove Multicast MAC filter */
932 error = wifi_remove_mcast_filter(mcast_mac);
933 if (error == 0)
934 {
935 result = WM_SUCCESS;
936 }
937 else
938 {
939 result = -WM_FAIL;
940 }
941 break;
942 default:
943 result = -WM_FAIL;
944 break;
945 }
946 done:
947 return result;
948 }
949 #endif /* #if CONFIG_IPV6 */
950
net_get_sta_handle(void)951 void *net_get_sta_handle(void)
952 {
953 return &g_mlan;
954 }
955
956 #if UAP_SUPPORT
net_get_uap_handle(void)957 void *net_get_uap_handle(void)
958 {
959 return &g_uap;
960 }
961 #endif
962
net_get_sta_interface(void)963 struct netif *net_get_sta_interface(void)
964 {
965 return (struct netif *)g_mlan.netif;
966 }
967
968 #if UAP_SUPPORT
net_get_uap_interface(void)969 struct netif *net_get_uap_interface(void)
970 {
971 return (struct netif *)g_uap.netif;
972 }
973 #endif
974
net_get_if_name_netif(char * pif_name,struct netif * iface)975 int net_get_if_name_netif(char *pif_name, struct netif *iface)
976 {
977 strncpy(pif_name, iface->if_dev->dev->name, NETIF_NAMESIZE);
978 return WM_SUCCESS;
979 }
980
net_stop_dhcp_timer(void)981 void net_stop_dhcp_timer(void)
982 {
983 (void)OSA_TimerDeactivate((osa_timer_handle_t)dhcp_timer);
984 }
985
stop_cb(void * ctx)986 static void stop_cb(void *ctx)
987 {
988 interface_t *if_handle = (interface_t *)net_get_mlan_handle();
989
990 net_dhcpv4_stop(if_handle->netif);
991 #if CONFIG_IPV6
992 if (!is_sta_ipv6_connected())
993 #endif
994 (void)net_if_dormant_on(if_handle->netif);
995 }
996
dhcp_timer_cb(osa_timer_arg_t arg)997 static void dhcp_timer_cb(osa_timer_arg_t arg)
998 {
999 stop_cb(NULL);
1000
1001 (void)wlan_wlcmgr_send_msg(WIFI_EVENT_NET_DHCP_CONFIG, WIFI_EVENT_REASON_FAILURE, NULL);
1002 }
1003
net_interface_up(void * intrfc_handle)1004 void net_interface_up(void *intrfc_handle)
1005 {
1006 /* case 1: start uap/ connect to uap firstly.
1007 When init sta/uap interface, the flag of iface->if_dev->flags is initialized to NET_IF_LOWER_UP.
1008 Function update_operational_state()(zephyr function) will be called by net_if_up(). Only iface->if_dev->flags
1009 is NET_IF_LOWER_UP, can call notify_iface_up() to start interface.
1010 iface->if_dev->oper_state will be set to NET_IF_OPER_UP.
1011 Function net_eth_carrier_on() will submit carrier_work to work queue, then net_if_carrier_on() is called.
1012 net_if_carrier_on() also call update_operational_state(), but don't start interface repeatedly because
1013 iface->if_dev->oper_state has been NET_IF_OPER_UP.
1014
1015 case 2: stop uap then start uap again / disconnect to uap then connect to uap.
1016 When stop uap or disconnect to uap, net_eth_carrier_off() will be called in zephyr wifi drvier glue
1017 file(nxp_wifi_drv.c). The flag of iface->if_dev->flags will be cleared. If only call net_if_up(),
1018 update_operational_state() will return early. So can't start interface.
1019 We can set iface->if_dev->flags to NET_IF_LOWER_UP by calling net_eth_carrier_on() to start interface.
1020
1021 Can't delete net_if_up() here, beacuse in addtion to start interface, net_if_up() will also perform other
1022 initilization work.*/
1023
1024 net_if_dormant_off(((interface_t *)intrfc_handle)->netif);
1025 }
1026
net_interface_down(void * intrfc_handle)1027 void net_interface_down(void *intrfc_handle)
1028 {
1029 /** includes dhcpv4 stop and ipv6 clear,
1030 * for static IP case, we do not clear IP addr
1031 */
1032 net_if_dormant_on(((interface_t *)intrfc_handle)->netif);
1033 }
1034
net_interface_dhcp_stop(void * intrfc_handle)1035 void net_interface_dhcp_stop(void *intrfc_handle)
1036 {
1037 net_dhcpv4_stop(((interface_t *)intrfc_handle)->netif);
1038 }
1039
ipv4_mcast_add(struct net_mgmt_event_callback * cb,struct net_if * iface)1040 static void ipv4_mcast_add(struct net_mgmt_event_callback *cb, struct net_if *iface)
1041 {
1042 igmp_mac_filter((struct netif *)iface, cb->info, NET_IF_ADD_MAC_FILTER);
1043 }
1044
ipv4_mcast_delete(struct net_mgmt_event_callback * cb,struct net_if * iface)1045 static void ipv4_mcast_delete(struct net_mgmt_event_callback *cb, struct net_if *iface)
1046 {
1047 igmp_mac_filter((struct netif *)iface, cb->info, NET_IF_DEL_MAC_FILTER);
1048 }
1049
1050 #if CONFIG_IPV6
ipv6_mcast_add(struct net_mgmt_event_callback * cb,struct net_if * iface)1051 static void ipv6_mcast_add(struct net_mgmt_event_callback *cb, struct net_if *iface)
1052 {
1053 mld_mac_filter((struct netif *)iface, cb->info, NET_IF_ADD_MAC_FILTER);
1054 }
1055
ipv6_mcast_delete(struct net_mgmt_event_callback * cb,struct net_if * iface)1056 static void ipv6_mcast_delete(struct net_mgmt_event_callback *cb, struct net_if *iface)
1057 {
1058 mld_mac_filter((struct netif *)iface, cb->info, NET_IF_DEL_MAC_FILTER);
1059 }
1060 #endif
1061
wifi_net_event_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)1062 static void wifi_net_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface)
1063 {
1064 // const struct wifi_status *status = (const struct wifi_status *)cb->info;
1065 enum wifi_event_reason wifi_event_reason;
1066
1067 switch (mgmt_event)
1068 {
1069 case NET_EVENT_IPV4_DHCP_BOUND:
1070 wifi_event_reason = WIFI_EVENT_REASON_SUCCESS;
1071 wlan_wlcmgr_send_msg(WIFI_EVENT_NET_DHCP_CONFIG, wifi_event_reason, NULL);
1072 break;
1073 case NET_EVENT_IPV4_MADDR_ADD:
1074 ipv4_mcast_add(cb, iface);
1075 break;
1076 case NET_EVENT_IPV4_MADDR_DEL:
1077 ipv4_mcast_delete(cb, iface);
1078 break;
1079 #if CONFIG_IPV6
1080 case NET_EVENT_IPV6_MADDR_ADD:
1081 ipv6_mcast_add(cb, iface);
1082 break;
1083 case NET_EVENT_IPV6_MADDR_DEL:
1084 ipv6_mcast_delete(cb, iface);
1085 break;
1086 case NET_EVENT_IPV6_DAD_SUCCEED:
1087 net_d("Receive zephyr ipv6 dad finished event.");
1088 #if UAP_SUPPORT && !CONFIG_WIFI_NM_HOSTAPD_AP
1089 /*Wi-Fi driver will recevie NET_EVENT_IPV6_DAD_SUCCEED from zephyr kernel after IPV6 DAD finished.
1090 Can notify wlcmgr_task task to get address.*/
1091 (void)wlan_wlcmgr_send_msg(WIFI_EVENT_UAP_NET_ADDR_CONFIG, WIFI_EVENT_REASON_SUCCESS, NULL);
1092 #endif
1093 break;
1094 case NET_EVENT_IPV6_ADDR_ADD:
1095 net_d("Receive zephyr ipv6 address added event.");
1096 break;
1097 #endif
1098 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
1099 case NET_EVENT_SUPPLICANT_READY:
1100 set_supp_ready_state(1);
1101 break;
1102 case NET_EVENT_SUPPLICANT_NOT_READY:
1103 set_supp_ready_state(0);
1104 break;
1105 #endif
1106 default:
1107 net_d("Unhandled net event: %x", mgmt_event);
1108 break;
1109 }
1110 }
1111
net_configure_address(struct net_ip_config * addr,void * intrfc_handle)1112 int net_configure_address(struct net_ip_config *addr, void *intrfc_handle)
1113 {
1114 if (addr == NULL)
1115 {
1116 return -WM_E_INVAL;
1117 }
1118 if (intrfc_handle == NULL)
1119 {
1120 return -WM_E_INVAL;
1121 }
1122
1123 interface_t *if_handle = (interface_t *)intrfc_handle;
1124
1125 #if CONFIG_P2P
1126 net_d("configuring interface %s (with %s)", (if_handle == &g_mlan) ? "mlan" : (if_handle == &g_uap) ? "uap" : "wfd",
1127 (addr->ipv4.addr_type == NET_ADDR_TYPE_DHCP) ? "DHCP client" : "Static IP");
1128 #else
1129 net_d("configuring interface %s (with %s)", (if_handle == &g_mlan) ? "mlan" : "uap",
1130 (addr->ipv4.addr_type == NET_ADDR_TYPE_DHCP) ? "DHCP client" : "Static IP");
1131 #endif
1132
1133 if (if_handle == &g_mlan)
1134 {
1135 net_if_set_default(if_handle->netif);
1136 }
1137
1138 switch (addr->ipv4.addr_type)
1139 {
1140 case NET_ADDR_TYPE_STATIC:
1141 NET_IPV4_ADDR_U32(if_handle->ipaddr) = addr->ipv4.address;
1142 NET_IPV4_ADDR_U32(if_handle->nmask) = addr->ipv4.netmask;
1143 NET_IPV4_ADDR_U32(if_handle->gw) = addr->ipv4.gw;
1144 net_if_ipv4_addr_add(if_handle->netif, &if_handle->ipaddr.in_addr, NET_ADDR_MANUAL, 0);
1145 net_if_ipv4_set_gw(if_handle->netif, &if_handle->gw.in_addr);
1146 net_if_ipv4_set_netmask_by_addr(if_handle->netif, &if_handle->ipaddr.in_addr, &if_handle->nmask.in_addr);
1147 break;
1148 case NET_ADDR_TYPE_DHCP:
1149 (void)OSA_TimerActivate((osa_timer_handle_t)dhcp_timer);
1150 net_dhcpv4_restart(if_handle->netif);
1151 break;
1152 case NET_ADDR_TYPE_LLA:
1153 /* For dhcp, instead of netifapi_netif_set_up, a
1154 netifapi_dhcp_start() call will be used */
1155 net_e("Not supported as of now...");
1156 break;
1157 default:
1158 net_d("Unexpected addr type");
1159 break;
1160 }
1161 /* Finally this should send the following event. */
1162 if ((if_handle == &g_mlan)
1163 #if CONFIG_P2P
1164 || ((if_handle == &g_wfd) && (netif_get_bss_type() == BSS_TYPE_STA))
1165 #endif
1166 )
1167 {
1168 #if CONFIG_IPV6
1169 (void)wlan_wlcmgr_send_msg(WIFI_EVENT_NET_IPV6_CONFIG, WIFI_EVENT_REASON_SUCCESS, NULL);
1170 #endif
1171 (void)wlan_wlcmgr_send_msg(WIFI_EVENT_NET_STA_ADDR_CONFIG, WIFI_EVENT_REASON_SUCCESS, NULL);
1172
1173 /* XXX For DHCP, the above event will only indicate that the
1174 * DHCP address obtaining process has started. Once the DHCP
1175 * address has been obtained, another event,
1176 * WD_EVENT_NET_DHCP_CONFIG, should be sent to the wlcmgr.
1177 */
1178 }
1179 #if UAP_SUPPORT
1180 else if (if_handle == &g_uap
1181 #if CONFIG_P2P
1182 || ((if_handle == &g_wfd) && (netif_get_bss_type() == BSS_TYPE_UAP))
1183 #endif
1184 )
1185 {
1186 /*For g_uap interface, notify wlcmgr_task task to get address only after receiving DAD finished event from
1187 * zephyr.*/
1188 net_if_dormant_off(if_handle->netif);
1189 }
1190 #endif
1191 else
1192 { /* Do Nothing */
1193 }
1194
1195 return WM_SUCCESS;
1196 }
1197
net_get_if_addr(struct net_ip_config * addr,void * intrfc_handle)1198 int net_get_if_addr(struct net_ip_config *addr, void *intrfc_handle)
1199 {
1200 interface_t *if_handle = (interface_t *)intrfc_handle;
1201 struct net_if_ipv4 *ipv4 = if_handle->netif->config.ip.ipv4;
1202
1203 addr->ipv4.address = NET_IPV4_ADDR_U32(ipv4->unicast[0].ipv4.address);
1204 addr->ipv4.netmask = ipv4->unicast[0].netmask.s_addr;
1205 addr->ipv4.gw = ipv4->gw.s_addr;
1206
1207 #if (CONFIG_DNS_RESOLVER)
1208 struct dns_resolve_context *ctx;
1209
1210 /* DNS status */
1211 ctx = dns_resolve_get_default();
1212 if (ctx)
1213 {
1214 int i;
1215
1216 for (i = 0; i < CONFIG_DNS_RESOLVER_MAX_SERVERS; i++)
1217 {
1218 if (ctx->servers[i].dns_server.sa_family == AF_INET)
1219 {
1220 if (i == 0)
1221 {
1222 addr->ipv4.dns1 = net_sin(&ctx->servers[i].dns_server)->sin_addr.s_addr;
1223 }
1224 if (i == 1)
1225 {
1226 addr->ipv4.dns2 = net_sin(&ctx->servers[i].dns_server)->sin_addr.s_addr;
1227 }
1228 }
1229 }
1230 }
1231 #endif
1232
1233 return WM_SUCCESS;
1234 }
1235
1236 #if CONFIG_IPV6
ipv6_addr_state_to_desc(unsigned char addr_state)1237 char *ipv6_addr_state_to_desc(unsigned char addr_state)
1238 {
1239 if (addr_state == NET_ADDR_TENTATIVE)
1240 {
1241 return IPV6_ADDR_STATE_TENTATIVE;
1242 }
1243 else if (addr_state == NET_ADDR_PREFERRED)
1244 {
1245 return IPV6_ADDR_STATE_PREFERRED;
1246 }
1247 else if (addr_state == NET_ADDR_DEPRECATED)
1248 {
1249 return IPV6_ADDR_STATE_DEPRECATED;
1250 }
1251 else
1252 {
1253 return IPV6_ADDR_UNKNOWN;
1254 }
1255 }
1256
1257 char *info = NULL;
1258 char extra_info[NET_IPV6_ADDR_LEN];
1259
ipv6_addr_addr_to_desc(struct net_ipv6_config * ipv6_conf)1260 char *ipv6_addr_addr_to_desc(struct net_ipv6_config *ipv6_conf)
1261 {
1262 struct in6_addr ip6_addr;
1263
1264 (void)memcpy((void *)&ip6_addr, (const void *)ipv6_conf->address, sizeof(ip6_addr));
1265
1266 info = net_addr_ntop(AF_INET6, &ip6_addr, extra_info, NET_IPV6_ADDR_LEN);
1267
1268 return info;
1269 }
1270
ipv6_addr_type_to_desc(struct net_ipv6_config * ipv6_conf)1271 char *ipv6_addr_type_to_desc(struct net_ipv6_config *ipv6_conf)
1272 {
1273 struct in6_addr ip6_addr;
1274
1275 (void)memcpy((void *)&ip6_addr, (const void *)ipv6_conf->address, sizeof(ip6_addr));
1276
1277 if (net_ipv6_is_ll_addr(&ip6_addr))
1278 {
1279 return IPV6_ADDR_TYPE_LINKLOCAL;
1280 }
1281 else if (net_ipv6_is_global_addr(&ip6_addr))
1282 {
1283 return IPV6_ADDR_TYPE_GLOBAL;
1284 }
1285 else if (net_ipv6_is_ula_addr(&ip6_addr))
1286 {
1287 return IPV6_ADDR_TYPE_UNIQUELOCAL;
1288 }
1289 else if (net_ipv6_is_ll_addr(&ip6_addr))
1290 {
1291 return IPV6_ADDR_TYPE_SITELOCAL;
1292 }
1293 else
1294 {
1295 return IPV6_ADDR_UNKNOWN;
1296 }
1297 }
1298
net_get_if_ipv6_addr(struct net_ip_config * addr,void * intrfc_handle)1299 int net_get_if_ipv6_addr(struct net_ip_config *addr, void *intrfc_handle)
1300 {
1301 interface_t *if_handle = (interface_t *)intrfc_handle;
1302 int i;
1303 struct net_if_ipv6 *ipv6;
1304 struct net_if_addr *unicast;
1305
1306 ipv6 = if_handle->netif->config.ip.ipv6;
1307
1308 addr->ipv6_count = 0;
1309
1310 for (i = 0; ipv6 && i < CONFIG_MAX_IPV6_ADDRESSES; i++)
1311 {
1312 unicast = &ipv6->unicast[i];
1313
1314 if (!unicast->is_used)
1315 {
1316 continue;
1317 }
1318
1319 (void)memcpy(addr->ipv6[i].address, &unicast->address.in6_addr, 16);
1320 addr->ipv6[i].addr_type = unicast->addr_type;
1321 addr->ipv6[i].addr_state = unicast->addr_state;
1322 addr->ipv6_count++;
1323 }
1324 /* TODO carry out more processing based on IPv6 fields in netif */
1325 return WM_SUCCESS;
1326 }
1327
net_get_if_ipv6_pref_addr(struct net_ip_config * addr,void * intrfc_handle)1328 int net_get_if_ipv6_pref_addr(struct net_ip_config *addr, void *intrfc_handle)
1329 {
1330 int i, ret = 0;
1331 interface_t *if_handle = (interface_t *)intrfc_handle;
1332 struct net_if_ipv6 *ipv6;
1333 struct net_if_addr *unicast;
1334 // struct net_if_mcast_addr *mcast;
1335
1336 ipv6 = if_handle->netif->config.ip.ipv6;
1337
1338 addr->ipv6_count = 0;
1339
1340 for (i = 0; ipv6 && i < CONFIG_MAX_IPV6_ADDRESSES; i++)
1341 {
1342 unicast = &ipv6->unicast[i];
1343
1344 if (!unicast->is_used)
1345 {
1346 continue;
1347 }
1348
1349 if (unicast->addr_state == NET_ADDR_PREFERRED)
1350 {
1351 (void)memcpy(addr->ipv6[ret++].address, &unicast->address.in6_addr, 16);
1352 addr->ipv6_count++;
1353 }
1354 }
1355 return ret;
1356 }
1357
net_clear_ipv6_ll_address(void * intrfc_handle)1358 static void net_clear_ipv6_ll_address(void *intrfc_handle)
1359 {
1360 struct net_if *iface = ((interface_t *)intrfc_handle)->netif;
1361
1362 if (iface == NULL)
1363 {
1364 return;
1365 }
1366
1367 /* We need to remove the old IPv6 link layer address, that is
1368 * generated from old MAC address, from network interface if
1369 * needed.
1370 */
1371 if (IS_ENABLED(CONFIG_NET_NATIVE_IPV6))
1372 {
1373 struct in6_addr iid;
1374
1375 net_ipv6_addr_create_iid(&iid, net_if_get_link_addr(iface));
1376
1377 /* No need to check the return value in this case. It
1378 * is not an error if the address is not found atm.
1379 */
1380 (void)net_if_ipv6_addr_rm(iface, &iid);
1381 }
1382 }
1383 #endif /* CONFIG_IPV6 */
1384
net_get_if_name(char * pif_name,void * intrfc_handle)1385 int net_get_if_name(char *pif_name, void *intrfc_handle)
1386 {
1387 interface_t *if_handle = (interface_t *)intrfc_handle;
1388 const struct device *dev = NULL;
1389 dev = net_if_get_device((struct net_if *)if_handle->netif);
1390 strncpy(pif_name, dev->name, NETIF_NAMESIZE - 1);
1391 pif_name[NETIF_NAMESIZE - 1] = '\0';
1392
1393 return WM_SUCCESS;
1394 }
1395
net_get_if_ip_addr(uint32_t * ip,void * intrfc_handle)1396 int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle)
1397 {
1398 interface_t *if_handle = (interface_t *)intrfc_handle;
1399 struct net_if_ipv4 *ipv4 = if_handle->netif->config.ip.ipv4;
1400
1401 *ip = NET_IPV4_ADDR_U32(ipv4->unicast[0].ipv4.address);
1402 return WM_SUCCESS;
1403 }
1404
net_get_if_ip_mask(uint32_t * nm,void * intrfc_handle)1405 int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle)
1406 {
1407 interface_t *if_handle = (interface_t *)intrfc_handle;
1408 struct net_if_ipv4 *ipv4 = if_handle->netif->config.ip.ipv4;
1409
1410 *nm = ipv4->unicast[0].netmask.s_addr;
1411 return WM_SUCCESS;
1412 }
1413
net_configure_dns(struct net_ip_config * ip,unsigned int role)1414 void net_configure_dns(struct net_ip_config *ip, unsigned int role)
1415 {
1416 if (ip->ipv4.addr_type == NET_ADDR_TYPE_STATIC)
1417 {
1418 if (role != WLAN_BSS_ROLE_UAP)
1419 {
1420 if (ip->ipv4.dns1 == 0U)
1421 {
1422 ip->ipv4.dns1 = ip->ipv4.gw;
1423 }
1424 if (ip->ipv4.dns2 == 0U)
1425 {
1426 ip->ipv4.dns2 = ip->ipv4.dns1;
1427 }
1428 }
1429 /* TODO: DNS server */
1430 #if 0
1431 ip4_addr_t tmp;
1432
1433 tmp.addr = ip->ipv4.dns1;
1434 dns_setserver(0, (ip_addr_t *)(void *)&tmp);
1435 tmp.addr = ip->ipv4.dns2;
1436 dns_setserver(1, (ip_addr_t *)(void *)&tmp);
1437 #endif
1438 }
1439 }
1440
net_stat(void)1441 void net_stat(void)
1442 {
1443 // net_print_statistics();
1444 }
1445
setup_mgmt_events(void)1446 static void setup_mgmt_events(void)
1447 {
1448 net_mgmt_init_event_callback(&net_event_v4_cb, wifi_net_event_handler, MCASTV4_MASK | DHCPV4_MASK);
1449
1450 net_mgmt_add_event_callback(&net_event_v4_cb);
1451
1452 #if CONFIG_IPV6
1453 net_mgmt_init_event_callback(&net_event_v6_cb, wifi_net_event_handler, MCASTV6_MASK | IPV6_MASK);
1454
1455 net_mgmt_add_event_callback(&net_event_v6_cb);
1456 #endif
1457
1458 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
1459 net_mgmt_init_event_callback(&net_event_supp_cb, wifi_net_event_handler, NET_SUPP_MASK);
1460
1461 net_mgmt_add_event_callback(&net_event_supp_cb);
1462 #endif
1463 }
1464
cleanup_mgmt_events(void)1465 static void cleanup_mgmt_events(void)
1466 {
1467 net_mgmt_del_event_callback(&net_event_v4_cb);
1468
1469 #if CONFIG_IPV6
1470 net_mgmt_del_event_callback(&net_event_v6_cb);
1471 #endif
1472
1473 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
1474 net_mgmt_del_event_callback(&net_event_supp_cb);
1475 #endif
1476
1477 }
1478
net_wlan_init(void)1479 int net_wlan_init(void)
1480 {
1481 int ret;
1482 osa_status_t status;
1483
1484 wifi_register_data_input_callback(&handle_data_packet);
1485 wifi_register_amsdu_data_input_callback(&handle_amsdu_data_packet);
1486 wifi_register_deliver_packet_above_callback(&handle_deliver_packet_above);
1487 wifi_register_wrapper_net_is_ip_or_ipv6_callback(&wrapper_net_is_ip_or_ipv6);
1488
1489 if (!net_wlan_init_done)
1490 {
1491 wifi_mac_addr_t mac_addr = {0};
1492
1493 wifi_get_device_mac_addr(&mac_addr);
1494 wlan_set_mac_addr(&mac_addr.mac[0]);
1495
1496 /* init STA netif */
1497 ret = wlan_get_mac_address(g_mlan.state.ethaddr.addr);
1498 if (ret != 0)
1499 {
1500 net_e("could not get STA wifi mac addr");
1501 return ret;
1502 }
1503
1504 net_if_set_link_addr(g_mlan.netif, g_mlan.state.ethaddr.addr, NET_MAC_ADDR_LEN, NET_LINK_ETHERNET);
1505 ethernet_init(g_mlan.netif);
1506
1507 #if CONFIG_WIFI_SOFTAP_SUPPORT
1508 /* init uAP netif */
1509 ret = wlan_get_mac_address_uap(g_uap.state.ethaddr.addr);
1510 if (ret != 0)
1511 {
1512 net_e("could not get uAP wifi mac addr");
1513 return ret;
1514 }
1515
1516 net_if_set_link_addr(g_uap.netif, g_uap.state.ethaddr.addr, NET_MAC_ADDR_LEN, NET_LINK_ETHERNET);
1517 ethernet_init(g_uap.netif);
1518 #endif
1519 net_wlan_init_done = 1;
1520
1521 status = OSA_TimerCreate((osa_timer_handle_t)dhcp_timer, MSEC_TO_TICK(DHCP_TIMEOUT), &dhcp_timer_cb, NULL, KOSA_TimerOnce,
1522 OSA_TIMER_NO_ACTIVATE);
1523 if (status != KOSA_StatusSuccess)
1524 {
1525 net_e("Unable to start dhcp timer");
1526 return -WM_FAIL;
1527 }
1528 }
1529
1530 setup_mgmt_events();
1531
1532 net_d("Initialized TCP/IP networking stack");
1533 wlan_wlcmgr_send_msg(WIFI_EVENT_NET_INTERFACE_CONFIG, WIFI_EVENT_REASON_SUCCESS, NULL);
1534 return WM_SUCCESS;
1535 }
1536
net_wlan_set_mac_address(unsigned char * sta_mac,unsigned char * uap_mac)1537 void net_wlan_set_mac_address(unsigned char *sta_mac, unsigned char *uap_mac)
1538 {
1539 if (sta_mac != NULL)
1540 {
1541 #if CONFIG_IPV6
1542 net_clear_ipv6_ll_address(&g_mlan);
1543 #endif
1544 (void)memcpy(g_mlan.state.ethaddr.addr, &sta_mac[0], MLAN_MAC_ADDR_LENGTH);
1545 net_if_set_link_addr(g_mlan.netif, g_mlan.state.ethaddr.addr, NET_MAC_ADDR_LEN, NET_LINK_ETHERNET);
1546 }
1547
1548 #if CONFIG_WIFI_SOFTAP_SUPPORT
1549 if (uap_mac != NULL)
1550 {
1551 #if CONFIG_IPV6
1552 net_clear_ipv6_ll_address(&g_uap);
1553 #endif
1554 (void)memcpy(g_uap.state.ethaddr.addr, &uap_mac[0], MLAN_MAC_ADDR_LENGTH);
1555 net_if_set_link_addr(g_uap.netif, g_uap.state.ethaddr.addr, NET_MAC_ADDR_LEN, NET_LINK_ETHERNET);
1556 }
1557 #endif
1558 }
1559
net_netif_deinit(struct net_if * netif)1560 static int net_netif_deinit(struct net_if *netif)
1561 {
1562 #if 0
1563 int ret;
1564 #if CONFIG_IPV6
1565 if (netif->mld_mac_filter != NULL)
1566 {
1567 ip6_addr_t ip6_allnodes_ll;
1568 ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
1569 (void)netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_DEL_MAC_FILTER);
1570 }
1571 #endif
1572 ret = netifapi_netif_remove(netif);
1573
1574 if (ret != WM_SUCCESS)
1575 {
1576 net_e("Interface remove failed");
1577 return -WM_FAIL;
1578 }
1579
1580 if (netif->state != NULL)
1581 {
1582 #if !CONFIG_WPA_SUPP
1583 mem_free(netif->state);
1584 #endif
1585 netif->state = NULL;
1586 }
1587 #endif
1588 #if CONFIG_NET_STATISTICS_WIFI
1589 const struct device *dev = net_if_get_device(netif);
1590 struct interface *if_handle = (struct interface *)dev->data;
1591
1592 if (dev && if_handle)
1593 {
1594 memset(&if_handle->stats, 0, sizeof(if_handle->stats));
1595 }
1596 #endif
1597 return WM_SUCCESS;
1598 }
1599
net_wlan_deinit(void)1600 int net_wlan_deinit(void)
1601 {
1602 int ret;
1603 osa_status_t status;
1604
1605 if (net_wlan_init_done != 1)
1606 {
1607 return -WM_FAIL;
1608 }
1609
1610 ret = net_netif_deinit(g_mlan.netif);
1611 if (ret != WM_SUCCESS)
1612 {
1613 net_e("MLAN interface deinit failed");
1614 return -WM_FAIL;
1615 }
1616
1617 #if CONFIG_WIFI_SOFTAP_SUPPORT
1618 ret = net_netif_deinit(g_uap.netif);
1619 if (ret != WM_SUCCESS)
1620 {
1621 net_e("UAP interface deinit failed");
1622 return -WM_FAIL;
1623 }
1624 #endif
1625 status = OSA_TimerDestroy((osa_timer_handle_t)dhcp_timer);
1626 if (status != KOSA_StatusSuccess)
1627 {
1628 net_e("DHCP timer deletion failed");
1629 return -WM_FAIL;
1630 }
1631
1632 cleanup_mgmt_events();
1633
1634 net_wlan_init_done = 0;
1635
1636 net_d("DeInitialized TCP/IP networking stack");
1637
1638 return WM_SUCCESS;
1639 }
1640
net_if_get_binding(const char * ifname)1641 const struct netif *net_if_get_binding(const char *ifname)
1642 {
1643 struct netif *iface = NULL;
1644 const struct device *dev = NULL;
1645
1646 dev = device_get_binding(ifname);
1647 if (!dev)
1648 {
1649 return NULL;
1650 }
1651
1652 iface = (struct netif *)net_if_lookup_by_dev(dev);
1653 if (!iface)
1654 {
1655 return NULL;
1656 }
1657
1658 return iface;
1659 }
1660
net_stack_buffer_copy_partial(void * stack_buffer,void * dst,uint16_t len,uint16_t offset)1661 int net_stack_buffer_copy_partial(void *stack_buffer, void *dst, uint16_t len, uint16_t offset)
1662 {
1663 struct net_buf *frag = NULL;
1664 uint16_t left = 0, total_copied = 0, copy_buf_len;
1665
1666 for (frag = ((struct net_pkt *)stack_buffer)->frags; len != 0 && frag != NULL; frag = frag->frags)
1667 {
1668 if ((offset != 0) && (offset >= frag->len))
1669 {
1670 offset = offset - frag->len;
1671 }
1672 else
1673 {
1674 copy_buf_len = frag->len - offset;
1675 if (copy_buf_len > len)
1676 copy_buf_len = len;
1677
1678 memcpy(&((char *)dst)[left], &((char *)frag->data)[offset], copy_buf_len);
1679 total_copied = total_copied + copy_buf_len;
1680 left = left + copy_buf_len;
1681 len = len - copy_buf_len;
1682 offset = 0;
1683 }
1684 }
1685
1686 return total_copied;
1687 }
1688
1689 #if CONFIG_TX_RX_ZERO_COPY
net_tx_zerocopy_process_cb(void * destAddr,void * srcAddr,uint32_t len)1690 void net_tx_zerocopy_process_cb(void *destAddr, void *srcAddr, uint32_t len)
1691 {
1692 outbuf_t *buf = (outbuf_t *)srcAddr;
1693 t_u16 header_len = INTF_HEADER_LEN + sizeof(TxPD) + ETH_HDR_LEN;
1694
1695 (void)memcpy((t_u8 *)destAddr, &buf->intf_header[0], header_len);
1696 net_pkt_read((struct net_pkt *)(buf->buffer), (t_u8 *)destAddr + header_len, (t_u16)(len - header_len));
1697 }
1698 #endif
1699
1700