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(&ethhdr->src.addr[3], &iw416_data.mac_addr[3], 3))) ||
395         (!memcmp(&ethhdr->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