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