1 /**
2  * Copyright 2023-2024 NXP
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * @file nxp_wifi_drv.c
6  * Shim layer between wifi driver connection manager and zephyr
7  * Wi-Fi L2 layer
8  */
9 
10 #define DT_DRV_COMPAT nxp_wifi
11 
12 #include <zephyr/net/ethernet.h>
13 #include <zephyr/net/dns_resolve.h>
14 #include <zephyr/device.h>
15 #include <soc.h>
16 #include <ethernet/eth_stats.h>
17 #include <zephyr/logging/log.h>
18 
19 #include <zephyr/net/net_if.h>
20 #include <zephyr/net/wifi_mgmt.h>
21 #ifdef CONFIG_PM_DEVICE
22 #include <zephyr/pm/device.h>
23 #endif
24 #ifdef CONFIG_WIFI_NM
25 #include <zephyr/net/wifi_nm.h>
26 #endif
27 
28 LOG_MODULE_REGISTER(nxp_wifi, CONFIG_WIFI_LOG_LEVEL);
29 
30 #include "nxp_wifi_drv.h"
31 
32 /*******************************************************************************
33  * Definitions
34  ******************************************************************************/
35 #ifdef CONFIG_NXP_WIFI_TC_RELOCATE
36 #define NXP_WIFI_SET_FUNC_ATTR __ramfunc
37 #else
38 #define NXP_WIFI_SET_FUNC_ATTR
39 #endif
40 
41 #ifdef CONFIG_NXP_RW610
42 #define IMU_IRQ_N        DT_INST_IRQ_BY_IDX(0, 0, irq)
43 #define IMU_IRQ_P        DT_INST_IRQ_BY_IDX(0, 0, priority)
44 #define IMU_WAKEUP_IRQ_N DT_INST_IRQ_BY_IDX(0, 1, irq)
45 #define IMU_WAKEUP_IRQ_P DT_INST_IRQ_BY_IDX(0, 1, priority)
46 #endif
47 /*******************************************************************************
48  * Variables
49  ******************************************************************************/
50 static int s_nxp_wifi_State = NXP_WIFI_NOT_INITIALIZED;
51 static bool s_nxp_wifi_StaConnected;
52 static bool s_nxp_wifi_UapActivated;
53 static struct k_event s_nxp_wifi_SyncEvent;
54 
55 static struct nxp_wifi_dev nxp_wifi0; /* static instance */
56 
57 static struct wlan_network nxp_wlan_network;
58 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
59 static struct wlan_network nxp_wlan_uap_network;
60 #endif
61 
62 #ifndef CONFIG_WIFI_NM_HOSTAPD_AP
63 static char uap_ssid[IEEEtypes_SSID_SIZE + 1];
64 #endif
65 
66 extern struct interface g_mlan;
67 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
68 extern struct interface g_uap;
69 #endif
70 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
71 extern const rtos_wpa_supp_dev_ops wpa_supp_ops;
72 #endif
73 
74 #if defined(CONFIG_PM_DEVICE) && defined(CONFIG_NXP_RW610)
75 extern int is_hs_handshake_done;
76 extern int wlan_host_sleep_state;
77 #endif
78 
79 static int nxp_wifi_recv(struct net_if *iface, struct net_pkt *pkt);
80 
81 /*******************************************************************************
82  * Prototypes
83  ******************************************************************************/
84 #ifdef CONFIG_NXP_WIFI_STA_AUTO_CONN
85 static void nxp_wifi_auto_connect(void);
86 #endif
87 
88 /* Callback Function passed to WLAN Connection Manager. The callback function
89  * gets called when there are WLAN Events that need to be handled by the
90  * application.
91  */
nxp_wifi_wlan_event_callback(enum wlan_event_reason reason,void * data)92 int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data)
93 {
94 	int ret;
95 #ifndef CONFIG_WIFI_NM_WPA_SUPPLICANT
96 	struct wlan_ip_config addr;
97 	char ssid[IEEEtypes_SSID_SIZE + 1];
98 	char ip[16];
99 #endif
100 	static int auth_fail;
101 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
102 	wlan_uap_client_disassoc_t *disassoc_resp = data;
103 	struct in_addr dhcps_addr4;
104 	struct in_addr base_addr;
105 	struct in_addr netmask_addr;
106 #endif
107 	struct wifi_iface_status status = { 0 };
108 	struct wifi_ap_sta_info ap_sta_info = { 0 };
109 
110 	LOG_DBG("WLAN: received event %d", reason);
111 
112 	if (s_nxp_wifi_State >= NXP_WIFI_INITIALIZED) {
113 		/* Do not replace the current set of events  */
114 		k_event_post(&s_nxp_wifi_SyncEvent, NXP_WIFI_EVENT_BIT(reason));
115 	}
116 
117 	switch (reason) {
118 	case WLAN_REASON_INITIALIZED:
119 		LOG_DBG("WLAN initialized");
120 
121 #ifdef CONFIG_NET_INTERFACE_NAME
122 		ret = net_if_set_name(g_mlan.netif, "ml");
123 		if (ret < 0) {
124 			LOG_ERR("Failed to set STA nxp_wlan_network interface name");
125 			return 0;
126 		}
127 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
128 		ret = net_if_set_name(g_uap.netif, "ua");
129 		if (ret < 0) {
130 			LOG_ERR("Failed to set uAP nxp_wlan_network interface name");
131 			return 0;
132 		}
133 #endif
134 #endif
135 
136 #ifdef CONFIG_NXP_WIFI_STA_AUTO_CONN
137 		nxp_wifi_auto_connect();
138 #endif
139 		break;
140 	case WLAN_REASON_INITIALIZATION_FAILED:
141 		LOG_ERR("WLAN: initialization failed");
142 		break;
143 	case WLAN_REASON_AUTH_SUCCESS:
144 #ifndef CONFIG_WIFI_NM_WPA_SUPPLICANT
145 		net_if_dormant_off(g_mlan.netif);
146 #endif
147 		LOG_DBG("WLAN: authenticated to nxp_wlan_network");
148 		break;
149 	case WLAN_REASON_ASSOC_SUCCESS:
150 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
151 		net_if_dormant_off(g_mlan.netif);
152 #endif
153 		LOG_DBG("WLAN: associated to nxp_wlan_network");
154 		break;
155 	case WLAN_REASON_SUCCESS:
156 		LOG_DBG("WLAN: connected to nxp_wlan_network");
157 #ifndef CONFIG_WIFI_NM_WPA_SUPPLICANT
158 		ret = wlan_get_address(&addr);
159 		if (ret != WM_SUCCESS) {
160 			LOG_ERR("failed to get IP address");
161 			return 0;
162 		}
163 
164 		net_inet_ntoa(addr.ipv4.address, ip);
165 
166 		ret = wlan_get_current_network_ssid(ssid);
167 		if (ret != WM_SUCCESS) {
168 			LOG_ERR("Failed to get External AP nxp_wlan_network ssid");
169 			return 0;
170 		}
171 
172 		LOG_DBG("Connected to following BSS:");
173 		LOG_DBG("SSID = [%s]", ssid);
174 		if (addr.ipv4.address != 0U) {
175 			LOG_DBG("IPv4 Address: [%s]", ip);
176 		}
177 #ifdef CONFIG_NXP_WIFI_IPV6
178 		ARRAY_FOR_EACH(addr.ipv6, i) {
179 			if ((addr.ipv6[i].addr_state == NET_ADDR_TENTATIVE) ||
180 			    (addr.ipv6[i].addr_state == NET_ADDR_PREFERRED)) {
181 				LOG_DBG("IPv6 Address: %-13s:\t%s (%s)",
182 					ipv6_addr_type_to_desc(
183 						(struct net_ipv6_config *)&addr.ipv6[i]),
184 					ipv6_addr_addr_to_desc(
185 						(struct net_ipv6_config *)&addr.ipv6[i]),
186 					ipv6_addr_state_to_desc(addr.ipv6[i].addr_state));
187 			}
188 		}
189 		LOG_DBG("");
190 #endif
191 #endif
192 		auth_fail = 0;
193 		s_nxp_wifi_StaConnected = true;
194 		wifi_mgmt_raise_connect_result_event(g_mlan.netif, 0);
195 		break;
196 	case WLAN_REASON_CONNECT_FAILED:
197 		net_if_dormant_on(g_mlan.netif);
198 		LOG_WRN("WLAN: connect failed");
199 		break;
200 	case WLAN_REASON_NETWORK_NOT_FOUND:
201 		net_if_dormant_on(g_mlan.netif);
202 		LOG_WRN("WLAN: nxp_wlan_network not found");
203 		break;
204 	case WLAN_REASON_NETWORK_AUTH_FAILED:
205 		LOG_WRN("WLAN: nxp_wlan_network authentication failed");
206 		auth_fail++;
207 		if (auth_fail >= 3) {
208 			LOG_WRN("Authentication Failed. Disconnecting ... ");
209 			wlan_disconnect();
210 			auth_fail = 0;
211 		}
212 		net_if_dormant_on(g_mlan.netif);
213 		break;
214 	case WLAN_REASON_ADDRESS_SUCCESS:
215 		LOG_DBG("wlan_network mgr: DHCP new lease");
216 		break;
217 	case WLAN_REASON_ADDRESS_FAILED:
218 		LOG_WRN("failed to obtain an IP address");
219 		break;
220 	case WLAN_REASON_USER_DISCONNECT:
221 		net_if_dormant_on(g_mlan.netif);
222 		LOG_DBG("disconnected");
223 		auth_fail = 0;
224 		s_nxp_wifi_StaConnected = false;
225 		wifi_mgmt_raise_disconnect_result_event(g_mlan.netif, 0);
226 		break;
227 	case WLAN_REASON_LINK_LOST:
228 		net_if_dormant_on(g_mlan.netif);
229 		LOG_WRN("WLAN: link lost");
230 		break;
231 	case WLAN_REASON_DISCONNECTED:
232 		net_if_dormant_on(g_mlan.netif);
233 		LOG_DBG("WLAN: deauth leaving");
234 		break;
235 	case WLAN_REASON_CHAN_SWITCH:
236 		LOG_DBG("WLAN: channel switch");
237 		break;
238 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
239 	case WLAN_REASON_UAP_SUCCESS:
240 		LOG_DBG("WLAN: UAP Started");
241 #ifndef CONFIG_WIFI_NM_HOSTAPD_AP
242 		ret = wlan_get_current_uap_network_ssid(uap_ssid);
243 		if (ret != WM_SUCCESS) {
244 			LOG_ERR("Failed to get Soft AP nxp_wlan_network ssid");
245 			return 0;
246 		}
247 
248 		LOG_DBG("Soft AP \"%s\" started successfully", uap_ssid);
249 #endif
250 		if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS, &dhcps_addr4) < 0) {
251 			LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS");
252 			return 0;
253 		}
254 		net_if_ipv4_addr_add(g_uap.netif, &dhcps_addr4, NET_ADDR_MANUAL, 0);
255 		net_if_ipv4_set_gw(g_uap.netif, &dhcps_addr4);
256 
257 		if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_MASK, &netmask_addr) < 0) {
258 			LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_MASK");
259 			return 0;
260 		}
261 		net_if_ipv4_set_netmask_by_addr(g_uap.netif, &dhcps_addr4, &netmask_addr);
262 		net_if_dormant_off(g_uap.netif);
263 
264 		if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_BASE, &base_addr) < 0) {
265 			LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_BASE");
266 			return 0;
267 		}
268 
269 		if (net_dhcpv4_server_start(g_uap.netif, &base_addr) < 0) {
270 			LOG_ERR("DHCP Server start failed");
271 			return 0;
272 		}
273 
274 		LOG_DBG("DHCP Server started successfully");
275 		s_nxp_wifi_UapActivated = true;
276 		break;
277 	case WLAN_REASON_UAP_CLIENT_ASSOC:
278 		LOG_DBG("WLAN: UAP a Client Associated");
279 		LOG_DBG("Client => ");
280 		print_mac((const char *)data);
281 		LOG_DBG("Associated with Soft AP");
282 		break;
283 	case WLAN_REASON_UAP_CLIENT_CONN:
284 		wlan_get_current_uap_network(&nxp_wlan_uap_network);
285 #ifdef CONFIG_NXP_WIFI_11AX
286 		if (nxp_wlan_uap_network.dot11ax) {
287 			ap_sta_info.link_mode = WIFI_6;
288 		} else
289 #endif
290 #ifdef CONFIG_NXP_WIFI_11AC
291 			if (nxp_wlan_uap_network.dot11ac) {
292 				ap_sta_info.link_mode = WIFI_5;
293 		} else
294 #endif
295 			if (nxp_wlan_uap_network.dot11n) {
296 				ap_sta_info.link_mode = WIFI_4;
297 		} else {
298 			ap_sta_info.link_mode = WIFI_3;
299 		}
300 
301 		memcpy(ap_sta_info.mac, data, WIFI_MAC_ADDR_LEN);
302 		ap_sta_info.mac_length  = WIFI_MAC_ADDR_LEN;
303 		ap_sta_info.twt_capable = status.twt_capable;
304 
305 		wifi_mgmt_raise_ap_sta_connected_event(g_uap.netif, &ap_sta_info);
306 		LOG_DBG("WLAN: UAP a Client Connected");
307 		LOG_DBG("Client => ");
308 		print_mac((const char *)data);
309 		LOG_DBG("Connected with Soft AP");
310 		break;
311 	case WLAN_REASON_UAP_CLIENT_DISSOC:
312 		memcpy(ap_sta_info.mac, disassoc_resp->sta_addr, WIFI_MAC_ADDR_LEN);
313 		wifi_mgmt_raise_ap_sta_disconnected_event(g_uap.netif, &ap_sta_info);
314 
315 		LOG_DBG("WLAN: UAP a Client Dissociated:");
316 		LOG_DBG(" Client MAC => ");
317 		print_mac((const char *)(disassoc_resp->sta_addr));
318 		LOG_DBG(" Reason code => ");
319 		LOG_DBG("%d", disassoc_resp->reason_code);
320 		break;
321 	case WLAN_REASON_UAP_STOPPED:
322 		net_if_dormant_on(g_uap.netif);
323 		LOG_DBG("WLAN: UAP Stopped");
324 
325 		if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS, &dhcps_addr4) < 0) {
326 			LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS");
327 		} else {
328 			net_if_ipv4_addr_rm(g_uap.netif, &dhcps_addr4);
329 		}
330 
331 		net_dhcpv4_server_stop(g_uap.netif);
332 		LOG_DBG("DHCP Server stopped successfully");
333 		s_nxp_wifi_UapActivated = false;
334 		break;
335 #endif
336 	case WLAN_REASON_PS_ENTER:
337 		LOG_DBG("WLAN: PS_ENTER");
338 		break;
339 	case WLAN_REASON_PS_EXIT:
340 		LOG_DBG("WLAN: PS EXIT");
341 		break;
342 #ifdef CONFIG_NXP_WIFI_SUBSCRIBE_EVENT_SUPPORT
343 	case WLAN_REASON_RSSI_HIGH:
344 	case WLAN_REASON_SNR_LOW:
345 	case WLAN_REASON_SNR_HIGH:
346 	case WLAN_REASON_MAX_FAIL:
347 	case WLAN_REASON_BEACON_MISSED:
348 	case WLAN_REASON_DATA_RSSI_LOW:
349 	case WLAN_REASON_DATA_RSSI_HIGH:
350 	case WLAN_REASON_DATA_SNR_LOW:
351 	case WLAN_REASON_DATA_SNR_HIGH:
352 	case WLAN_REASON_LINK_QUALITY:
353 	case WLAN_REASON_PRE_BEACON_LOST:
354 		break;
355 #endif
356 	case WLAN_REASON_FW_HANG:
357 	case WLAN_REASON_FW_RESET:
358 		LOG_DBG("WLAN: FW hang");
359 		break;
360 	default:
361 		LOG_WRN("WLAN: Unknown Event: %d", reason);
362 	}
363 	return 0;
364 }
365 
nxp_wifi_wlan_init(void)366 static int nxp_wifi_wlan_init(void)
367 {
368 	int status = NXP_WIFI_RET_SUCCESS;
369 	int ret;
370 
371 	if (s_nxp_wifi_State != NXP_WIFI_NOT_INITIALIZED) {
372 		status = NXP_WIFI_RET_FAIL;
373 	}
374 
375 	if (status == NXP_WIFI_RET_SUCCESS) {
376 		k_event_init(&s_nxp_wifi_SyncEvent);
377 	}
378 
379 	if (status == NXP_WIFI_RET_SUCCESS) {
380 		ret = wlan_init(wlan_fw_bin, wlan_fw_bin_len);
381 		if (ret != WM_SUCCESS) {
382 			status = NXP_WIFI_RET_FAIL;
383 		}
384 	}
385 
386 	if (status != NXP_WIFI_RET_SUCCESS) {
387 		return -1;
388 	}
389 
390 	s_nxp_wifi_State = NXP_WIFI_INITIALIZED;
391 
392 	nxp_wifi_internal_register_rx_cb(nxp_wifi_recv);
393 
394 	return 0;
395 }
396 
nxp_wifi_wlan_start(void)397 static int nxp_wifi_wlan_start(void)
398 {
399 	int status = NXP_WIFI_RET_SUCCESS;
400 	int ret;
401 	uint32_t syncBit;
402 
403 	if (s_nxp_wifi_State != NXP_WIFI_INITIALIZED) {
404 		status = NXP_WIFI_RET_NOT_READY;
405 	}
406 
407 	if (status == NXP_WIFI_RET_SUCCESS) {
408 		k_event_clear(&s_nxp_wifi_SyncEvent, NXP_WIFI_SYNC_INIT_GROUP);
409 
410 		ret = wlan_start(nxp_wifi_wlan_event_callback);
411 		if (ret != WM_SUCCESS) {
412 			status = NXP_WIFI_RET_FAIL;
413 		}
414 	}
415 
416 	if (status == NXP_WIFI_RET_SUCCESS) {
417 		syncBit = k_event_wait(&s_nxp_wifi_SyncEvent, NXP_WIFI_SYNC_INIT_GROUP, false,
418 				       NXP_WIFI_SYNC_TIMEOUT_MS);
419 		k_event_clear(&s_nxp_wifi_SyncEvent, NXP_WIFI_SYNC_INIT_GROUP);
420 		if (syncBit & NXP_WIFI_EVENT_BIT(WLAN_REASON_INITIALIZED)) {
421 			status = NXP_WIFI_RET_SUCCESS;
422 		} else if (syncBit & NXP_WIFI_EVENT_BIT(WLAN_REASON_INITIALIZATION_FAILED)) {
423 			status = NXP_WIFI_RET_FAIL;
424 		} else {
425 			status = NXP_WIFI_RET_TIMEOUT;
426 		}
427 	}
428 
429 	if (status != NXP_WIFI_RET_SUCCESS) {
430 		return -1;
431 	}
432 
433 	s_nxp_wifi_State = NXP_WIFI_STARTED;
434 
435 	/* Initialize device as dormant */
436 	net_if_dormant_on(g_mlan.netif);
437 
438 	/* L1 network layer (physical layer) is up */
439 	net_eth_carrier_on(g_mlan.netif);
440 
441 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
442 	/* Initialize device as dormant */
443 	net_if_dormant_on(g_uap.netif);
444 
445 	/* L1 network layer (physical layer) is up */
446 	net_eth_carrier_on(g_uap.netif);
447 #endif
448 
449 	return 0;
450 }
451 
452 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
453 
nxp_wifi_start_ap(const struct device * dev,struct wifi_connect_req_params * params)454 static int nxp_wifi_start_ap(const struct device *dev, struct wifi_connect_req_params *params)
455 {
456 	int status = NXP_WIFI_RET_SUCCESS;
457 	int ret;
458 	struct interface *if_handle = (struct interface *)&g_uap;
459 	struct ipv4_config *ap_addr4 = &nxp_wlan_uap_network.ip.ipv4;
460 
461 	if (if_handle->state.interface != WLAN_BSS_TYPE_UAP) {
462 		LOG_ERR("Wi-Fi not in uAP mode");
463 		return -EIO;
464 	}
465 
466 	if ((s_nxp_wifi_State != NXP_WIFI_STARTED) || (s_nxp_wifi_UapActivated != false)) {
467 		status = NXP_WIFI_RET_NOT_READY;
468 	}
469 
470 	if (status == NXP_WIFI_RET_SUCCESS) {
471 		if ((params->ssid_length == 0) || (params->ssid_length > IEEEtypes_SSID_SIZE)) {
472 			status = NXP_WIFI_RET_BAD_PARAM;
473 		}
474 	}
475 
476 	if (status == NXP_WIFI_RET_SUCCESS) {
477 		wlan_remove_network(nxp_wlan_uap_network.name);
478 
479 		wlan_initialize_uap_network(&nxp_wlan_uap_network);
480 
481 		memcpy(nxp_wlan_uap_network.name, NXP_WIFI_UAP_NETWORK_NAME,
482 		       strlen(NXP_WIFI_UAP_NETWORK_NAME));
483 
484 		memcpy(nxp_wlan_uap_network.ssid, params->ssid, params->ssid_length);
485 
486 		if (params->channel == WIFI_CHANNEL_ANY) {
487 			nxp_wlan_uap_network.channel = 0;
488 		} else {
489 			nxp_wlan_uap_network.channel = params->channel;
490 		}
491 
492 		if (params->mfp == WIFI_MFP_REQUIRED) {
493 			nxp_wlan_uap_network.security.mfpc = true;
494 			nxp_wlan_uap_network.security.mfpr = true;
495 		} else if (params->mfp == WIFI_MFP_OPTIONAL) {
496 			nxp_wlan_uap_network.security.mfpc = true;
497 			nxp_wlan_uap_network.security.mfpr = false;
498 		}
499 
500 		if (params->security == WIFI_SECURITY_TYPE_NONE) {
501 			nxp_wlan_uap_network.security.type = WLAN_SECURITY_NONE;
502 		} else if (params->security == WIFI_SECURITY_TYPE_PSK) {
503 			nxp_wlan_uap_network.security.type = WLAN_SECURITY_WPA2;
504 			nxp_wlan_uap_network.security.psk_len = params->psk_length;
505 			strncpy(nxp_wlan_uap_network.security.psk, params->psk, params->psk_length);
506 		}
507 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
508 		else if (params->security == WIFI_SECURITY_TYPE_PSK_SHA256) {
509 			nxp_wlan_uap_network.security.type = WLAN_SECURITY_WPA2;
510 			nxp_wlan_uap_network.security.key_mgmt |= WLAN_KEY_MGMT_PSK_SHA256;
511 			nxp_wlan_uap_network.security.psk_len = params->psk_length;
512 			strncpy(nxp_wlan_uap_network.security.psk, params->psk, params->psk_length);
513 		}
514 #endif
515 		else if (params->security == WIFI_SECURITY_TYPE_SAE) {
516 			nxp_wlan_uap_network.security.type = WLAN_SECURITY_WPA3_SAE;
517 			nxp_wlan_uap_network.security.password_len = params->psk_length;
518 			strncpy(nxp_wlan_uap_network.security.password, params->psk,
519 				params->psk_length);
520 		} else {
521 			status = NXP_WIFI_RET_BAD_PARAM;
522 		}
523 	}
524 
525 	if (status != NXP_WIFI_RET_SUCCESS) {
526 		LOG_ERR("Failed to enable Wi-Fi AP mode");
527 		return -EAGAIN;
528 	}
529 
530 	if (params->ignore_broadcast_ssid != 0) {
531 		wlan_uap_set_hidden_ssid(params->ignore_broadcast_ssid);
532 	}
533 
534 	switch (params->bandwidth) {
535 	case WIFI_FREQ_BANDWIDTH_20MHZ:
536 	case WIFI_FREQ_BANDWIDTH_40MHZ:
537 	case WIFI_FREQ_BANDWIDTH_80MHZ:
538 		wlan_uap_set_bandwidth(params->bandwidth);
539 		break;
540 	default:
541 		LOG_ERR("Invalid bandwidth");
542 		return -EAGAIN;
543 	}
544 
545 	if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS, &ap_addr4->address) < 0) {
546 		LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_ADDRESS");
547 		return -ENOENT;
548 	}
549 	ap_addr4->gw = ap_addr4->address;
550 
551 	if (net_addr_pton(AF_INET, CONFIG_NXP_WIFI_SOFTAP_IP_MASK, &ap_addr4->netmask) < 0) {
552 		LOG_ERR("Invalid CONFIG_NXP_WIFI_SOFTAP_IP_MASK");
553 		return -ENOENT;
554 	}
555 
556 	ret = wlan_add_network(&nxp_wlan_uap_network);
557 	if (ret != WM_SUCCESS) {
558 		status = NXP_WIFI_RET_FAIL;
559 	}
560 
561 	ret = wlan_start_network(nxp_wlan_uap_network.name);
562 	if (ret != WM_SUCCESS) {
563 		wlan_remove_network(nxp_wlan_uap_network.name);
564 		status = NXP_WIFI_RET_FAIL;
565 	}
566 
567 	return 0;
568 }
569 
nxp_wifi_stop_ap(const struct device * dev)570 static int nxp_wifi_stop_ap(const struct device *dev)
571 {
572 	int status = NXP_WIFI_RET_SUCCESS;
573 	int ret;
574 	struct interface *if_handle = (struct interface *)&g_uap;
575 
576 	if (if_handle->state.interface != WLAN_BSS_TYPE_UAP) {
577 		LOG_ERR("Wi-Fi not in uAP mode");
578 		return -EIO;
579 	}
580 
581 	if ((s_nxp_wifi_State != NXP_WIFI_STARTED) || (s_nxp_wifi_UapActivated != true)) {
582 		status = NXP_WIFI_RET_NOT_READY;
583 	}
584 
585 	if (status == NXP_WIFI_RET_SUCCESS) {
586 		ret = wlan_stop_network(NXP_WIFI_UAP_NETWORK_NAME);
587 		if (ret != WM_SUCCESS) {
588 			status = NXP_WIFI_RET_FAIL;
589 		}
590 	}
591 
592 	if (status != NXP_WIFI_RET_SUCCESS) {
593 		LOG_ERR("Failed to disable Wi-Fi AP mode");
594 		return -EAGAIN;
595 	}
596 
597 	return 0;
598 }
599 
nxp_wifi_ap_config_params(const struct device * dev,struct wifi_ap_config_params * params)600 static int nxp_wifi_ap_config_params(const struct device *dev, struct wifi_ap_config_params *params)
601 {
602 	int status = NXP_WIFI_RET_SUCCESS;
603 	int ret = WM_SUCCESS;
604 	interface_t *if_handle = (interface_t *)dev->data;
605 
606 	if (if_handle->state.interface != WLAN_BSS_TYPE_UAP) {
607 		LOG_ERR("Wi-Fi not in uAP mode");
608 		return -EIO;
609 	}
610 
611 	if (s_nxp_wifi_State != NXP_WIFI_STARTED) {
612 		status = NXP_WIFI_RET_NOT_READY;
613 	}
614 
615 	if (status == NXP_WIFI_RET_SUCCESS) {
616 		if (params->type & WIFI_AP_CONFIG_PARAM_MAX_INACTIVITY) {
617 			ret = wlan_uap_set_sta_ageout_timer(params->max_inactivity * 10);
618 			if (ret != WM_SUCCESS) {
619 				status = NXP_WIFI_RET_FAIL;
620 				LOG_ERR("Failed to set maximum inactivity duration for stations");
621 			} else {
622 				LOG_INF("Set maximum inactivity duration for stations: %d (s)",
623 					params->max_inactivity);
624 			}
625 		}
626 
627 		if (params->type & WIFI_AP_CONFIG_PARAM_MAX_NUM_STA) {
628 			ret = wlan_set_uap_max_clients(params->max_num_sta);
629 			if (ret != WM_SUCCESS) {
630 				status = NXP_WIFI_RET_FAIL;
631 				LOG_ERR("Failed to set maximum number of stations");
632 			} else {
633 				LOG_INF("Set maximum number of stations: %d", params->max_num_sta);
634 			}
635 		}
636 
637 		if (params->type & WIFI_AP_CONFIG_PARAM_BANDWIDTH) {
638 			ret = wlan_uap_set_bandwidth(params->bandwidth);
639 			if (ret != WM_SUCCESS) {
640 				status = NXP_WIFI_RET_FAIL;
641 				LOG_ERR("Failed to set Wi-Fi AP bandwidth");
642 			} else {
643 				LOG_INF("Set  Wi-Fi AP bandwidth: %d", params->bandwidth);
644 			}
645 		}
646 	}
647 
648 	if (status != NXP_WIFI_RET_SUCCESS) {
649 		return -EAGAIN;
650 	}
651 
652 	return 0;
653 }
654 #endif
655 
nxp_wifi_process_results(unsigned int count)656 static int nxp_wifi_process_results(unsigned int count)
657 {
658 	struct wlan_scan_result scan_result = {0};
659 	struct wifi_scan_result res = {0};
660 
661 	if (!count) {
662 		LOG_DBG("No Wi-Fi AP found");
663 		goto out;
664 	}
665 
666 	if (g_mlan.max_bss_cnt) {
667 		count = g_mlan.max_bss_cnt > count ? count : g_mlan.max_bss_cnt;
668 	}
669 
670 	for (int i = 0; i < count; i++) {
671 		wlan_get_scan_result(i, &scan_result);
672 
673 		memset(&res, 0, sizeof(struct wifi_scan_result));
674 
675 		memcpy(res.mac, scan_result.bssid, WIFI_MAC_ADDR_LEN);
676 		res.mac_length = WIFI_MAC_ADDR_LEN;
677 		res.ssid_length = scan_result.ssid_len;
678 		strncpy(res.ssid, scan_result.ssid, scan_result.ssid_len);
679 
680 		res.rssi = -scan_result.rssi;
681 		res.channel = scan_result.channel;
682 		res.band = scan_result.channel > 14 ? WIFI_FREQ_BAND_5_GHZ : WIFI_FREQ_BAND_2_4_GHZ;
683 
684 		res.security = WIFI_SECURITY_TYPE_NONE;
685 
686 		if (scan_result.wpa2_entp) {
687 			res.security = WIFI_SECURITY_TYPE_EAP_TLS;
688 		}
689 		if (scan_result.wpa2) {
690 			res.security = WIFI_SECURITY_TYPE_PSK;
691 		}
692 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
693 		if (scan_result.wpa2_sha256) {
694 			res.security = WIFI_SECURITY_TYPE_PSK_SHA256;
695 		}
696 #endif
697 		if (scan_result.wpa3_sae) {
698 			res.security = WIFI_SECURITY_TYPE_SAE;
699 		}
700 
701 		if (scan_result.ap_mfpr) {
702 			res.mfp = WIFI_MFP_REQUIRED;
703 		} else if (scan_result.ap_mfpc) {
704 			res.mfp = WIFI_MFP_OPTIONAL;
705 		}
706 
707 		if (g_mlan.scan_cb) {
708 			g_mlan.scan_cb(g_mlan.netif, 0, &res);
709 
710 			/* ensure notifications get delivered */
711 			k_yield();
712 		}
713 	}
714 
715 out:
716 	/* report end of scan event */
717 	if (g_mlan.scan_cb) {
718 		g_mlan.scan_cb(g_mlan.netif, 0, NULL);
719 	}
720 
721 	g_mlan.scan_cb = NULL;
722 
723 	return WM_SUCCESS;
724 }
725 
nxp_wifi_scan(const struct device * dev,struct wifi_scan_params * params,scan_result_cb_t cb)726 static int nxp_wifi_scan(const struct device *dev, struct wifi_scan_params *params,
727 			 scan_result_cb_t cb)
728 {
729 	int ret;
730 	struct interface *if_handle = (struct interface *)dev->data;
731 	wlan_scan_params_v2_t wlan_scan_params_v2 = {0};
732 	uint8_t i = 0;
733 
734 	if (if_handle->state.interface != WLAN_BSS_TYPE_STA) {
735 		LOG_ERR("Wi-Fi not in station mode");
736 		return -EIO;
737 	}
738 
739 	if (s_nxp_wifi_State != NXP_WIFI_STARTED) {
740 		LOG_ERR("Wi-Fi not started status %d", s_nxp_wifi_State);
741 		return -EBUSY;
742 	}
743 
744 	if (g_mlan.scan_cb != NULL) {
745 		LOG_WRN("Scan callback in progress");
746 		return -EINPROGRESS;
747 	}
748 
749 	g_mlan.scan_cb = cb;
750 
751 	if (params == NULL) {
752 		goto do_scan;
753 	}
754 
755 	g_mlan.max_bss_cnt = params->max_bss_cnt;
756 
757 	if (params->bands & (1 << WIFI_FREQ_BAND_6_GHZ)) {
758 		LOG_ERR("Wi-Fi band 6 GHz not supported");
759 		g_mlan.scan_cb = NULL;
760 		return -EIO;
761 	}
762 #if (CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX > 0)
763 	if (params->ssids[0]) {
764 		strncpy(wlan_scan_params_v2.ssid[0], params->ssids[0], WIFI_SSID_MAX_LEN);
765 		wlan_scan_params_v2.ssid[0][WIFI_SSID_MAX_LEN - 1] = 0;
766 	}
767 
768 #if (CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX > 1)
769 	if (params->ssids[1]) {
770 		strncpy(wlan_scan_params_v2.ssid[1], params->ssids[1], WIFI_SSID_MAX_LEN);
771 		wlan_scan_params_v2.ssid[1][WIFI_SSID_MAX_LEN - 1] = 0;
772 	}
773 #endif
774 #endif
775 
776 #ifdef CONFIG_WIFI_MGMT_SCAN_CHAN_MAX_MANUAL
777 
778 	for (i = 0; i < WIFI_MGMT_SCAN_CHAN_MAX_MANUAL && params->band_chan[i].channel; i++) {
779 		if (params->scan_type == WIFI_SCAN_TYPE_ACTIVE) {
780 			wlan_scan_params_v2.chan_list[i].scan_type = MLAN_SCAN_TYPE_ACTIVE;
781 			wlan_scan_params_v2.chan_list[i].scan_time = params->dwell_time_active;
782 		} else {
783 			wlan_scan_params_v2.chan_list[i].scan_type = MLAN_SCAN_TYPE_PASSIVE;
784 			wlan_scan_params_v2.chan_list[i].scan_time = params->dwell_time_passive;
785 		}
786 
787 		wlan_scan_params_v2.chan_list[i].chan_number =
788 			(uint8_t)(params->band_chan[i].channel);
789 	}
790 #endif
791 
792 	wlan_scan_params_v2.num_channels = i;
793 
794 	if (params->bands & (1 << WIFI_FREQ_BAND_2_4_GHZ)) {
795 		wlan_scan_params_v2.chan_list[0].radio_type = 0 | BAND_SPECIFIED;
796 	}
797 #ifdef CONFIG_5GHz_SUPPORT
798 	if (params->bands & (1 << WIFI_FREQ_BAND_5_GHZ)) {
799 		if (wlan_scan_params_v2.chan_list[0].radio_type & BAND_SPECIFIED) {
800 			wlan_scan_params_v2.chan_list[0].radio_type = 0;
801 		} else {
802 			wlan_scan_params_v2.chan_list[0].radio_type = 1 | BAND_SPECIFIED;
803 		}
804 	}
805 #else
806 	if (params->bands & (1 << WIFI_FREQ_BAND_5_GHZ)) {
807 		LOG_ERR("Wi-Fi band 5Hz not supported");
808 		g_mlan.scan_cb = NULL;
809 		return -EIO;
810 	}
811 #endif
812 
813 do_scan:
814 	wlan_scan_params_v2.cb = nxp_wifi_process_results;
815 
816 	ret = wlan_scan_with_opt(wlan_scan_params_v2);
817 	if (ret != WM_SUCCESS) {
818 		LOG_ERR("Failed to start Wi-Fi scanning");
819 		g_mlan.scan_cb = NULL;
820 		return -EAGAIN;
821 	}
822 
823 	return 0;
824 }
825 
nxp_wifi_version(const struct device * dev,struct wifi_version * params)826 static int nxp_wifi_version(const struct device *dev, struct wifi_version *params)
827 {
828 	int status = NXP_WIFI_RET_SUCCESS;
829 
830 	if (s_nxp_wifi_State != NXP_WIFI_STARTED) {
831 		status = NXP_WIFI_RET_NOT_READY;
832 	}
833 
834 	if (status != NXP_WIFI_RET_SUCCESS) {
835 		LOG_ERR("Failed to get Wi-Fi driver/firmware version");
836 		return -EAGAIN;
837 	}
838 
839 	params->drv_version = WLAN_DRV_VERSION;
840 
841 	params->fw_version = wlan_get_firmware_version_ext();
842 
843 	return 0;
844 }
845 
nxp_wifi_connect(const struct device * dev,struct wifi_connect_req_params * params)846 static int nxp_wifi_connect(const struct device *dev, struct wifi_connect_req_params *params)
847 {
848 	int status = NXP_WIFI_RET_SUCCESS;
849 	int ret;
850 	struct interface *if_handle = (struct interface *)dev->data;
851 
852 	if (s_nxp_wifi_State != NXP_WIFI_STARTED) {
853 		LOG_ERR("Wi-Fi not started");
854 		wifi_mgmt_raise_connect_result_event(g_mlan.netif, -1);
855 		return -EALREADY;
856 	}
857 
858 	if (if_handle->state.interface != WLAN_BSS_TYPE_STA) {
859 		LOG_ERR("Wi-Fi not in station mode");
860 		wifi_mgmt_raise_connect_result_event(g_mlan.netif, -1);
861 		return -EIO;
862 	}
863 
864 	if ((params->ssid_length == 0) || (params->ssid_length > IEEEtypes_SSID_SIZE)) {
865 		status = NXP_WIFI_RET_BAD_PARAM;
866 	}
867 
868 	if (status == NXP_WIFI_RET_SUCCESS) {
869 		wlan_disconnect();
870 
871 		wlan_remove_network(nxp_wlan_network.name);
872 
873 		wlan_initialize_sta_network(&nxp_wlan_network);
874 
875 		memcpy(nxp_wlan_network.name, NXP_WIFI_STA_NETWORK_NAME,
876 		       strlen(NXP_WIFI_STA_NETWORK_NAME));
877 
878 		memcpy(nxp_wlan_network.ssid, params->ssid, params->ssid_length);
879 
880 		nxp_wlan_network.ssid_specific = 1;
881 
882 		if (params->channel == WIFI_CHANNEL_ANY) {
883 			nxp_wlan_network.channel = 0;
884 		} else {
885 			nxp_wlan_network.channel = params->channel;
886 		}
887 
888 		if (params->mfp == WIFI_MFP_REQUIRED) {
889 			nxp_wlan_network.security.mfpc = true;
890 			nxp_wlan_network.security.mfpr = true;
891 		} else if (params->mfp == WIFI_MFP_OPTIONAL) {
892 			nxp_wlan_network.security.mfpc = true;
893 			nxp_wlan_network.security.mfpr = false;
894 		}
895 
896 		if (params->security == WIFI_SECURITY_TYPE_NONE) {
897 			nxp_wlan_network.security.type = WLAN_SECURITY_NONE;
898 		} else if (params->security == WIFI_SECURITY_TYPE_PSK) {
899 			nxp_wlan_network.security.type = WLAN_SECURITY_WPA2;
900 			nxp_wlan_network.security.psk_len = params->psk_length;
901 			strncpy(nxp_wlan_network.security.psk, params->psk, params->psk_length);
902 		}
903 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
904 		else if (params->security == WIFI_SECURITY_TYPE_PSK_SHA256) {
905 			nxp_wlan_network.security.type = WLAN_SECURITY_WPA2;
906 			nxp_wlan_network.security.key_mgmt |= WLAN_KEY_MGMT_PSK_SHA256;
907 			nxp_wlan_network.security.psk_len = params->psk_length;
908 			strncpy(nxp_wlan_network.security.psk, params->psk, params->psk_length);
909 		}
910 #endif
911 		else if (params->security == WIFI_SECURITY_TYPE_SAE) {
912 			nxp_wlan_network.security.type = WLAN_SECURITY_WPA3_SAE;
913 			nxp_wlan_network.security.password_len = params->psk_length;
914 			strncpy(nxp_wlan_network.security.password, params->psk,
915 				params->psk_length);
916 		} else {
917 			status = NXP_WIFI_RET_BAD_PARAM;
918 		}
919 	}
920 
921 	if (status != NXP_WIFI_RET_SUCCESS) {
922 		LOG_ERR("Failed to connect to Wi-Fi access point");
923 		return -EAGAIN;
924 	}
925 
926 	ret = wlan_add_network(&nxp_wlan_network);
927 	if (ret != WM_SUCCESS) {
928 		status = NXP_WIFI_RET_FAIL;
929 	}
930 
931 	ret = wlan_connect(nxp_wlan_network.name);
932 	if (ret != WM_SUCCESS) {
933 		status = NXP_WIFI_RET_FAIL;
934 	}
935 
936 	return 0;
937 }
938 
nxp_wifi_disconnect(const struct device * dev)939 static int nxp_wifi_disconnect(const struct device *dev)
940 {
941 	int status = NXP_WIFI_RET_SUCCESS;
942 	int ret;
943 	struct interface *if_handle = (struct interface *)dev->data;
944 	enum wlan_connection_state connection_state = WLAN_DISCONNECTED;
945 
946 	if (s_nxp_wifi_State != NXP_WIFI_STARTED) {
947 		status = NXP_WIFI_RET_NOT_READY;
948 	}
949 
950 	if (if_handle->state.interface != WLAN_BSS_TYPE_STA) {
951 		LOG_ERR("Wi-Fi not in station mode");
952 		return -EIO;
953 	}
954 
955 	wlan_get_connection_state(&connection_state);
956 	if (connection_state == WLAN_DISCONNECTED) {
957 		s_nxp_wifi_StaConnected = false;
958 		wifi_mgmt_raise_disconnect_result_event(g_mlan.netif, -1);
959 		return NXP_WIFI_RET_SUCCESS;
960 	}
961 
962 	if (status == NXP_WIFI_RET_SUCCESS) {
963 		ret = wlan_disconnect();
964 		if (ret != WM_SUCCESS) {
965 			status = NXP_WIFI_RET_FAIL;
966 		}
967 	}
968 
969 	if (status != NXP_WIFI_RET_SUCCESS) {
970 		LOG_ERR("Failed to disconnect from AP");
971 		wifi_mgmt_raise_disconnect_result_event(g_mlan.netif, -1);
972 		return -EAGAIN;
973 	}
974 
975 	wifi_mgmt_raise_disconnect_result_event(g_mlan.netif, 0);
976 
977 	return 0;
978 }
979 
nxp_wifi_security_type(enum wlan_security_type type)980 static inline enum wifi_security_type nxp_wifi_security_type(enum wlan_security_type type)
981 {
982 	switch (type) {
983 	case WLAN_SECURITY_NONE:
984 		return WIFI_SECURITY_TYPE_NONE;
985 	case WLAN_SECURITY_WPA2:
986 		return WIFI_SECURITY_TYPE_PSK;
987 	case WLAN_SECURITY_WPA3_SAE:
988 		return WIFI_SECURITY_TYPE_SAE;
989 	default:
990 		return WIFI_SECURITY_TYPE_UNKNOWN;
991 	}
992 }
993 
994 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
nxp_wifi_uap_status(const struct device * dev,struct wifi_iface_status * status)995 static int nxp_wifi_uap_status(const struct device *dev, struct wifi_iface_status *status)
996 {
997 	enum wlan_connection_state connection_state = WLAN_UAP_STOPPED;
998 	struct interface *if_handle = (struct interface *)&g_uap;
999 
1000 	wlan_get_uap_connection_state(&connection_state);
1001 
1002 	switch (connection_state) {
1003 	case WLAN_UAP_STARTED:
1004 		status->state = WIFI_SAP_IFACE_ENABLED;
1005 		break;
1006 	case WLAN_UAP_STOPPED:
1007 		status->state = WIFI_SAP_IFACE_DISABLED;
1008 		break;
1009 	default:
1010 		status->state = WIFI_SAP_IFACE_DISABLED;
1011 		break;
1012 	}
1013 
1014 	if (connection_state == WLAN_UAP_STARTED) {
1015 
1016 		if (!wlan_get_current_uap_network(&nxp_wlan_uap_network)) {
1017 			strncpy(status->ssid, nxp_wlan_uap_network.ssid, WIFI_SSID_MAX_LEN);
1018 			status->ssid[WIFI_SSID_MAX_LEN - 1] = 0;
1019 			status->ssid_len = strlen(status->ssid);
1020 
1021 			memcpy(status->bssid, nxp_wlan_uap_network.bssid, WIFI_MAC_ADDR_LEN);
1022 
1023 			status->rssi = nxp_wlan_uap_network.rssi;
1024 
1025 			status->channel = nxp_wlan_uap_network.channel;
1026 
1027 			status->beacon_interval = nxp_wlan_uap_network.beacon_period;
1028 
1029 			status->dtim_period = nxp_wlan_uap_network.dtim_period;
1030 
1031 			if (if_handle->state.interface == WLAN_BSS_TYPE_STA) {
1032 				status->iface_mode = WIFI_MODE_INFRA;
1033 			} else if (if_handle->state.interface == WLAN_BSS_TYPE_UAP) {
1034 				status->iface_mode = WIFI_MODE_AP;
1035 			}
1036 
1037 #ifdef CONFIG_NXP_WIFI_11AX
1038 			if (nxp_wlan_uap_network.dot11ax) {
1039 				status->link_mode = WIFI_6;
1040 			}
1041 #endif
1042 #ifdef CONFIG_NXP_WIFI_11AC
1043 			else if (nxp_wlan_uap_network.dot11ac) {
1044 				status->link_mode = WIFI_5;
1045 			}
1046 #endif
1047 			else if (nxp_wlan_uap_network.dot11n) {
1048 				status->link_mode = WIFI_4;
1049 			} else {
1050 				status->link_mode = WIFI_3;
1051 			}
1052 
1053 			status->band = nxp_wlan_uap_network.channel > 14 ? WIFI_FREQ_BAND_5_GHZ
1054 									 : WIFI_FREQ_BAND_2_4_GHZ;
1055 			status->security =
1056 				nxp_wifi_security_type(nxp_wlan_uap_network.security.type);
1057 			status->mfp =
1058 				nxp_wlan_uap_network.security.mfpr
1059 					? WIFI_MFP_REQUIRED
1060 					: (nxp_wlan_uap_network.security.mfpc ? WIFI_MFP_OPTIONAL
1061 									      : 0);
1062 		}
1063 	}
1064 
1065 	return 0;
1066 }
1067 #endif
1068 
nxp_wifi_status(const struct device * dev,struct wifi_iface_status * status)1069 static int nxp_wifi_status(const struct device *dev, struct wifi_iface_status *status)
1070 {
1071 	enum wlan_connection_state connection_state = WLAN_DISCONNECTED;
1072 	struct interface *if_handle = (struct interface *)dev->data;
1073 
1074 	wlan_get_connection_state(&connection_state);
1075 
1076 	if (s_nxp_wifi_State != NXP_WIFI_STARTED) {
1077 		status->state = WIFI_STATE_INTERFACE_DISABLED;
1078 
1079 		return 0;
1080 	}
1081 
1082 	if (connection_state == WLAN_DISCONNECTED) {
1083 		status->state = WIFI_STATE_DISCONNECTED;
1084 	} else if (connection_state == WLAN_SCANNING) {
1085 		status->state = WIFI_STATE_SCANNING;
1086 	} else if (connection_state == WLAN_ASSOCIATING) {
1087 		status->state = WIFI_STATE_ASSOCIATING;
1088 	} else if (connection_state == WLAN_ASSOCIATED) {
1089 		status->state = WIFI_STATE_ASSOCIATED;
1090 	} else if (connection_state == WLAN_AUTHENTICATED
1091 			|| connection_state == WLAN_CONNECTED) {
1092 		status->state = WIFI_STATE_COMPLETED;
1093 
1094 		if (!wlan_get_current_network(&nxp_wlan_network)) {
1095 			strncpy(status->ssid, nxp_wlan_network.ssid, WIFI_SSID_MAX_LEN - 1);
1096 			status->ssid[WIFI_SSID_MAX_LEN - 1] = '\0';
1097 			status->ssid_len = strlen(nxp_wlan_network.ssid);
1098 
1099 			memcpy(status->bssid, nxp_wlan_network.bssid, WIFI_MAC_ADDR_LEN);
1100 
1101 			status->rssi = nxp_wlan_network.rssi;
1102 
1103 			status->channel = nxp_wlan_network.channel;
1104 
1105 			status->beacon_interval = nxp_wlan_network.beacon_period;
1106 
1107 			status->dtim_period = nxp_wlan_network.dtim_period;
1108 
1109 			if (if_handle->state.interface == WLAN_BSS_TYPE_STA) {
1110 				status->iface_mode = WIFI_MODE_INFRA;
1111 			}
1112 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
1113 			else if (if_handle->state.interface == WLAN_BSS_TYPE_UAP) {
1114 				status->iface_mode = WIFI_MODE_AP;
1115 			}
1116 #endif
1117 
1118 #ifdef CONFIG_NXP_WIFI_11AX
1119 			if (nxp_wlan_network.dot11ax) {
1120 				status->link_mode = WIFI_6;
1121 			} else
1122 #endif
1123 #ifdef CONFIG_NXP_WIFI_11AC
1124 				if (nxp_wlan_network.dot11ac) {
1125 					status->link_mode = WIFI_5;
1126 			} else
1127 #endif
1128 				if (nxp_wlan_network.dot11n) {
1129 					status->link_mode = WIFI_4;
1130 			} else {
1131 				status->link_mode = WIFI_3;
1132 			}
1133 
1134 			status->band = nxp_wlan_network.channel > 14 ? WIFI_FREQ_BAND_5_GHZ
1135 								     : WIFI_FREQ_BAND_2_4_GHZ;
1136 			status->security = nxp_wifi_security_type(nxp_wlan_network.security.type);
1137 			status->mfp = nxp_wlan_network.security.mfpr ? WIFI_MFP_REQUIRED :
1138 				(nxp_wlan_network.security.mfpc ? WIFI_MFP_OPTIONAL : 0);
1139 		}
1140 	}
1141 
1142 	return 0;
1143 }
1144 
1145 #if defined(CONFIG_NET_STATISTICS_WIFI)
nxp_wifi_stats(const struct device * dev,struct net_stats_wifi * stats)1146 static int nxp_wifi_stats(const struct device *dev, struct net_stats_wifi *stats)
1147 {
1148 	struct interface *if_handle = (struct interface *)dev->data;
1149 
1150 	stats->bytes.received = if_handle->stats.bytes.received;
1151 	stats->bytes.sent = if_handle->stats.bytes.sent;
1152 	stats->pkts.rx = if_handle->stats.pkts.rx;
1153 	stats->pkts.tx = if_handle->stats.pkts.tx;
1154 	stats->errors.rx = if_handle->stats.errors.rx;
1155 	stats->errors.tx = if_handle->stats.errors.tx;
1156 	stats->broadcast.rx = if_handle->stats.broadcast.rx;
1157 	stats->broadcast.tx = if_handle->stats.broadcast.tx;
1158 	stats->multicast.rx = if_handle->stats.multicast.rx;
1159 	stats->multicast.tx = if_handle->stats.multicast.tx;
1160 	stats->sta_mgmt.beacons_rx = if_handle->stats.sta_mgmt.beacons_rx;
1161 	stats->sta_mgmt.beacons_miss = if_handle->stats.sta_mgmt.beacons_miss;
1162 
1163 	return 0;
1164 }
1165 #endif
1166 
1167 #ifdef CONFIG_NXP_WIFI_STA_AUTO_CONN
nxp_wifi_auto_connect(void)1168 static void nxp_wifi_auto_connect(void)
1169 {
1170 	int ssid_len = strlen(CONFIG_NXP_WIFI_STA_AUTO_SSID);
1171 	int psk_len = strlen(CONFIG_NXP_WIFI_STA_AUTO_PASSWORD);
1172 	struct wifi_connect_req_params params = {0};
1173 	char ssid[IEEEtypes_SSID_SIZE] = {0};
1174 	char psk[WLAN_PSK_MAX_LENGTH] = {0};
1175 
1176 	if (ssid_len >= IEEEtypes_SSID_SIZE) {
1177 		LOG_ERR("AutoConnect SSID too long");
1178 		return;
1179 	}
1180 	if (ssid_len == 0) {
1181 		LOG_ERR("AutoConnect SSID NULL");
1182 		return;
1183 	}
1184 
1185 	strcpy(ssid, CONFIG_NXP_WIFI_STA_AUTO_SSID);
1186 
1187 	if (psk_len == 0) {
1188 		params.security = WIFI_SECURITY_TYPE_NONE;
1189 	} else if (psk_len >= WLAN_PSK_MIN_LENGTH && psk_len < WLAN_PSK_MAX_LENGTH) {
1190 		strcpy(psk, CONFIG_NXP_WIFI_STA_AUTO_PASSWORD);
1191 		params.security = WIFI_SECURITY_TYPE_PSK;
1192 	} else {
1193 		LOG_ERR("AutoConnect invalid password length %d", psk_len);
1194 		return;
1195 	}
1196 
1197 	params.channel = WIFI_CHANNEL_ANY;
1198 	params.ssid = &ssid[0];
1199 	params.ssid_length = ssid_len;
1200 	params.psk = &psk[0];
1201 	params.psk_length = psk_len;
1202 
1203 	LOG_DBG("AutoConnect SSID[%s]", ssid);
1204 	nxp_wifi_connect(g_mlan.netif->if_dev->dev, &params);
1205 }
1206 #endif
1207 
1208 #ifdef CONFIG_NXP_WIFI_11K
nxp_wifi_11k_cfg(const struct device * dev,struct wifi_11k_params * params)1209 static int nxp_wifi_11k_cfg(const struct device *dev, struct wifi_11k_params *params)
1210 {
1211 	if (params->oper == WIFI_MGMT_GET) {
1212 		params->enable_11k = wlan_get_host_11k_status();
1213 	} else {
1214 		wlan_host_11k_cfg(params->enable_11k);
1215 	}
1216 
1217 	return 0;
1218 }
1219 #endif
1220 
nxp_wifi_power_save(const struct device * dev,struct wifi_ps_params * params)1221 static int nxp_wifi_power_save(const struct device *dev, struct wifi_ps_params *params)
1222 {
1223 	int status = NXP_WIFI_RET_SUCCESS;
1224 	int ret = WM_SUCCESS;
1225 	uint32_t syncBit;
1226 	struct interface *if_handle = (struct interface *)dev->data;
1227 
1228 	if (if_handle->state.interface != WLAN_BSS_TYPE_STA) {
1229 		LOG_ERR("Wi-Fi not in station mode");
1230 		return -EIO;
1231 	}
1232 
1233 	if (s_nxp_wifi_State != NXP_WIFI_STARTED) {
1234 		status = NXP_WIFI_RET_NOT_READY;
1235 	}
1236 
1237 	if (status == NXP_WIFI_RET_SUCCESS) {
1238 
1239 		switch (params->type) {
1240 		case WIFI_PS_PARAM_STATE:
1241 			if (params->enabled == WIFI_PS_DISABLED) {
1242 				k_event_clear(&s_nxp_wifi_SyncEvent, NXP_WIFI_SYNC_PS_GROUP);
1243 				ret = wlan_deepsleepps_off();
1244 				if (ret != WM_SUCCESS) {
1245 					status = NXP_WIFI_RET_FAIL;
1246 				}
1247 
1248 				if (status == NXP_WIFI_RET_SUCCESS) {
1249 					syncBit = k_event_wait(&s_nxp_wifi_SyncEvent,
1250 							       NXP_WIFI_SYNC_PS_GROUP, false,
1251 							       NXP_WIFI_SYNC_TIMEOUT_MS);
1252 					k_event_clear(&s_nxp_wifi_SyncEvent,
1253 						      NXP_WIFI_SYNC_PS_GROUP);
1254 					if (syncBit & NXP_WIFI_EVENT_BIT(WLAN_REASON_PS_EXIT)) {
1255 						status = NXP_WIFI_RET_SUCCESS;
1256 					} else {
1257 						status = NXP_WIFI_RET_TIMEOUT;
1258 					}
1259 				}
1260 
1261 				if (status != NXP_WIFI_RET_SUCCESS) {
1262 					LOG_DBG("Wi-Fi power save is already disabled");
1263 					return -EAGAIN;
1264 				}
1265 
1266 				k_event_clear(&s_nxp_wifi_SyncEvent, NXP_WIFI_SYNC_PS_GROUP);
1267 				ret = wlan_ieeeps_off();
1268 				if (ret != WM_SUCCESS) {
1269 					status = NXP_WIFI_RET_FAIL;
1270 				}
1271 
1272 				if (status == NXP_WIFI_RET_SUCCESS) {
1273 					syncBit = k_event_wait(&s_nxp_wifi_SyncEvent,
1274 							       NXP_WIFI_SYNC_PS_GROUP, false,
1275 							       NXP_WIFI_SYNC_TIMEOUT_MS);
1276 					k_event_clear(&s_nxp_wifi_SyncEvent,
1277 						      NXP_WIFI_SYNC_PS_GROUP);
1278 					if (syncBit & NXP_WIFI_EVENT_BIT(WLAN_REASON_PS_EXIT)) {
1279 						status = NXP_WIFI_RET_SUCCESS;
1280 					} else {
1281 						status = NXP_WIFI_RET_TIMEOUT;
1282 					}
1283 				}
1284 
1285 				if (status != NXP_WIFI_RET_SUCCESS) {
1286 					LOG_DBG("Wi-Fi power save is already disabled");
1287 					return -EAGAIN;
1288 				}
1289 			} else if (params->enabled == WIFI_PS_ENABLED) {
1290 				k_event_clear(&s_nxp_wifi_SyncEvent, NXP_WIFI_SYNC_PS_GROUP);
1291 				ret = wlan_deepsleepps_on();
1292 				if (ret != WM_SUCCESS) {
1293 					status = NXP_WIFI_RET_FAIL;
1294 				}
1295 
1296 				if (status == NXP_WIFI_RET_SUCCESS) {
1297 					syncBit = k_event_wait(&s_nxp_wifi_SyncEvent,
1298 							       NXP_WIFI_SYNC_PS_GROUP, false,
1299 							       NXP_WIFI_SYNC_TIMEOUT_MS);
1300 					k_event_clear(&s_nxp_wifi_SyncEvent,
1301 						      NXP_WIFI_SYNC_PS_GROUP);
1302 					if (syncBit & NXP_WIFI_EVENT_BIT(WLAN_REASON_PS_ENTER)) {
1303 						status = NXP_WIFI_RET_SUCCESS;
1304 					} else {
1305 						status = NXP_WIFI_RET_TIMEOUT;
1306 					}
1307 				}
1308 
1309 				if (status != NXP_WIFI_RET_SUCCESS) {
1310 					LOG_DBG("Wi-Fi power save is already enabled");
1311 					return -EAGAIN;
1312 				}
1313 
1314 				k_event_clear(&s_nxp_wifi_SyncEvent, NXP_WIFI_SYNC_PS_GROUP);
1315 				ret = wlan_ieeeps_on((unsigned int)WAKE_ON_UNICAST |
1316 						     (unsigned int)WAKE_ON_MAC_EVENT |
1317 						     (unsigned int)WAKE_ON_MULTICAST |
1318 						     (unsigned int)WAKE_ON_ARP_BROADCAST);
1319 
1320 				if (ret != WM_SUCCESS) {
1321 					status = NXP_WIFI_RET_FAIL;
1322 				}
1323 
1324 				if (status == NXP_WIFI_RET_SUCCESS) {
1325 					syncBit = k_event_wait(&s_nxp_wifi_SyncEvent,
1326 							       NXP_WIFI_SYNC_PS_GROUP, false,
1327 							       NXP_WIFI_SYNC_TIMEOUT_MS);
1328 					k_event_clear(&s_nxp_wifi_SyncEvent,
1329 						      NXP_WIFI_SYNC_PS_GROUP);
1330 					if (syncBit & NXP_WIFI_EVENT_BIT(WLAN_REASON_PS_ENTER)) {
1331 						status = NXP_WIFI_RET_SUCCESS;
1332 					} else {
1333 						status = NXP_WIFI_RET_TIMEOUT;
1334 					}
1335 				}
1336 
1337 				if (status != NXP_WIFI_RET_SUCCESS) {
1338 					LOG_DBG("Wi-Fi power save is already enabled");
1339 					return -EAGAIN;
1340 				}
1341 			}
1342 			break;
1343 		case WIFI_PS_PARAM_LISTEN_INTERVAL:
1344 			wlan_configure_listen_interval((int)params->listen_interval);
1345 			break;
1346 		case WIFI_PS_PARAM_WAKEUP_MODE:
1347 			if (params->wakeup_mode == WIFI_PS_WAKEUP_MODE_DTIM) {
1348 				wlan_configure_listen_interval(0);
1349 			}
1350 			break;
1351 		case WIFI_PS_PARAM_MODE:
1352 			if (params->mode == WIFI_PS_MODE_WMM) {
1353 				ret = wlan_set_wmm_uapsd(1);
1354 
1355 				if (ret != WM_SUCCESS) {
1356 					status = NXP_WIFI_RET_FAIL;
1357 				}
1358 			} else if (params->mode == WIFI_PS_MODE_LEGACY) {
1359 				ret = wlan_set_wmm_uapsd(0);
1360 
1361 				if (ret != WM_SUCCESS) {
1362 					status = NXP_WIFI_RET_FAIL;
1363 				}
1364 			}
1365 			break;
1366 		case WIFI_PS_PARAM_TIMEOUT:
1367 			wlan_configure_delay_to_ps((int)params->timeout_ms);
1368 			break;
1369 		default:
1370 			status = NXP_WIFI_RET_FAIL;
1371 			break;
1372 		}
1373 	}
1374 
1375 	if (status != NXP_WIFI_RET_SUCCESS) {
1376 		LOG_ERR("Failed to set Wi-Fi power save");
1377 		return -EAGAIN;
1378 	}
1379 
1380 	return 0;
1381 }
1382 
nxp_wifi_get_power_save(const struct device * dev,struct wifi_ps_config * config)1383 int nxp_wifi_get_power_save(const struct device *dev, struct wifi_ps_config *config)
1384 {
1385 	int status = NXP_WIFI_RET_SUCCESS;
1386 	struct interface *if_handle = (struct interface *)dev->data;
1387 
1388 	if (if_handle->state.interface != WLAN_BSS_TYPE_STA) {
1389 		LOG_ERR("Wi-Fi not in station mode");
1390 		return -EIO;
1391 	}
1392 
1393 	if (s_nxp_wifi_State != NXP_WIFI_STARTED) {
1394 		status = NXP_WIFI_RET_NOT_READY;
1395 	}
1396 
1397 	if (status == NXP_WIFI_RET_SUCCESS) {
1398 		if (config) {
1399 			if (wlan_is_power_save_enabled()) {
1400 				config->ps_params.enabled = WIFI_PS_ENABLED;
1401 			} else {
1402 				config->ps_params.enabled = WIFI_PS_DISABLED;
1403 			}
1404 
1405 			config->ps_params.listen_interval = wlan_get_listen_interval();
1406 
1407 			config->ps_params.timeout_ms = wlan_get_delay_to_ps();
1408 			if (config->ps_params.listen_interval) {
1409 				config->ps_params.wakeup_mode = WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL;
1410 			} else {
1411 				config->ps_params.wakeup_mode = WIFI_PS_WAKEUP_MODE_DTIM;
1412 			}
1413 
1414 			if (wlan_is_wmm_uapsd_enabled()) {
1415 				config->ps_params.mode = WIFI_PS_MODE_WMM;
1416 			} else {
1417 				config->ps_params.mode = WIFI_PS_MODE_LEGACY;
1418 			}
1419 		} else {
1420 			status = NXP_WIFI_RET_FAIL;
1421 		}
1422 	}
1423 
1424 	if (status != NXP_WIFI_RET_SUCCESS) {
1425 		LOG_ERR("Failed to get Wi-Fi power save config");
1426 		return -EAGAIN;
1427 	}
1428 
1429 	return 0;
1430 }
1431 
nxp_wifi_reg_domain(const struct device * dev,struct wifi_reg_domain * reg_domain)1432 static int nxp_wifi_reg_domain(const struct device *dev, struct wifi_reg_domain *reg_domain)
1433 {
1434 	int ret;
1435 	uint8_t index = 0;
1436 	chan_freq_power_t *nxp_wifi_chan_freq_power = NULL;
1437 	int nxp_wifi_cfp_no = 0;
1438 
1439 	if (reg_domain->oper == WIFI_MGMT_GET) {
1440 		nxp_wifi_chan_freq_power = (chan_freq_power_t *)wlan_get_regulatory_domain(0,
1441 				&nxp_wifi_cfp_no);
1442 		if (nxp_wifi_chan_freq_power != NULL) {
1443 			for (int i = 0; i < nxp_wifi_cfp_no; i++) {
1444 				reg_domain->chan_info[i].center_frequency =
1445 					nxp_wifi_chan_freq_power[i].freq;
1446 				reg_domain->chan_info[i].max_power =
1447 					nxp_wifi_chan_freq_power[i].max_tx_power;
1448 				reg_domain->chan_info[i].supported = 1;
1449 				reg_domain->chan_info[i].passive_only =
1450 					nxp_wifi_chan_freq_power[i].passive_scan_or_radar_detect;
1451 				reg_domain->chan_info[i].dfs =
1452 					nxp_wifi_chan_freq_power[i].passive_scan_or_radar_detect;
1453 			}
1454 			index = nxp_wifi_cfp_no;
1455 		}
1456 
1457 		nxp_wifi_chan_freq_power = (chan_freq_power_t *)wlan_get_regulatory_domain(1,
1458 				&nxp_wifi_cfp_no);
1459 		if (nxp_wifi_chan_freq_power != NULL) {
1460 			for (int i = 0; i < nxp_wifi_cfp_no; i++) {
1461 				reg_domain->chan_info[index + i].center_frequency =
1462 					nxp_wifi_chan_freq_power[i].freq;
1463 				reg_domain->chan_info[index + i].max_power =
1464 					nxp_wifi_chan_freq_power[i].max_tx_power;
1465 				reg_domain->chan_info[index + i].supported = 1;
1466 				reg_domain->chan_info[index + i].passive_only =
1467 					nxp_wifi_chan_freq_power[i].passive_scan_or_radar_detect;
1468 				reg_domain->chan_info[index + i].dfs =
1469 					nxp_wifi_chan_freq_power[i].passive_scan_or_radar_detect;
1470 			}
1471 			index += nxp_wifi_cfp_no;
1472 		}
1473 		reg_domain->num_channels = index;
1474 		wifi_get_country_code(reg_domain->country_code);
1475 	} else {
1476 		if (is_uap_started()) {
1477 			LOG_ERR("region code can not be set after uAP start!");
1478 			return -EAGAIN;
1479 		}
1480 
1481 		ret = wlan_set_country_code(reg_domain->country_code);
1482 		if (ret != WM_SUCCESS) {
1483 			LOG_ERR("Unable to set country code: %s", reg_domain->country_code);
1484 			return -EAGAIN;
1485 		}
1486 	}
1487 	return 0;
1488 }
1489 
1490 #ifdef CONFIG_NXP_WIFI_11AX_TWT
nxp_wifi_set_twt(const struct device * dev,struct wifi_twt_params * params)1491 static int nxp_wifi_set_twt(const struct device *dev, struct wifi_twt_params *params)
1492 {
1493 	wlan_twt_setup_config_t twt_setup_conf;
1494 	wlan_twt_teardown_config_t teardown_conf;
1495 	int ret = -1;
1496 
1497 	if (params->negotiation_type == WIFI_TWT_INDIVIDUAL) {
1498 		params->negotiation_type = 0;
1499 	} else if (params->negotiation_type == WIFI_TWT_BROADCAST) {
1500 		params->negotiation_type = 3;
1501 	}
1502 
1503 	if (params->operation == WIFI_TWT_SETUP) {
1504 		twt_setup_conf.implicit = params->setup.implicit;
1505 		twt_setup_conf.announced = params->setup.announce;
1506 		twt_setup_conf.trigger_enabled = params->setup.trigger;
1507 		twt_setup_conf.twt_info_disabled = params->setup.twt_info_disable;
1508 		twt_setup_conf.negotiation_type = params->negotiation_type;
1509 		twt_setup_conf.twt_wakeup_duration = params->setup.twt_wake_interval;
1510 		twt_setup_conf.flow_identifier = params->flow_id;
1511 		twt_setup_conf.hard_constraint = 1;
1512 		twt_setup_conf.twt_exponent = params->setup.twt_exponent;
1513 		twt_setup_conf.twt_mantissa = params->setup.twt_mantissa;
1514 		twt_setup_conf.twt_request = params->setup.responder;
1515 		ret = wlan_set_twt_setup_cfg(&twt_setup_conf);
1516 	} else if (params->operation == WIFI_TWT_TEARDOWN) {
1517 		teardown_conf.flow_identifier = params->flow_id;
1518 		teardown_conf.negotiation_type = params->negotiation_type;
1519 		teardown_conf.teardown_all_twt = params->teardown.teardown_all;
1520 		ret = wlan_set_twt_teardown_cfg(&teardown_conf);
1521 	}
1522 
1523 	return ret;
1524 }
1525 
nxp_wifi_set_btwt(const struct device * dev,struct wifi_twt_params * params)1526 static int nxp_wifi_set_btwt(const struct device *dev, struct wifi_twt_params *params)
1527 {
1528 	wlan_btwt_config_t btwt_config;
1529 
1530 	btwt_config.action = 1;
1531 	btwt_config.sub_id = params->btwt.sub_id;
1532 	btwt_config.nominal_wake = params->btwt.nominal_wake;
1533 	btwt_config.max_sta_support = params->btwt.max_sta_support;
1534 	btwt_config.twt_mantissa = params->btwt.twt_mantissa;
1535 	btwt_config.twt_offset = params->btwt.twt_offset;
1536 	btwt_config.twt_exponent = params->btwt.twt_exponent;
1537 	btwt_config.sp_gap = params->btwt.sp_gap;
1538 
1539 	return wlan_set_btwt_cfg(&btwt_config);
1540 }
1541 #endif
1542 
nxp_wifi_set_rts_threshold(const struct device * dev,unsigned int rts_threshold)1543 static int nxp_wifi_set_rts_threshold(const struct device *dev, unsigned int rts_threshold)
1544 {
1545 	int ret = -1;
1546 
1547 #if CONFIG_NXP_WIFI_RTS_THRESHOLD
1548 	if (rts_threshold == -1) {
1549 		rts_threshold = MLAN_RTS_MAX_VALUE;
1550 	}
1551 
1552 	ret = wlan_set_rts(rts_threshold);
1553 #endif
1554 
1555 	return ret;
1556 }
1557 
nxp_wifi_ap_set_rts_threshold(const struct device * dev,unsigned int rts_threshold)1558 static int nxp_wifi_ap_set_rts_threshold(const struct device *dev, unsigned int rts_threshold)
1559 {
1560 	int ret = -1;
1561 
1562 #if CONFIG_NXP_WIFI_RTS_THRESHOLD
1563 	if (rts_threshold == -1) {
1564 		rts_threshold = MLAN_RTS_MAX_VALUE;
1565 	}
1566 
1567 	ret = wlan_set_uap_rts(rts_threshold);
1568 #endif
1569 
1570 	return ret;
1571 }
1572 
nxp_wifi_sta_init(struct net_if * iface)1573 static void nxp_wifi_sta_init(struct net_if *iface)
1574 {
1575 	const struct device *dev = net_if_get_device(iface);
1576 	struct ethernet_context *eth_ctx = net_if_l2_data(iface);
1577 	struct interface *intf = dev->data;
1578 
1579 	eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
1580 	intf->netif = iface;
1581 #ifdef CONFIG_WIFI_NM
1582 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
1583 	wifi_nm_register_mgd_type_iface(wifi_nm_get_instance("wifi_supplicant"),
1584 			WIFI_TYPE_STA, iface);
1585 #else
1586 	wifi_nm_register_mgd_type_iface(wifi_nm_get_instance("wifi_sta"),
1587 			WIFI_TYPE_STA, iface);
1588 #endif
1589 #endif
1590 	g_mlan.state.interface = WLAN_BSS_TYPE_STA;
1591 
1592 #ifndef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
1593 	int ret;
1594 
1595 	if (s_nxp_wifi_State == NXP_WIFI_NOT_INITIALIZED) {
1596 		/* Initialize the wifi subsystem */
1597 		ret = nxp_wifi_wlan_init();
1598 		if (ret) {
1599 			LOG_ERR("wlan initialization failed");
1600 			return;
1601 		}
1602 		ret = nxp_wifi_wlan_start();
1603 		if (ret) {
1604 			LOG_ERR("wlan start failed");
1605 			return;
1606 		}
1607 	}
1608 #endif
1609 }
1610 
1611 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
1612 
nxp_wifi_uap_init(struct net_if * iface)1613 static void nxp_wifi_uap_init(struct net_if *iface)
1614 {
1615 	const struct device *dev = net_if_get_device(iface);
1616 	struct ethernet_context *eth_ctx = net_if_l2_data(iface);
1617 	struct interface *intf = dev->data;
1618 	int ret;
1619 
1620 	eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
1621 	intf->netif = iface;
1622 
1623 #ifdef CONFIG_WIFI_NM
1624 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
1625 	wifi_nm_register_mgd_type_iface(wifi_nm_get_instance("hostapd"),
1626 			WIFI_TYPE_SAP, iface);
1627 #else
1628 	wifi_nm_register_mgd_type_iface(wifi_nm_get_instance("wifi_sap"),
1629 			WIFI_TYPE_SAP, iface);
1630 #endif
1631 #endif
1632 	g_uap.state.interface = WLAN_BSS_TYPE_UAP;
1633 
1634 	if (s_nxp_wifi_State == NXP_WIFI_NOT_INITIALIZED) {
1635 		/* Initialize the wifi subsystem */
1636 		ret = nxp_wifi_wlan_init();
1637 		if (ret) {
1638 			LOG_ERR("wlan initialization failed");
1639 			return;
1640 		}
1641 		ret = nxp_wifi_wlan_start();
1642 		if (ret) {
1643 			LOG_ERR("wlan start failed");
1644 			return;
1645 		}
1646 	}
1647 }
1648 
1649 #endif
1650 
nxp_wifi_send(const struct device * dev,struct net_pkt * pkt)1651 static NXP_WIFI_SET_FUNC_ATTR int nxp_wifi_send(const struct device *dev, struct net_pkt *pkt)
1652 {
1653 #if defined(CONFIG_NET_STATISTICS_WIFI)
1654 	struct interface *if_handle = (struct interface *)dev->data;
1655 	const int pkt_len = net_pkt_get_len(pkt);
1656 	struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);
1657 #endif
1658 
1659 	/* Enqueue packet for transmission */
1660 	if (nxp_wifi_internal_tx(dev, pkt) != WM_SUCCESS) {
1661 		goto out;
1662 	}
1663 
1664 #if defined(CONFIG_NET_STATISTICS_WIFI)
1665 	if_handle->stats.bytes.sent += pkt_len;
1666 	if_handle->stats.pkts.tx++;
1667 
1668 	if (net_eth_is_addr_multicast(&hdr->dst)) {
1669 		if_handle->stats.multicast.tx++;
1670 	} else if (net_eth_is_addr_broadcast(&hdr->dst)) {
1671 		if_handle->stats.broadcast.tx++;
1672 	}
1673 #endif
1674 
1675 	return 0;
1676 
1677 out:
1678 #if defined(CONFIG_NET_STATISTICS_WIFI)
1679 	if_handle->stats.errors.tx++;
1680 #endif
1681 	return -EIO;
1682 }
1683 
nxp_wifi_recv(struct net_if * iface,struct net_pkt * pkt)1684 static NXP_WIFI_SET_FUNC_ATTR int nxp_wifi_recv(struct net_if *iface, struct net_pkt *pkt)
1685 {
1686 #if defined(CONFIG_NET_STATISTICS_WIFI)
1687 	struct interface *if_handle = (struct interface *)(net_if_get_device(iface)->data);
1688 	const int pkt_len = net_pkt_get_len(pkt);
1689 	struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);
1690 #endif
1691 
1692 	if (net_recv_data(iface, pkt) < 0) {
1693 		goto out;
1694 	}
1695 
1696 #if defined(CONFIG_NET_STATISTICS_WIFI)
1697 	if (net_eth_is_addr_broadcast(&hdr->dst)) {
1698 		if_handle->stats.broadcast.rx++;
1699 	} else if (net_eth_is_addr_multicast(&hdr->dst)) {
1700 		if_handle->stats.multicast.rx++;
1701 	}
1702 
1703 	if_handle->stats.bytes.received += pkt_len;
1704 	if_handle->stats.pkts.rx++;
1705 #endif
1706 
1707 	return 0;
1708 
1709 out:
1710 #if defined(CONFIG_NET_STATISTICS_WIFI)
1711 	if_handle->stats.errors.rx++;
1712 #endif
1713 	return -EIO;
1714 }
1715 
1716 #ifdef CONFIG_NXP_RW610
1717 extern void WL_MCI_WAKEUP0_DriverIRQHandler(void);
1718 extern void WL_MCI_WAKEUP_DONE0_DriverIRQHandler(void);
1719 #endif
1720 
nxp_wifi_dev_init(const struct device * dev)1721 static int nxp_wifi_dev_init(const struct device *dev)
1722 {
1723 	struct nxp_wifi_dev *nxp_wifi = &nxp_wifi0;
1724 
1725 	k_mutex_init(&nxp_wifi->mutex);
1726 
1727 	nxp_wifi_shell_register(nxp_wifi);
1728 
1729 #ifdef CONFIG_NXP_RW610
1730 	IRQ_CONNECT(IMU_IRQ_N, IMU_IRQ_P, WL_MCI_WAKEUP0_DriverIRQHandler, 0, 0);
1731 	irq_enable(IMU_IRQ_N);
1732 	IRQ_CONNECT(IMU_WAKEUP_IRQ_N, IMU_WAKEUP_IRQ_P, WL_MCI_WAKEUP_DONE0_DriverIRQHandler, 0, 0);
1733 	irq_enable(IMU_WAKEUP_IRQ_N);
1734 #if (DT_INST_PROP(0, wakeup_source))
1735 	EnableDeepSleepIRQ(IMU_IRQ_N);
1736 #endif
1737 #endif
1738 
1739 	return 0;
1740 }
1741 
nxp_wifi_set_config(const struct device * dev,enum ethernet_config_type type,const struct ethernet_config * config)1742 static int nxp_wifi_set_config(const struct device *dev, enum ethernet_config_type type,
1743 			       const struct ethernet_config *config)
1744 {
1745 	struct interface *if_handle = (struct interface *)dev->data;
1746 
1747 	switch (type) {
1748 	case ETHERNET_CONFIG_TYPE_MAC_ADDRESS:
1749 		memcpy(if_handle->mac_address, config->mac_address.addr, 6);
1750 
1751 		net_if_set_link_addr(if_handle->netif, if_handle->mac_address,
1752 				     sizeof(if_handle->mac_address), NET_LINK_ETHERNET);
1753 
1754 		if (if_handle->state.interface == WLAN_BSS_TYPE_STA) {
1755 			if (wlan_set_sta_mac_addr(if_handle->mac_address)) {
1756 				LOG_ERR("Failed to set Wi-Fi MAC Address");
1757 				return -ENOEXEC;
1758 			}
1759 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
1760 		} else if (if_handle->state.interface == WLAN_BSS_TYPE_UAP) {
1761 			if (wlan_set_uap_mac_addr(if_handle->mac_address)) {
1762 				LOG_ERR("Failed to set Wi-Fi MAC Address");
1763 				return -ENOEXEC;
1764 			}
1765 #endif
1766 		} else {
1767 			LOG_ERR("Invalid Interface index");
1768 			return -ENOEXEC;
1769 		}
1770 		break;
1771 	default:
1772 		return -ENOTSUP;
1773 	}
1774 
1775 	return 0;
1776 }
1777 
1778 #if defined(CONFIG_PM_DEVICE) && defined(CONFIG_NXP_RW610)
device_pm_dump_wakeup_source(void)1779 void device_pm_dump_wakeup_source(void)
1780 {
1781 	if (POWER_GetWakeupStatus(IMU_IRQ_N)) {
1782 		LOG_INF("Wakeup by WLAN");
1783 		POWER_ClearWakeupStatus(IMU_IRQ_N);
1784 	} else if (POWER_GetWakeupStatus(41)) {
1785 		LOG_INF("Wakeup by OSTIMER");
1786 		POWER_ClearWakeupStatus(41);
1787 	} else if (POWER_GetWakeupStatus(32)) {
1788 		LOG_INF("Wakeup by RTC");
1789 		POWER_ClearWakeupStatus(32);
1790 	}
1791 }
1792 
device_wlan_pm_action(const struct device * dev,enum pm_device_action pm_action)1793 static int device_wlan_pm_action(const struct device *dev, enum pm_device_action pm_action)
1794 {
1795 	int ret = 0;
1796 
1797 	switch (pm_action) {
1798 	case PM_DEVICE_ACTION_SUSPEND:
1799 		if (!wlan_host_sleep_state || !wlan_is_started() || wakelock_isheld()
1800 #ifdef CONFIG_NXP_WIFI_WMM_UAPSD
1801 		    || wlan_is_wmm_uapsd_enabled()
1802 #endif
1803 		)
1804 			return -EBUSY;
1805 		/*
1806 		 * Trigger host sleep handshake here. Before handshake is done, host is not allowed
1807 		 * to enter low power mode
1808 		 */
1809 		if (!is_hs_handshake_done) {
1810 			is_hs_handshake_done = WLAN_HOSTSLEEP_IN_PROCESS;
1811 			ret = wlan_hs_send_event(HOST_SLEEP_HANDSHAKE, NULL);
1812 			if (ret != 0) {
1813 				return -EFAULT;
1814 			}
1815 			return -EBUSY;
1816 		}
1817 		if (is_hs_handshake_done == WLAN_HOSTSLEEP_IN_PROCESS) {
1818 			return -EBUSY;
1819 		}
1820 		if (is_hs_handshake_done == WLAN_HOSTSLEEP_FAIL) {
1821 			is_hs_handshake_done = 0;
1822 			return -EFAULT;
1823 		}
1824 		break;
1825 	case PM_DEVICE_ACTION_RESUME:
1826 		/*
1827 		 * Cancel host sleep in firmware and dump wakekup source.
1828 		 * If sleep state is periodic, start timer to keep host in full power state for 5s.
1829 		 * User can use this time to issue other commands.
1830 		 */
1831 		if (is_hs_handshake_done == WLAN_HOSTSLEEP_SUCCESS) {
1832 			ret = wlan_hs_send_event(HOST_SLEEP_EXIT, NULL);
1833 			if (ret != 0) {
1834 				return -EFAULT;
1835 			}
1836 			device_pm_dump_wakeup_source();
1837 			/* reset hs hanshake flag after waking up */
1838 			is_hs_handshake_done = 0;
1839 			if (wlan_host_sleep_state == HOST_SLEEP_ONESHOT) {
1840 				wlan_host_sleep_state = HOST_SLEEP_DISABLE;
1841 			}
1842 		}
1843 		break;
1844 	default:
1845 		break;
1846 	}
1847 	return ret;
1848 }
1849 
1850 PM_DEVICE_DT_INST_DEFINE(0, device_wlan_pm_action);
1851 #endif
1852 
1853 static const struct wifi_mgmt_ops nxp_wifi_sta_mgmt = {
1854 	.get_version = nxp_wifi_version,
1855 	.scan = nxp_wifi_scan,
1856 	.connect = nxp_wifi_connect,
1857 	.disconnect = nxp_wifi_disconnect,
1858 	.reg_domain = nxp_wifi_reg_domain,
1859 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
1860 	.ap_enable = nxp_wifi_start_ap,
1861 	.ap_disable = nxp_wifi_stop_ap,
1862 #endif
1863 	.iface_status = nxp_wifi_status,
1864 #if defined(CONFIG_NET_STATISTICS_WIFI)
1865 	.get_stats = nxp_wifi_stats,
1866 #endif
1867 #ifdef CONFIG_NXP_WIFI_11K
1868 	.cfg_11k = nxp_wifi_11k_cfg,
1869 #endif
1870 	.set_power_save = nxp_wifi_power_save,
1871 	.get_power_save_config = nxp_wifi_get_power_save,
1872 #ifdef CONFIG_NXP_WIFI_11AX_TWT
1873 	.set_twt = nxp_wifi_set_twt,
1874 #endif
1875 	.set_rts_threshold = nxp_wifi_set_rts_threshold,
1876 };
1877 
1878 #if defined(CONFIG_WIFI_NM) && !defined(CONFIG_WIFI_NM_WPA_SUPPLICANT)
1879 DEFINE_WIFI_NM_INSTANCE(wifi_sta, &nxp_wifi_sta_mgmt);
1880 #endif
1881 
1882 #if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT)
1883 static const struct zep_wpa_supp_dev_ops nxp_wifi_drv_ops = {
1884 	.init = wifi_nxp_wpa_supp_dev_init,
1885 	.deinit                   = wifi_nxp_wpa_supp_dev_deinit,
1886 	.scan2                    = wifi_nxp_wpa_supp_scan2,
1887 	.scan_abort               = wifi_nxp_wpa_supp_scan_abort,
1888 	.get_scan_results2        = wifi_nxp_wpa_supp_scan_results_get,
1889 	.deauthenticate           = wifi_nxp_wpa_supp_deauthenticate,
1890 	.authenticate             = wifi_nxp_wpa_supp_authenticate,
1891 	.associate                = wifi_nxp_wpa_supp_associate,
1892 	.set_key                  = wifi_nxp_wpa_supp_set_key,
1893 	.set_supp_port            = wifi_nxp_wpa_supp_set_supp_port,
1894 	.signal_poll              = wifi_nxp_wpa_supp_signal_poll,
1895 	.send_mlme                = wifi_nxp_wpa_supp_send_mlme,
1896 	.get_wiphy                = wifi_nxp_wpa_supp_get_wiphy,
1897 	.get_capa                 = wifi_nxp_wpa_supp_get_capa,
1898 	.get_conn_info            = wifi_nxp_wpa_supp_get_conn_info,
1899 	.set_country              = wifi_nxp_wpa_supp_set_country,
1900 	.get_country              = wifi_nxp_wpa_supp_get_country,
1901 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
1902 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
1903 	.hapd_init                = wifi_nxp_hostapd_dev_init,
1904 	.hapd_deinit              = wifi_nxp_hostapd_dev_deinit,
1905 #endif
1906 	.init_ap                  = wifi_nxp_wpa_supp_init_ap,
1907 	.set_ap                   = wifi_nxp_hostapd_set_ap,
1908 	.stop_ap                  = wifi_nxp_hostapd_stop_ap,
1909 	.sta_remove               = wifi_nxp_hostapd_sta_remove,
1910 	.sta_add                  = wifi_nxp_hostapd_sta_add,
1911 	.do_acs                   = wifi_nxp_hostapd_do_acs,
1912 #endif
1913 	.dpp_listen               = wifi_nxp_wpa_dpp_listen,
1914 	.remain_on_channel        = wifi_nxp_wpa_supp_remain_on_channel,
1915 	.cancel_remain_on_channel = wifi_nxp_wpa_supp_cancel_remain_on_channel,
1916 	.send_action_cancel_wait  = wifi_nxp_wpa_supp_cancel_action_wait,
1917 };
1918 #endif
1919 
1920 static const struct net_wifi_mgmt_offload nxp_wifi_sta_apis = {
1921 	.wifi_iface.iface_api.init = nxp_wifi_sta_init,
1922 	.wifi_iface.set_config = nxp_wifi_set_config,
1923 	.wifi_iface.send = nxp_wifi_send,
1924 	.wifi_mgmt_api = &nxp_wifi_sta_mgmt,
1925 #if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT)
1926 	.wifi_drv_ops = &nxp_wifi_drv_ops,
1927 #endif
1928 };
1929 
1930 NET_DEVICE_INIT_INSTANCE(wifi_nxp_sta, "ml", 0, nxp_wifi_dev_init, PM_DEVICE_DT_INST_GET(0),
1931 			 &g_mlan,
1932 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
1933 			 &wpa_supp_ops,
1934 #else
1935 			 NULL,
1936 #endif
1937 			 CONFIG_WIFI_INIT_PRIORITY, &nxp_wifi_sta_apis, ETHERNET_L2,
1938 			 NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
1939 
1940 #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT
1941 static const struct wifi_mgmt_ops nxp_wifi_uap_mgmt = {
1942 	.ap_enable = nxp_wifi_start_ap,
1943 	.ap_disable = nxp_wifi_stop_ap,
1944 	.iface_status = nxp_wifi_uap_status,
1945 #if defined(CONFIG_NET_STATISTICS_WIFI)
1946 	.get_stats = nxp_wifi_stats,
1947 #endif
1948 	.set_power_save = nxp_wifi_power_save,
1949 	.get_power_save_config = nxp_wifi_get_power_save,
1950 	.ap_config_params = nxp_wifi_ap_config_params,
1951 #ifdef CONFIG_NXP_WIFI_11AX_TWT
1952 	.set_btwt = nxp_wifi_set_btwt,
1953 #endif
1954 	.set_rts_threshold = nxp_wifi_ap_set_rts_threshold,
1955 };
1956 
1957 #if defined(CONFIG_WIFI_NM) && !defined(CONFIG_WIFI_NM_HOSTAPD_AP)
1958 DEFINE_WIFI_NM_INSTANCE(wifi_sap, &nxp_wifi_uap_mgmt);
1959 #endif
1960 
1961 static const struct net_wifi_mgmt_offload nxp_wifi_uap_apis = {
1962 	.wifi_iface.iface_api.init = nxp_wifi_uap_init,
1963 	.wifi_iface.set_config = nxp_wifi_set_config,
1964 	.wifi_iface.send = nxp_wifi_send,
1965 	.wifi_mgmt_api = &nxp_wifi_uap_mgmt,
1966 #if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT)
1967 	.wifi_drv_ops = &nxp_wifi_drv_ops,
1968 #endif
1969 };
1970 
1971 NET_DEVICE_INIT_INSTANCE(wifi_nxp_uap, "ua", 1, NULL, NULL, &g_uap,
1972 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT
1973 			 &wpa_supp_ops,
1974 #else
1975 			 NULL,
1976 #endif
1977 			 CONFIG_WIFI_INIT_PRIORITY, &nxp_wifi_uap_apis, ETHERNET_L2,
1978 			 NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
1979 #endif
1980