1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @brief File containing WPA supplicant interface specific definitions for the
9  * Zephyr OS layer of the Wi-Fi driver.
10  */
11 #include <stdlib.h>
12 
13 #include <zephyr/device.h>
14 #include <zephyr/logging/log.h>
15 
16 #include "fmac_main.h"
17 #include "common/fmac_util.h"
18 #include "wifi_mgmt.h"
19 #include "wpa_supp_if.h"
20 
21 LOG_MODULE_DECLARE(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL);
22 
23 K_SEM_DEFINE(wait_for_event_sem, 0, 1);
24 K_SEM_DEFINE(wait_for_scan_resp_sem, 0, 1);
25 static K_MUTEX_DEFINE(mgmt_tx_lock);
26 
27 #define ACTION_FRAME_RESP_TIMEOUT_MS 5000
28 #define SET_IFACE_EVENT_TIMEOUT_MS 5000
29 #define CARR_ON_TIMEOUT_MS 5000
30 
get_nrf_wifi_auth_type(int wpa_auth_alg)31 static int get_nrf_wifi_auth_type(int wpa_auth_alg)
32 {
33 	if (wpa_auth_alg & WPA_AUTH_ALG_OPEN) {
34 		return NRF_WIFI_AUTHTYPE_OPEN_SYSTEM;
35 	}
36 	if (wpa_auth_alg & WPA_AUTH_ALG_SHARED) {
37 		return NRF_WIFI_AUTHTYPE_SHARED_KEY;
38 	}
39 	if (wpa_auth_alg & WPA_AUTH_ALG_LEAP) {
40 		return NRF_WIFI_AUTHTYPE_NETWORK_EAP;
41 	}
42 	if (wpa_auth_alg & WPA_AUTH_ALG_FT) {
43 		return NRF_WIFI_AUTHTYPE_FT;
44 	}
45 	if (wpa_auth_alg & WPA_AUTH_ALG_SAE) {
46 		return NRF_WIFI_AUTHTYPE_SAE;
47 	}
48 
49 	return NRF_WIFI_AUTHTYPE_MAX;
50 }
51 
wpa_alg_to_cipher_suite(enum wpa_alg alg,size_t key_len)52 static unsigned int wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
53 {
54 	switch (alg) {
55 	case WPA_ALG_WEP:
56 		if (key_len == 5) {
57 			return RSN_CIPHER_SUITE_WEP40;
58 		}
59 		return RSN_CIPHER_SUITE_WEP104;
60 	case WPA_ALG_TKIP:
61 		return RSN_CIPHER_SUITE_TKIP;
62 	case WPA_ALG_CCMP:
63 		return RSN_CIPHER_SUITE_CCMP;
64 	case WPA_ALG_GCMP:
65 		return RSN_CIPHER_SUITE_GCMP;
66 	case WPA_ALG_CCMP_256:
67 		return RSN_CIPHER_SUITE_CCMP_256;
68 	case WPA_ALG_GCMP_256:
69 		return RSN_CIPHER_SUITE_GCMP_256;
70 	case WPA_ALG_BIP_CMAC_128:
71 		return RSN_CIPHER_SUITE_AES_128_CMAC;
72 	case WPA_ALG_BIP_GMAC_128:
73 		return RSN_CIPHER_SUITE_BIP_GMAC_128;
74 	case WPA_ALG_BIP_GMAC_256:
75 		return RSN_CIPHER_SUITE_BIP_GMAC_256;
76 	case WPA_ALG_BIP_CMAC_256:
77 		return RSN_CIPHER_SUITE_BIP_CMAC_256;
78 	case WPA_ALG_SMS4:
79 		return RSN_CIPHER_SUITE_SMS4;
80 	case WPA_ALG_KRK:
81 		return RSN_CIPHER_SUITE_KRK;
82 	case WPA_ALG_NONE:
83 		LOG_ERR("%s: Unexpected encryption algorithm %d", __func__, alg);
84 		return 0;
85 	}
86 
87 	LOG_ERR("%s: Unsupported encryption algorithm %d", __func__, alg);
88 	return 0;
89 }
90 
drv2supp_chan_width(int width)91 static enum chan_width drv2supp_chan_width(int width)
92 {
93 	switch (width) {
94 	case NRF_WIFI_CHAN_WIDTH_20_NOHT:
95 		return CHAN_WIDTH_20_NOHT;
96 	case NRF_WIFI_CHAN_WIDTH_20:
97 		return CHAN_WIDTH_20;
98 	case NRF_WIFI_CHAN_WIDTH_40:
99 		return CHAN_WIDTH_40;
100 	case NRF_WIFI_CHAN_WIDTH_80:
101 		return CHAN_WIDTH_80;
102 	case NRF_WIFI_CHAN_WIDTH_80P80:
103 		return CHAN_WIDTH_80P80;
104 	case NRF_WIFI_CHAN_WIDTH_160:
105 		return CHAN_WIDTH_160;
106 	default:
107 		break;
108 	}
109 	return CHAN_WIDTH_UNKNOWN;
110 }
111 
nrf_wifi_wpa_supp_event_proc_scan_start(void * if_priv)112 void nrf_wifi_wpa_supp_event_proc_scan_start(void *if_priv)
113 {
114 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
115 
116 	vif_ctx_zep = if_priv;
117 
118 	if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.scan_start) {
119 		vif_ctx_zep->supp_callbk_fns.scan_start(vif_ctx_zep->supp_drv_if_ctx);
120 	}
121 }
122 
nrf_wifi_wpa_supp_event_proc_scan_done(void * if_priv,struct nrf_wifi_umac_event_trigger_scan * scan_done_event,unsigned int event_len,int aborted)123 void nrf_wifi_wpa_supp_event_proc_scan_done(void *if_priv,
124 					struct nrf_wifi_umac_event_trigger_scan *scan_done_event,
125 					unsigned int event_len,
126 					int aborted)
127 {
128 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
129 	union wpa_event_data event;
130 	struct scan_info *info = NULL;
131 
132 	vif_ctx_zep = if_priv;
133 
134 	memset(&event, 0, sizeof(event));
135 
136 	info = &event.scan_info;
137 
138 	info->aborted = aborted;
139 	info->external_scan = 0;
140 	info->nl_scan_event = 1;
141 
142 	if (vif_ctx_zep->supp_drv_if_ctx &&
143 		vif_ctx_zep->supp_callbk_fns.scan_done) {
144 		vif_ctx_zep->supp_callbk_fns.scan_done(vif_ctx_zep->supp_drv_if_ctx,
145 			&event);
146 	}
147 	k_work_cancel_delayable(&vif_ctx_zep->scan_timeout_work);
148 	vif_ctx_zep->scan_in_progress = false;
149 	k_sem_give(&wait_for_scan_resp_sem);
150 }
151 
nrf_wifi_wpa_supp_event_proc_scan_res(void * if_priv,struct nrf_wifi_umac_event_new_scan_results * scan_res,unsigned int event_len,bool more_res)152 void nrf_wifi_wpa_supp_event_proc_scan_res(void *if_priv,
153 					struct nrf_wifi_umac_event_new_scan_results *scan_res,
154 					unsigned int event_len,
155 					bool more_res)
156 {
157 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
158 	struct wpa_scan_res *r = NULL;
159 	const unsigned char *ie = NULL;
160 	const unsigned char *beacon_ie = NULL;
161 	unsigned int ie_len = 0;
162 	unsigned int beacon_ie_len = 0;
163 	unsigned char *pos = NULL;
164 
165 	vif_ctx_zep = if_priv;
166 
167 	if (scan_res->valid_fields & NRF_WIFI_EVENT_NEW_SCAN_RESULTS_IES_VALID) {
168 		ie = scan_res->ies;
169 		ie_len = scan_res->ies_len;
170 	}
171 
172 	if (scan_res->valid_fields & NRF_WIFI_EVENT_NEW_SCAN_RESULTS_BEACON_IES_VALID) {
173 		beacon_ie = scan_res->ies + scan_res->ies_len;
174 		beacon_ie_len = scan_res->beacon_ies_len;
175 	}
176 
177 	r = nrf_wifi_osal_mem_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
178 
179 	if (!r) {
180 		LOG_ERR("%s: Unable to allocate memory for scan result", __func__);
181 		return;
182 	}
183 
184 	if (scan_res->valid_fields & NRF_WIFI_EVENT_NEW_SCAN_RESULTS_MAC_ADDR_VALID) {
185 		memcpy(r->bssid, scan_res->mac_addr, ETH_ALEN);
186 	}
187 
188 	r->freq = scan_res->frequency;
189 
190 	if (scan_res->valid_fields & NRF_WIFI_EVENT_NEW_SCAN_RESULTS_BEACON_INTERVAL_VALID) {
191 		r->beacon_int = scan_res->beacon_interval;
192 	}
193 
194 	r->caps = scan_res->capability;
195 
196 	r->flags |= WPA_SCAN_NOISE_INVALID;
197 
198 	if (scan_res->signal.signal_type == NRF_WIFI_SIGNAL_TYPE_MBM) {
199 		r->level = scan_res->signal.signal.mbm_signal;
200 		r->level /= 100; /* mBm to dBm */
201 		r->flags |= (WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID);
202 	} else if (scan_res->signal.signal_type == NRF_WIFI_SIGNAL_TYPE_UNSPEC) {
203 		r->level = scan_res->signal.signal.unspec_signal;
204 		r->flags |= WPA_SCAN_QUAL_INVALID;
205 	} else {
206 		r->flags |= (WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID);
207 	}
208 
209 	if (scan_res->valid_fields & NRF_WIFI_EVENT_NEW_SCAN_RESULTS_IES_TSF_VALID) {
210 		r->tsf = scan_res->ies_tsf;
211 	}
212 
213 	if (scan_res->valid_fields & NRF_WIFI_EVENT_NEW_SCAN_RESULTS_BEACON_IES_TSF_VALID) {
214 		if (scan_res->beacon_ies_tsf > r->tsf) {
215 			r->tsf = scan_res->beacon_ies_tsf;
216 		}
217 	}
218 
219 	if (scan_res->seen_ms_ago) {
220 		r->age = scan_res->seen_ms_ago;
221 	}
222 
223 	r->ie_len = ie_len;
224 
225 	pos = (unsigned char *)(r + 1);
226 
227 	if (ie) {
228 		memcpy(pos, ie, ie_len);
229 
230 		pos += ie_len;
231 	}
232 
233 	r->beacon_ie_len = beacon_ie_len;
234 
235 	if (beacon_ie) {
236 		memcpy(pos, beacon_ie, beacon_ie_len);
237 	}
238 
239 	if (scan_res->valid_fields & NRF_WIFI_EVENT_NEW_SCAN_RESULTS_STATUS_VALID) {
240 		switch (scan_res->status) {
241 		case NRF_WIFI_BSS_STATUS_ASSOCIATED:
242 			r->flags |= WPA_SCAN_ASSOCIATED;
243 			break;
244 		default:
245 			break;
246 		}
247 	}
248 
249 	if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.scan_res) {
250 		vif_ctx_zep->supp_callbk_fns.scan_res(vif_ctx_zep->supp_drv_if_ctx, r, more_res);
251 	}
252 
253 	if (!more_res) {
254 		vif_ctx_zep->scan_in_progress = false;
255 	}
256 
257 	nrf_wifi_osal_mem_free(r);
258 }
259 
nrf_wifi_wpa_supp_event_proc_auth_resp(void * if_priv,struct nrf_wifi_umac_event_mlme * auth_resp,unsigned int event_len)260 void nrf_wifi_wpa_supp_event_proc_auth_resp(void *if_priv,
261 					    struct nrf_wifi_umac_event_mlme *auth_resp,
262 					    unsigned int event_len)
263 {
264 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
265 	union wpa_event_data event;
266 	const struct ieee80211_mgmt *mgmt = NULL;
267 	const unsigned char *frame = NULL;
268 	unsigned int frame_len = 0;
269 
270 	vif_ctx_zep = if_priv;
271 
272 	frame = auth_resp->frame.frame;
273 	frame_len = auth_resp->frame.frame_len;
274 	mgmt = (const struct ieee80211_mgmt *)frame;
275 
276 	if (frame_len < 4 + (2 * NRF_WIFI_ETH_ADDR_LEN)) {
277 		LOG_ERR("%s: MLME event too short", __func__);
278 		return;
279 	}
280 
281 
282 	if (frame_len < 24 + sizeof(mgmt->u.auth)) {
283 		LOG_ERR("%s: Authentication response frame too short", __func__);
284 		return;
285 	}
286 
287 	memset(&event, 0, sizeof(event));
288 
289 	memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
290 
291 	event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
292 
293 	event.auth.auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
294 
295 	event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
296 
297 	if (frame_len > 24 + sizeof(mgmt->u.auth)) {
298 		event.auth.ies = mgmt->u.auth.variable;
299 		event.auth.ies_len = (frame_len - 24 - sizeof(mgmt->u.auth));
300 	}
301 
302 	if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.auth_resp) {
303 		vif_ctx_zep->supp_callbk_fns.auth_resp(vif_ctx_zep->supp_drv_if_ctx, &event);
304 	}
305 }
306 
nrf_wifi_wpa_supp_event_proc_assoc_resp(void * if_priv,struct nrf_wifi_umac_event_mlme * assoc_resp,unsigned int event_len)307 void nrf_wifi_wpa_supp_event_proc_assoc_resp(void *if_priv,
308 					     struct nrf_wifi_umac_event_mlme *assoc_resp,
309 					     unsigned int event_len)
310 {
311 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
312 	union wpa_event_data event;
313 	const struct ieee80211_mgmt *mgmt = NULL;
314 	const unsigned char *frame = NULL;
315 	unsigned int frame_len = 0;
316 	unsigned short status = WLAN_STATUS_UNSPECIFIED_FAILURE;
317 
318 	vif_ctx_zep = if_priv;
319 
320 	frame = assoc_resp->frame.frame;
321 	frame_len = assoc_resp->frame.frame_len;
322 	mgmt = (const struct ieee80211_mgmt *)frame;
323 
324 	if (frame_len < 24 + sizeof(mgmt->u.assoc_resp)) {
325 		LOG_ERR("%s: Association response frame too short", __func__);
326 		return;
327 	}
328 
329 	memset(&event, 0, sizeof(event));
330 
331 	status = le_to_host16(mgmt->u.assoc_resp.status_code);
332 
333 	if (status != WLAN_STATUS_SUCCESS) {
334 		event.assoc_reject.bssid = mgmt->bssid;
335 
336 		if (frame_len > 24 + sizeof(mgmt->u.assoc_resp)) {
337 			event.assoc_reject.resp_ies = (unsigned char *)mgmt->u.assoc_resp.variable;
338 			event.assoc_reject.resp_ies_len =
339 				(frame_len - 24 - sizeof(mgmt->u.assoc_resp));
340 		}
341 
342 		event.assoc_reject.status_code = status;
343 	} else {
344 		event.assoc_info.addr = mgmt->bssid;
345 		event.assoc_info.resp_frame = frame;
346 		event.assoc_info.resp_frame_len = frame_len;
347 		event.assoc_info.freq = vif_ctx_zep->assoc_freq;
348 
349 		if (frame_len > 24 + sizeof(mgmt->u.assoc_resp)) {
350 			event.assoc_info.resp_ies = (unsigned char *)mgmt->u.assoc_resp.variable;
351 			event.assoc_info.resp_ies_len =
352 				(frame_len - 24 - sizeof(mgmt->u.assoc_resp));
353 		}
354 
355 		if (assoc_resp->req_ie_len > 0) {
356 			event.assoc_info.req_ies = (unsigned char *)assoc_resp->req_ie;
357 			event.assoc_info.req_ies_len = assoc_resp->req_ie_len;
358 		}
359 
360 	}
361 
362 	if (vif_ctx_zep->supp_drv_if_ctx &&
363 		vif_ctx_zep->supp_callbk_fns.assoc_resp) {
364 		vif_ctx_zep->supp_callbk_fns.assoc_resp(vif_ctx_zep->supp_drv_if_ctx,
365 			&event, status);
366 	}
367 }
368 
nrf_wifi_wpa_supp_event_proc_deauth(void * if_priv,struct nrf_wifi_umac_event_mlme * deauth,unsigned int event_len)369 void nrf_wifi_wpa_supp_event_proc_deauth(void *if_priv,
370 					 struct nrf_wifi_umac_event_mlme *deauth,
371 					 unsigned int event_len)
372 {
373 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
374 	union wpa_event_data event;
375 	const struct ieee80211_mgmt *mgmt = NULL;
376 	const unsigned char *frame = NULL;
377 	unsigned int frame_len = 0;
378 
379 	vif_ctx_zep = if_priv;
380 
381 	frame = deauth->frame.frame;
382 	frame_len = deauth->frame.frame_len;
383 	mgmt = (const struct ieee80211_mgmt *)frame;
384 
385 	if (frame_len < 24 + sizeof(mgmt->u.deauth)) {
386 		LOG_ERR("%s: Deauthentication frame too short", __func__);
387 		return;
388 	}
389 
390 	memset(&event, 0, sizeof(event));
391 
392 	event.deauth_info.addr = &mgmt->sa[0];
393 	event.deauth_info.reason_code = le_to_host16(mgmt->u.deauth.reason_code);
394 	if (frame + frame_len > mgmt->u.deauth.variable) {
395 		event.deauth_info.ie = mgmt->u.deauth.variable;
396 		event.deauth_info.ie_len = (frame + frame_len - mgmt->u.deauth.variable);
397 	}
398 
399 	if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.deauth) {
400 		vif_ctx_zep->supp_callbk_fns.deauth(vif_ctx_zep->supp_drv_if_ctx,
401 			&event, mgmt);
402 	}
403 }
404 
nrf_wifi_wpa_supp_event_proc_disassoc(void * if_priv,struct nrf_wifi_umac_event_mlme * disassoc,unsigned int event_len)405 void nrf_wifi_wpa_supp_event_proc_disassoc(void *if_priv,
406 					   struct nrf_wifi_umac_event_mlme *disassoc,
407 					   unsigned int event_len)
408 {
409 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
410 	union wpa_event_data event;
411 	const struct ieee80211_mgmt *mgmt = NULL;
412 	const unsigned char *frame = NULL;
413 	unsigned int frame_len = 0;
414 
415 	vif_ctx_zep = if_priv;
416 
417 	frame = disassoc->frame.frame;
418 	frame_len = disassoc->frame.frame_len;
419 	mgmt = (const struct ieee80211_mgmt *)frame;
420 
421 	if (frame_len < 24 + sizeof(mgmt->u.disassoc)) {
422 		LOG_ERR("%s: Disassociation frame too short", __func__);
423 		return;
424 	}
425 
426 	memset(&event, 0, sizeof(event));
427 
428 	event.disassoc_info.addr = &mgmt->sa[0];
429 	event.disassoc_info.reason_code = le_to_host16(mgmt->u.disassoc.reason_code);
430 	if (frame + frame_len > mgmt->u.disassoc.variable) {
431 		event.disassoc_info.ie = mgmt->u.disassoc.variable;
432 		event.disassoc_info.ie_len = (frame + frame_len - mgmt->u.disassoc.variable);
433 	}
434 
435 	if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.disassoc)	{
436 		vif_ctx_zep->supp_callbk_fns.disassoc(vif_ctx_zep->supp_drv_if_ctx, &event);
437 	}
438 
439 	(void) nrf_wifi_twt_teardown_flows(vif_ctx_zep, 0, NRF_WIFI_MAX_TWT_FLOWS);
440 }
441 
nrf_wifi_wpa_supp_dev_init(void * supp_drv_if_ctx,const char * iface_name,struct zep_wpa_supp_dev_callbk_fns * supp_callbk_fns)442 void *nrf_wifi_wpa_supp_dev_init(void *supp_drv_if_ctx, const char *iface_name,
443 				 struct zep_wpa_supp_dev_callbk_fns *supp_callbk_fns)
444 {
445 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
446 	const struct device *device = DEVICE_DT_GET(DT_CHOSEN(zephyr_wifi));
447 
448 	if (!device) {
449 		LOG_ERR("%s: Interface %s not found", __func__, iface_name);
450 		return NULL;
451 	}
452 
453 	vif_ctx_zep = device->data;
454 
455 	if (!vif_ctx_zep || !vif_ctx_zep->rpu_ctx_zep) {
456 		LOG_ERR("%s: Interface %s not properly initialized", __func__, iface_name);
457 		return NULL;
458 	}
459 
460 	/* Needed to make sure that during initialization, commands like setting regdomain
461 	 * does not access it.
462 	 */
463 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
464 	vif_ctx_zep->supp_drv_if_ctx = supp_drv_if_ctx;
465 
466 	memcpy(&vif_ctx_zep->supp_callbk_fns, supp_callbk_fns,
467 	       sizeof(vif_ctx_zep->supp_callbk_fns));
468 
469 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
470 	return vif_ctx_zep;
471 }
472 
nrf_wifi_wpa_supp_dev_deinit(void * if_priv)473 void nrf_wifi_wpa_supp_dev_deinit(void *if_priv)
474 {
475 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
476 
477 	vif_ctx_zep = if_priv;
478 
479 	vif_ctx_zep->supp_drv_if_ctx = NULL;
480 }
481 
nrf_wifi_wpa_supp_scan2(void * if_priv,struct wpa_driver_scan_params * params)482 int nrf_wifi_wpa_supp_scan2(void *if_priv, struct wpa_driver_scan_params *params)
483 {
484 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
485 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
486 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
487 	struct nrf_wifi_umac_scan_info *scan_info = NULL;
488 	int indx = 0;
489 	int ret = -1;
490 	int num_freqs = 0;
491 
492 	if (!if_priv || !params) {
493 		LOG_ERR("%s: Invalid params", __func__);
494 		return ret;
495 	}
496 
497 	vif_ctx_zep = if_priv;
498 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
499 	if (!rpu_ctx_zep->rpu_ctx) {
500 		LOG_ERR("%s: RPU context not initialized", __func__);
501 		return ret;
502 	}
503 
504 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
505 	if (!rpu_ctx_zep->rpu_ctx) {
506 		LOG_DBG("%s: RPU context not initialized", __func__);
507 		goto out;
508 	}
509 
510 	if (vif_ctx_zep->scan_in_progress) {
511 		LOG_ERR("%s: Scan already in progress", __func__);
512 		ret = -EBUSY;
513 		goto out;
514 	}
515 
516 	if (params->freqs) {
517 		for (indx = 0; params->freqs[indx]; indx++) {
518 			num_freqs++;
519 		}
520 	}
521 
522 	scan_info = nrf_wifi_osal_mem_zalloc(sizeof(*scan_info) +
523 					    (num_freqs * sizeof(unsigned int)));
524 
525 	if (!scan_info) {
526 		LOG_ERR("%s: Unable to allocate memory for scan info", __func__);
527 		ret = -ENOMEM;
528 		goto out;
529 	}
530 
531 	memset(scan_info, 0x0, sizeof(*scan_info));
532 
533 	if (params->freqs) {
534 		for (indx = 0; params->freqs[indx]; indx++) {
535 			scan_info->scan_params.center_frequency[indx] =
536 				params->freqs[indx];
537 		}
538 		scan_info->scan_params.num_scan_channels = indx;
539 	}
540 
541 	if (params->filter_ssids) {
542 		scan_info->scan_params.num_scan_ssids = params->num_filter_ssids;
543 
544 		for (indx = 0; indx < params->num_filter_ssids; indx++) {
545 			memcpy(scan_info->scan_params.scan_ssids[indx].nrf_wifi_ssid,
546 			       params->filter_ssids[indx].ssid,
547 			       params->filter_ssids[indx].ssid_len);
548 
549 			scan_info->scan_params.scan_ssids[indx].nrf_wifi_ssid_len =
550 				params->filter_ssids[indx].ssid_len;
551 		}
552 	}
553 
554 	scan_info->scan_reason = SCAN_CONNECT;
555 
556 	/* Copy extra_ies */
557 	if (params->extra_ies_len && params->extra_ies_len <= NRF_WIFI_MAX_IE_LEN) {
558 		memcpy(scan_info->scan_params.ie.ie, params->extra_ies, params->extra_ies_len);
559 		scan_info->scan_params.ie.ie_len = params->extra_ies_len;
560 	} else if (params->extra_ies_len) {
561 		LOG_ERR("%s: extra_ies_len %d is greater than max IE len %d",
562 			__func__, params->extra_ies_len, NRF_WIFI_MAX_IE_LEN);
563 		goto out;
564 	}
565 
566 	status = nrf_wifi_sys_fmac_scan(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, scan_info);
567 
568 	if (status != NRF_WIFI_STATUS_SUCCESS) {
569 		LOG_ERR("%s: Scan trigger failed", __func__);
570 		goto out;
571 	}
572 
573 	vif_ctx_zep->scan_type = SCAN_CONNECT;
574 	vif_ctx_zep->scan_in_progress = true;
575 
576 	k_work_schedule(&vif_ctx_zep->scan_timeout_work,
577 		K_SECONDS(CONFIG_WIFI_NRF70_SCAN_TIMEOUT_S));
578 
579 	ret = 0;
580 out:
581 	if (scan_info) {
582 		nrf_wifi_osal_mem_free(scan_info);
583 	}
584 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
585 	return ret;
586 }
587 
nrf_wifi_wpa_supp_scan_abort(void * if_priv)588 int nrf_wifi_wpa_supp_scan_abort(void *if_priv)
589 {
590 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
591 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
592 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
593 	int sem_ret;
594 
595 	vif_ctx_zep = if_priv;
596 	if (!vif_ctx_zep) {
597 		LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
598 		return -1;
599 	}
600 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
601 	if (!rpu_ctx_zep) {
602 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
603 		return -1;
604 	}
605 
606 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
607 	if (!rpu_ctx_zep->rpu_ctx) {
608 		LOG_DBG("%s: RPU context not initialized", __func__);
609 		goto out;
610 	}
611 
612 	if (!vif_ctx_zep->scan_in_progress) {
613 		LOG_ERR("%s:Ignore scan abort, no scan in progress", __func__);
614 		goto out;
615 	}
616 
617 	status = nrf_wifi_sys_fmac_abort_scan(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx);
618 
619 	if (status != NRF_WIFI_STATUS_SUCCESS) {
620 		LOG_ERR("%s: nrf_wifi_sys_fmac_abort_scan failed", __func__);
621 		goto out;
622 	}
623 
624 	k_sem_reset(&wait_for_scan_resp_sem);
625 	sem_ret = k_sem_take(&wait_for_scan_resp_sem, K_MSEC(RPU_RESP_EVENT_TIMEOUT));
626 	if (sem_ret) {
627 		LOG_ERR("%s: Timedout waiting for scan abort response, ret = %d",
628 			    __func__, sem_ret);
629 		status = NRF_WIFI_STATUS_FAIL;
630 		goto out;
631 	}
632 
633 out:
634 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
635 	return status;
636 }
637 
nrf_wifi_wpa_supp_scan_results_get(void * if_priv)638 int nrf_wifi_wpa_supp_scan_results_get(void *if_priv)
639 {
640 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
641 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
642 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
643 	int ret = -1;
644 
645 	if (!if_priv) {
646 		LOG_ERR("%s: Invalid params", __func__);
647 		return ret;
648 	}
649 
650 	vif_ctx_zep = if_priv;
651 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
652 	if (!rpu_ctx_zep) {
653 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
654 		return ret;
655 	}
656 
657 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
658 	if (!rpu_ctx_zep->rpu_ctx) {
659 		LOG_DBG("%s: RPU context not initialized", __func__);
660 		goto out;
661 	}
662 
663 	status = nrf_wifi_sys_fmac_scan_res_get(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx,
664 					    SCAN_CONNECT);
665 
666 	if (status != NRF_WIFI_STATUS_SUCCESS) {
667 		LOG_ERR("%s: nrf_wifi_sys_fmac_scan_res_get failed", __func__);
668 		goto out;
669 	}
670 
671 	ret = 0;
672 out:
673 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
674 	return ret;
675 }
676 
nrf_wifi_wpa_supp_deauthenticate(void * if_priv,const char * addr,unsigned short reason_code)677 int nrf_wifi_wpa_supp_deauthenticate(void *if_priv, const char *addr, unsigned short reason_code)
678 {
679 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
680 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
681 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
682 	struct nrf_wifi_umac_disconn_info deauth_info;
683 	int ret = -1;
684 
685 	if ((!if_priv) || (!addr)) {
686 		LOG_ERR("%s: Invalid params", __func__);
687 		return ret;
688 	}
689 
690 	vif_ctx_zep = if_priv;
691 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
692 	if (!rpu_ctx_zep) {
693 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
694 		return ret;
695 	}
696 
697 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
698 	if (!rpu_ctx_zep->rpu_ctx) {
699 		LOG_DBG("%s: RPU context not initialized", __func__);
700 		goto out;
701 	}
702 
703 	memset(&deauth_info, 0, sizeof(deauth_info));
704 
705 	deauth_info.reason_code = reason_code;
706 
707 	memcpy(deauth_info.mac_addr, addr, sizeof(deauth_info.mac_addr));
708 
709 	status = nrf_wifi_sys_fmac_deauth(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &deauth_info);
710 
711 	if (status != NRF_WIFI_STATUS_SUCCESS) {
712 		LOG_ERR("%s: nrf_wifi_sys_fmac_deauth failed", __func__);
713 		goto out;
714 	}
715 
716 	ret = nrf_wifi_twt_teardown_flows(vif_ctx_zep, 0, NRF_WIFI_MAX_TWT_FLOWS);
717 out:
718 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
719 	return ret;
720 }
721 
nrf_wifi_wpa_supp_add_key(struct nrf_wifi_umac_key_info * key_info,enum wpa_alg alg,int key_idx,int defkey,const unsigned char * seq,size_t seq_len,const unsigned char * key,size_t key_len)722 int nrf_wifi_wpa_supp_add_key(struct nrf_wifi_umac_key_info *key_info, enum wpa_alg alg,
723 			      int key_idx,
724 			      int defkey, const unsigned char *seq, size_t seq_len,
725 			      const unsigned char *key, size_t key_len)
726 {
727 	unsigned int suite = 0;
728 
729 	suite = wpa_alg_to_cipher_suite(alg, key_len);
730 
731 	if (!suite) {
732 		return -1;
733 	}
734 
735 	if (defkey && alg == WPA_ALG_BIP_CMAC_128) {
736 		key_info->nrf_wifi_flags = NRF_WIFI_KEY_DEFAULT_MGMT;
737 	} else if (defkey) {
738 		key_info->nrf_wifi_flags = NRF_WIFI_KEY_DEFAULT;
739 	}
740 
741 	key_info->key_idx = key_idx;
742 	key_info->cipher_suite = suite;
743 
744 	if (key && key_len) {
745 		memcpy(key_info->key.nrf_wifi_key, key, key_len);
746 		key_info->key.nrf_wifi_key_len = key_len;
747 	}
748 	if (seq && seq_len) {
749 		memcpy(key_info->seq.nrf_wifi_seq, seq, seq_len);
750 		key_info->seq.nrf_wifi_seq_len = seq_len;
751 	}
752 
753 	return 0;
754 }
755 
nrf_wifi_wpa_supp_authenticate(void * if_priv,struct wpa_driver_auth_params * params,struct wpa_bss * curr_bss)756 int nrf_wifi_wpa_supp_authenticate(void *if_priv, struct wpa_driver_auth_params *params,
757 				struct wpa_bss *curr_bss)
758 {
759 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
760 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
761 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
762 	struct nrf_wifi_umac_auth_info auth_info;
763 	int ret = -1;
764 	int type;
765 	int count = 0;
766 	int max_ie_len = 0;
767 
768 	if ((!if_priv) || (!params)) {
769 		LOG_ERR("%s: Invalid params", __func__);
770 		return ret;
771 	}
772 
773 	vif_ctx_zep = if_priv;
774 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
775 	if (!rpu_ctx_zep) {
776 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
777 		return ret;
778 	}
779 
780 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
781 	if (!rpu_ctx_zep->rpu_ctx) {
782 		LOG_DBG("%s: RPU context not initialized", __func__);
783 		goto out;
784 	}
785 
786 #ifdef CONFIG_NRF70_RAW_DATA_RX
787 	if (vif_ctx_zep->if_type == NRF_WIFI_IFTYPE_MONITOR) {
788 		LOG_ERR("%s: Interface is in Monitor mode -  cannot connect to a BSS", __func__);
789 		goto out;
790 	}
791 #endif /* CONFIG_NRF70_RAW_DATA_RX */
792 
793 	memset(&auth_info, 0, sizeof(auth_info));
794 
795 
796 	if (params->bssid) {
797 		memcpy(auth_info.nrf_wifi_bssid, params->bssid, ETH_ALEN);
798 	}
799 
800 	if (params->freq) {
801 		auth_info.frequency = params->freq;
802 	}
803 
804 	if (params->ssid) {
805 		memcpy(auth_info.ssid.nrf_wifi_ssid, params->ssid, params->ssid_len);
806 
807 		auth_info.ssid.nrf_wifi_ssid_len = params->ssid_len;
808 	}
809 
810 	if (params->ie) {
811 		max_ie_len = (params->ie_len > NRF_WIFI_MAX_IE_LEN) ?
812 			     NRF_WIFI_MAX_IE_LEN : params->ie_len;
813 		memcpy(&auth_info.ie.ie, params->ie, max_ie_len);
814 		auth_info.ie.ie_len = max_ie_len;
815 	} else {
816 		auth_info.scan_width = 0; /* hard coded */
817 		auth_info.nrf_wifi_signal = curr_bss->level;
818 		auth_info.capability = curr_bss->caps;
819 		auth_info.beacon_interval = curr_bss->beacon_int;
820 		auth_info.tsf = curr_bss->tsf;
821 		auth_info.from_beacon = 0; /* hard coded */
822 	}
823 
824 	if (params->auth_data) {
825 		auth_info.sae.sae_data_len = params->auth_data_len;
826 
827 		memcpy(auth_info.sae.sae_data, params->auth_data, params->auth_data_len);
828 	}
829 
830 	type = get_nrf_wifi_auth_type(params->auth_alg);
831 
832 	if (type != NRF_WIFI_AUTHTYPE_MAX) {
833 		auth_info.auth_type = type;
834 	}
835 
836 	if (type == NRF_WIFI_AUTHTYPE_SHARED_KEY) {
837 		size_t key_len = params->wep_key_len[params->wep_tx_keyidx];
838 		struct nrf_wifi_umac_key_info *key_info = &auth_info.key_info;
839 
840 		key_info->cipher_suite = wpa_alg_to_cipher_suite(params->auth_alg, key_len);
841 		memcpy(key_info->key.nrf_wifi_key,
842 			   params->wep_key[params->wep_tx_keyidx],
843 			   key_len);
844 		key_info->key.nrf_wifi_key_len = key_len;
845 		key_info->valid_fields |= NRF_WIFI_KEY_VALID | NRF_WIFI_KEY_IDX_VALID |
846 			NRF_WIFI_CIPHER_SUITE_VALID;
847 	}
848 
849 	if (params->local_state_change) {
850 		auth_info.nrf_wifi_flags |= NRF_WIFI_CMD_AUTHENTICATE_LOCAL_STATE_CHANGE;
851 	}
852 
853 	status = nrf_wifi_sys_fmac_auth(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &auth_info);
854 
855 	if (status != NRF_WIFI_STATUS_SUCCESS) {
856 		LOG_ERR("%s: MLME command failed (auth): count=%d ret=%d", __func__, count, ret);
857 		count++;
858 		ret = -1;
859 	} else {
860 		LOG_DBG("%s:Authentication request sent successfully", __func__);
861 		ret = 0;
862 	}
863 out:
864 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
865 	return ret;
866 }
867 
nrf_wifi_wpa_supp_associate(void * if_priv,struct wpa_driver_associate_params * params)868 int nrf_wifi_wpa_supp_associate(void *if_priv, struct wpa_driver_associate_params *params)
869 {
870 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
871 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
872 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
873 	struct nrf_wifi_umac_assoc_info assoc_info;
874 	int ret = -1;
875 
876 	if ((!if_priv) || (!params)) {
877 		LOG_ERR("%s: Invalid params", __func__);
878 		return ret;
879 	}
880 
881 	vif_ctx_zep = if_priv;
882 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
883 	if (!rpu_ctx_zep->rpu_ctx) {
884 		LOG_DBG("%s: RPU context not initialized", __func__);
885 		return ret;
886 	}
887 
888 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
889 	if (!rpu_ctx_zep->rpu_ctx) {
890 		LOG_DBG("%s: RPU context not initialized", __func__);
891 		goto out;
892 	}
893 
894 	memset(&assoc_info, 0, sizeof(assoc_info));
895 
896 	if (params->bssid) {
897 		memcpy(assoc_info.nrf_wifi_bssid, params->bssid, sizeof(assoc_info.nrf_wifi_bssid));
898 	}
899 
900 	if (params->freq.freq) {
901 		assoc_info.center_frequency = params->freq.freq;
902 		vif_ctx_zep->assoc_freq = params->freq.freq;
903 	} else {
904 		vif_ctx_zep->assoc_freq = 0;
905 	}
906 
907 	if (params->prev_bssid) {
908 		assoc_info.prev_bssid_flag = 1;
909 		memcpy(assoc_info.prev_bssid, params->prev_bssid, ETH_ALEN);
910 	}
911 
912 	if (params->ssid) {
913 		assoc_info.ssid.nrf_wifi_ssid_len = params->ssid_len;
914 
915 		memcpy(assoc_info.ssid.nrf_wifi_ssid, params->ssid, params->ssid_len);
916 
917 	}
918 
919 	if (params->wpa_ie) {
920 		assoc_info.wpa_ie.ie_len = params->wpa_ie_len;
921 		memcpy(assoc_info.wpa_ie.ie, params->wpa_ie, params->wpa_ie_len);
922 	}
923 
924 	assoc_info.control_port = 1;
925 
926 	if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED) {
927 		assoc_info.use_mfp = NRF_WIFI_MFP_REQUIRED;
928 	}
929 
930 	if (params->bss_max_idle_period) {
931 		assoc_info.bss_max_idle_time = params->bss_max_idle_period;
932 	}
933 
934 	status = nrf_wifi_sys_fmac_assoc(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &assoc_info);
935 
936 	if (status != NRF_WIFI_STATUS_SUCCESS) {
937 		LOG_ERR("%s: MLME command failed (assoc)", __func__);
938 	} else {
939 		LOG_DBG("%s: Association request sent successfully", __func__);
940 		ret = 0;
941 	}
942 
943 out:
944 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
945 	return ret;
946 }
947 
nrf_wifi_wpa_supp_set_key(void * if_priv,const unsigned char * ifname,enum wpa_alg alg,const unsigned char * addr,int key_idx,int set_tx,const unsigned char * seq,size_t seq_len,const unsigned char * key,size_t key_len,enum key_flag key_flag)948 int nrf_wifi_wpa_supp_set_key(void *if_priv, const unsigned char *ifname, enum wpa_alg alg,
949 			      const unsigned char *addr, int key_idx, int set_tx,
950 			      const unsigned char *seq, size_t seq_len, const unsigned char *key,
951 			      size_t key_len, enum key_flag key_flag)
952 {
953 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
954 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
955 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
956 	struct nrf_wifi_umac_key_info key_info;
957 	const unsigned char *mac_addr = NULL;
958 	unsigned int suite;
959 	int ret = -1;
960 
961 
962 	if ((!if_priv) || (!ifname)) {
963 		LOG_ERR("%s: Invalid params", __func__);
964 		return ret;
965 	}
966 
967 	vif_ctx_zep = if_priv;
968 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
969 	if (!rpu_ctx_zep->rpu_ctx) {
970 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
971 		return ret;
972 	}
973 
974 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
975 	if (!rpu_ctx_zep->rpu_ctx) {
976 		LOG_DBG("%s: RPU context not initialized", __func__);
977 		goto out;
978 	}
979 
980 	/* Can happen in a positive case where "net if down" is completed, but WPA
981 	 * supplicant is still deleting keys.
982 	 */
983 	if (!rpu_ctx_zep->rpu_ctx) {
984 		goto out;
985 	}
986 
987 	memset(&key_info, 0, sizeof(key_info));
988 
989 	if (alg != WPA_ALG_NONE) {
990 		suite = wpa_alg_to_cipher_suite(alg, key_len);
991 
992 		if (!suite) {
993 			goto out;
994 		}
995 
996 		memcpy(key_info.key.nrf_wifi_key, key, key_len);
997 
998 		key_info.key.nrf_wifi_key_len = key_len;
999 		key_info.cipher_suite = suite;
1000 
1001 		key_info.valid_fields |= (NRF_WIFI_CIPHER_SUITE_VALID | NRF_WIFI_KEY_VALID);
1002 	}
1003 
1004 	if (seq && seq_len) {
1005 		memcpy(key_info.seq.nrf_wifi_seq, seq, seq_len);
1006 
1007 		key_info.seq.nrf_wifi_seq_len = seq_len;
1008 		key_info.valid_fields |= NRF_WIFI_SEQ_VALID;
1009 	}
1010 
1011 
1012 	/* TODO: Implement/check set_tx */
1013 	if (addr && !is_broadcast_ether_addr(addr)) {
1014 		mac_addr = addr;
1015 		key_info.key_type = NRF_WIFI_KEYTYPE_PAIRWISE;
1016 		key_info.valid_fields |= NRF_WIFI_KEY_TYPE_VALID;
1017 	} else if (addr && is_broadcast_ether_addr(addr)) {
1018 		mac_addr = NULL;
1019 		key_info.key_type = NRF_WIFI_KEYTYPE_GROUP;
1020 		key_info.valid_fields |= NRF_WIFI_KEY_TYPE_VALID;
1021 		key_info.nrf_wifi_flags |= NRF_WIFI_KEY_DEFAULT_TYPE_MULTICAST;
1022 	}
1023 
1024 	key_info.key_idx = key_idx;
1025 	key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID;
1026 
1027 	if (alg == WPA_ALG_NONE) {
1028 		status = nrf_wifi_sys_fmac_del_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx,
1029 					       &key_info, mac_addr);
1030 
1031 		if (status != NRF_WIFI_STATUS_SUCCESS) {
1032 			LOG_ERR("%s: nrf_wifi_sys_fmac_del_key failed", __func__);
1033 		} else {
1034 			ret = 0;
1035 		}
1036 	} else {
1037 		status = nrf_wifi_sys_fmac_add_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx,
1038 					       &key_info, mac_addr);
1039 
1040 		if (status != NRF_WIFI_STATUS_SUCCESS) {
1041 			LOG_ERR("%s: nrf_wifi_sys_fmac_add_key failed", __func__);
1042 		} else {
1043 			ret = 0;
1044 		}
1045 	}
1046 
1047 	/*
1048 	 * If we failed or don't need to set the default TX key (below),
1049 	 * we're done here.
1050 	 */
1051 	if (ret || !set_tx || alg == WPA_ALG_NONE) {
1052 		goto out;
1053 	}
1054 
1055 
1056 	memset(&key_info, 0, sizeof(key_info));
1057 
1058 	key_info.key_idx = key_idx;
1059 	key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID;
1060 
1061 	if (alg == WPA_ALG_BIP_CMAC_128 || alg == WPA_ALG_BIP_GMAC_128 ||
1062 	    alg == WPA_ALG_BIP_GMAC_256 || alg == WPA_ALG_BIP_CMAC_256) {
1063 		key_info.nrf_wifi_flags = NRF_WIFI_KEY_DEFAULT_MGMT;
1064 	} else {
1065 		key_info.nrf_wifi_flags = NRF_WIFI_KEY_DEFAULT;
1066 	}
1067 
1068 	if (addr && is_broadcast_ether_addr(addr)) {
1069 		key_info.nrf_wifi_flags |= NRF_WIFI_KEY_DEFAULT_TYPE_MULTICAST;
1070 	} else if (addr) {
1071 		key_info.nrf_wifi_flags |= NRF_WIFI_KEY_DEFAULT_TYPE_UNICAST;
1072 	}
1073 
1074 	status = nrf_wifi_sys_fmac_set_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &key_info);
1075 
1076 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1077 		LOG_ERR("%s: nrf_wifi_sys_fmac_set_key failed", __func__);
1078 		ret = -1;
1079 	} else {
1080 		ret = 0;
1081 	}
1082 out:
1083 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1084 	return ret;
1085 }
1086 
nrf_wifi_wpa_set_supp_port(void * if_priv,int authorized,char * bssid)1087 int nrf_wifi_wpa_set_supp_port(void *if_priv, int authorized, char *bssid)
1088 {
1089 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1090 	struct nrf_wifi_umac_chg_sta_info chg_sta_info;
1091 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1092 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1093 	int ret = -1;
1094 
1095 	if (!if_priv || !bssid) {
1096 		LOG_ERR("%s: Invalid params", __func__);
1097 		return ret;
1098 	}
1099 
1100 	vif_ctx_zep = if_priv;
1101 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1102 	if (!rpu_ctx_zep) {
1103 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1104 		return ret;
1105 	}
1106 
1107 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1108 	if (!rpu_ctx_zep->rpu_ctx) {
1109 		LOG_DBG("%s: RPU context not initialized", __func__);
1110 		goto out;
1111 	}
1112 
1113 	if (vif_ctx_zep->if_op_state != NRF_WIFI_FMAC_IF_OP_STATE_UP) {
1114 		LOG_DBG("%s: Interface not UP, ignoring", __func__);
1115 		ret = 0;
1116 		goto out;
1117 	}
1118 
1119 	memset(&chg_sta_info, 0x0, sizeof(chg_sta_info));
1120 
1121 	memcpy(chg_sta_info.mac_addr, bssid, ETH_ALEN);
1122 
1123 	vif_ctx_zep->authorized = authorized;
1124 
1125 	if (authorized) {
1126 		/* BIT(NL80211_STA_FLAG_AUTHORIZED) */
1127 		chg_sta_info.sta_flags2.nrf_wifi_mask = 1 << 1;
1128 		/* BIT(NL80211_STA_FLAG_AUTHORIZED) */
1129 		chg_sta_info.sta_flags2.nrf_wifi_set = 1 << 1;
1130 	}
1131 
1132 	status = nrf_wifi_sys_fmac_chg_sta(rpu_ctx_zep->rpu_ctx,
1133 					   vif_ctx_zep->vif_idx,
1134 					   &chg_sta_info);
1135 
1136 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1137 		LOG_ERR("%s: nrf_wifi_sys_fmac_chg_sta failed", __func__);
1138 		ret = -1;
1139 		goto out;
1140 	}
1141 
1142 	ret = 0;
1143 out:
1144 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1145 	return ret;
1146 }
1147 
nrf_wifi_wpa_supp_signal_poll(void * if_priv,struct wpa_signal_info * si,unsigned char * bssid)1148 int nrf_wifi_wpa_supp_signal_poll(void *if_priv, struct wpa_signal_info *si, unsigned char *bssid)
1149 {
1150 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1151 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1152 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1153 	enum nrf_wifi_status ret = NRF_WIFI_STATUS_FAIL;
1154 	int sem_ret;
1155 	int rssi_record_elapsed_time_ms = 0;
1156 
1157 	if (!if_priv || !si || !bssid) {
1158 		LOG_ERR("%s: Invalid params", __func__);
1159 		return ret;
1160 	}
1161 
1162 	vif_ctx_zep = if_priv;
1163 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1164 	if (!rpu_ctx_zep) {
1165 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1166 		return ret;
1167 	}
1168 
1169 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1170 	if (!rpu_ctx_zep->rpu_ctx) {
1171 		LOG_DBG("%s: RPU context not initialized", __func__);
1172 		goto out;
1173 	}
1174 
1175 	fmac_dev_ctx = rpu_ctx_zep->rpu_ctx;
1176 
1177 	vif_ctx_zep->signal_info = si;
1178 
1179 	rssi_record_elapsed_time_ms =
1180 		nrf_wifi_osal_time_elapsed_us(vif_ctx_zep->rssi_record_timestamp_us) / 1000;
1181 
1182 	if (rssi_record_elapsed_time_ms > CONFIG_NRF70_RSSI_STALE_TIMEOUT_MS) {
1183 		ret = nrf_wifi_sys_fmac_get_station(rpu_ctx_zep->rpu_ctx,
1184 						    vif_ctx_zep->vif_idx,
1185 						    bssid);
1186 		if (ret != NRF_WIFI_STATUS_SUCCESS) {
1187 			LOG_ERR("%s: Failed to send get station info command", __func__);
1188 			goto out;
1189 		}
1190 
1191 		sem_ret = k_sem_take(&wait_for_event_sem, K_MSEC(RPU_RESP_EVENT_TIMEOUT));
1192 		if (sem_ret) {
1193 			LOG_ERR("%s: Failed to get station info, ret = %d", __func__, sem_ret);
1194 			ret = NRF_WIFI_STATUS_FAIL;
1195 			goto out;
1196 		}
1197 	} else {
1198 		si->data.signal = (int)vif_ctx_zep->rssi;
1199 	}
1200 
1201 	ret = nrf_wifi_sys_fmac_get_interface(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx);
1202 	if (ret != NRF_WIFI_STATUS_SUCCESS) {
1203 		LOG_ERR("%s: Failed to send get interface info command", __func__);
1204 		goto out;
1205 	}
1206 
1207 	sem_ret = k_sem_take(&wait_for_event_sem, K_MSEC(RPU_RESP_EVENT_TIMEOUT));
1208 	if (sem_ret) {
1209 		LOG_ERR("%s: Failed to get interface info, ret = %d", __func__, sem_ret);
1210 		ret = NRF_WIFI_STATUS_FAIL;
1211 		goto out;
1212 	}
1213 	vif_ctx_zep->signal_info->frequency = vif_ctx_zep->assoc_freq;
1214 out:
1215 	vif_ctx_zep->signal_info = NULL;
1216 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1217 	return ret;
1218 }
1219 
nrf_wifi_wpa_supp_event_proc_get_sta(void * if_priv,struct nrf_wifi_umac_event_new_station * info,unsigned int event_len)1220 void nrf_wifi_wpa_supp_event_proc_get_sta(void *if_priv,
1221 					   struct nrf_wifi_umac_event_new_station *info,
1222 					   unsigned int event_len)
1223 {
1224 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1225 	struct wpa_signal_info *signal_info = NULL;
1226 
1227 	if (!if_priv || !info) {
1228 		LOG_ERR("%s: Invalid params", __func__);
1229 		goto out;
1230 	}
1231 
1232 	vif_ctx_zep = if_priv;
1233 	if (!vif_ctx_zep) {
1234 		LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
1235 		goto out;
1236 	}
1237 
1238 #ifdef CONFIG_NRF70_AP_MODE
1239 	vif_ctx_zep->inactive_time_sec = info->sta_info.inactive_time;
1240 #endif /* CONFIG_NRF70_AP_MODE */
1241 
1242 	signal_info = vif_ctx_zep->signal_info;
1243 	/* Semaphore timedout */
1244 	if (!signal_info) {
1245 		goto out;
1246 	}
1247 
1248 	if (info->sta_info.valid_fields & NRF_WIFI_STA_INFO_SIGNAL_VALID) {
1249 		signal_info->data.signal = info->sta_info.signal;
1250 	} else {
1251 		signal_info->data.signal = 0;
1252 	}
1253 
1254 	if (info->sta_info.valid_fields & NRF_WIFI_STA_INFO_SIGNAL_AVG_VALID) {
1255 		signal_info->data.avg_signal = info->sta_info.signal_avg;
1256 	} else {
1257 		signal_info->data.avg_signal = 0;
1258 	}
1259 
1260 	if (info->sta_info.valid_fields & NRF_WIFI_STA_INFO_RX_BEACON_SIGNAL_AVG_VALID) {
1261 		signal_info->data.avg_beacon_signal = info->sta_info.rx_beacon_signal_avg;
1262 	} else {
1263 		signal_info->data.avg_beacon_signal = 0;
1264 	}
1265 
1266 	signal_info->data.current_tx_rate = 0;
1267 
1268 	if (info->sta_info.valid_fields & NRF_WIFI_STA_INFO_TX_BITRATE_VALID) {
1269 		if (info->sta_info.tx_bitrate.valid_fields & NRF_WIFI_RATE_INFO_BITRATE_VALID) {
1270 			signal_info->data.current_tx_rate = info->sta_info.tx_bitrate.bitrate * 100;
1271 		}
1272 	}
1273 out:
1274 	k_sem_give(&wait_for_event_sem);
1275 }
1276 
nrf_wifi_wpa_supp_event_proc_get_if(void * if_priv,struct nrf_wifi_interface_info * info,unsigned int event_len)1277 void nrf_wifi_wpa_supp_event_proc_get_if(void *if_priv,
1278 					   struct nrf_wifi_interface_info *info,
1279 					   unsigned int event_len)
1280 {
1281 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1282 	struct nrf_wifi_chan_definition *chan_def_info = NULL;
1283 	struct wpa_signal_info *signal_info = NULL;
1284 
1285 	if (!if_priv || !info) {
1286 		LOG_ERR("%s: Invalid params", __func__);
1287 		k_sem_give(&wait_for_event_sem);
1288 		return;
1289 	}
1290 
1291 	vif_ctx_zep = if_priv;
1292 	signal_info = vif_ctx_zep->signal_info;
1293 
1294 	/* Semaphore timedout */
1295 	if (!signal_info) {
1296 		LOG_DBG("%s: Get interface Semaphore timedout", __func__);
1297 		return;
1298 	}
1299 
1300 	chan_def_info = (struct nrf_wifi_chan_definition *)(&info->chan_def);
1301 	signal_info->chanwidth = drv2supp_chan_width(chan_def_info->width);
1302 	signal_info->center_frq1 = chan_def_info->center_frequency1;
1303 	signal_info->center_frq2 = chan_def_info->center_frequency2;
1304 
1305 	k_sem_give(&wait_for_event_sem);
1306 }
1307 
nrf_wifi_wpa_supp_event_mgmt_tx_status(void * if_priv,struct nrf_wifi_umac_event_mlme * mlme_event,unsigned int event_len)1308 void nrf_wifi_wpa_supp_event_mgmt_tx_status(void *if_priv,
1309 		struct nrf_wifi_umac_event_mlme *mlme_event,
1310 		unsigned int event_len)
1311 {
1312 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1313 	bool acked = false;
1314 
1315 	if (!if_priv) {
1316 		LOG_ERR("%s: Missing interface context", __func__);
1317 		return;
1318 	}
1319 
1320 	vif_ctx_zep = if_priv;
1321 
1322 	if (!mlme_event) {
1323 		LOG_ERR("%s: Missing MLME event data", __func__);
1324 		return;
1325 	}
1326 
1327 	acked = mlme_event->nrf_wifi_flags & NRF_WIFI_EVENT_MLME_ACK ? true : false;
1328 	LOG_DBG("%s: Mgmt frame %llx tx status: %s",
1329 		    __func__, mlme_event->cookie, acked ? "ACK" : "NOACK");
1330 
1331 	if (vif_ctx_zep->supp_drv_if_ctx &&
1332 		vif_ctx_zep->supp_callbk_fns.mgmt_tx_status) {
1333 		vif_ctx_zep->supp_callbk_fns.mgmt_tx_status(vif_ctx_zep->supp_drv_if_ctx,
1334 				mlme_event->frame.frame,
1335 				mlme_event->frame.frame_len,
1336 				acked);
1337 	}
1338 }
1339 
nrf_wifi_wpa_supp_event_proc_unprot_mgmt(void * if_priv,struct nrf_wifi_umac_event_mlme * unprot_mgmt,unsigned int event_len)1340 void nrf_wifi_wpa_supp_event_proc_unprot_mgmt(void *if_priv,
1341 		struct nrf_wifi_umac_event_mlme *unprot_mgmt,
1342 		unsigned int event_len)
1343 {
1344 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1345 	union wpa_event_data event;
1346 	const struct ieee80211_mgmt *mgmt = NULL;
1347 	const unsigned char *frame = NULL;
1348 	unsigned int frame_len = 0;
1349 	int cmd_evnt = 0;
1350 
1351 	vif_ctx_zep = if_priv;
1352 
1353 	frame = unprot_mgmt->frame.frame;
1354 	frame_len = unprot_mgmt->frame.frame_len;
1355 
1356 	mgmt = (const struct ieee80211_mgmt *)frame;
1357 	cmd_evnt = ((struct nrf_wifi_umac_hdr *)unprot_mgmt)->cmd_evnt;
1358 
1359 	if (frame_len < 24 + sizeof(mgmt->u.deauth)) {
1360 		LOG_ERR("%s: Unprotected mgmt frame too short", __func__);
1361 		return;
1362 	}
1363 
1364 	memset(&event, 0, sizeof(event));
1365 
1366 	event.unprot_deauth.sa = &mgmt->sa[0];
1367 	event.unprot_deauth.da = &mgmt->da[0];
1368 
1369 	if (cmd_evnt == NRF_WIFI_UMAC_EVENT_UNPROT_DEAUTHENTICATE) {
1370 		event.unprot_deauth.reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1371 		if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.unprot_deauth) {
1372 			vif_ctx_zep->supp_callbk_fns.unprot_deauth(vif_ctx_zep->supp_drv_if_ctx,
1373 									  &event);
1374 		}
1375 	} else if (cmd_evnt == NRF_WIFI_UMAC_EVENT_UNPROT_DISASSOCIATE) {
1376 		event.unprot_disassoc.reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1377 		if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.unprot_disassoc) {
1378 			vif_ctx_zep->supp_callbk_fns.unprot_disassoc(vif_ctx_zep->supp_drv_if_ctx,
1379 										&event);
1380 		}
1381 	}
1382 }
1383 
nrf_wifi_nl80211_send_mlme(void * if_priv,const u8 * data,size_t data_len,int noack,unsigned int freq,int no_cck,int offchanok,unsigned int wait_time,int cookie)1384 int nrf_wifi_nl80211_send_mlme(void *if_priv, const u8 *data,
1385 		size_t data_len, int noack,
1386 		unsigned int freq, int no_cck,
1387 		int offchanok,
1388 		unsigned int wait_time,
1389 		int cookie)
1390 {
1391 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1392 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1393 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1394 	struct nrf_wifi_umac_mgmt_tx_info *mgmt_tx_info = NULL;
1395 	unsigned int timeout = 0;
1396 
1397 	if (!if_priv || !data) {
1398 		LOG_ERR("%s: Invalid params", __func__);
1399 		return -1;
1400 	}
1401 
1402 	vif_ctx_zep = if_priv;
1403 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1404 	if (!rpu_ctx_zep) {
1405 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1406 		return -1;
1407 	}
1408 
1409 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1410 	if (!rpu_ctx_zep->rpu_ctx) {
1411 		LOG_DBG("%s: RPU context not initialized", __func__);
1412 		goto out;
1413 	}
1414 
1415 	k_mutex_lock(&mgmt_tx_lock, K_FOREVER);
1416 
1417 	mgmt_tx_info = nrf_wifi_osal_mem_zalloc(sizeof(*mgmt_tx_info));
1418 
1419 	if (!mgmt_tx_info) {
1420 		LOG_ERR("%s: Unable to allocate memory", __func__);
1421 		goto out;
1422 	}
1423 
1424 	if (offchanok) {
1425 		mgmt_tx_info->nrf_wifi_flags |= NRF_WIFI_CMD_FRAME_OFFCHANNEL_TX_OK;
1426 	}
1427 
1428 	if (noack) {
1429 		mgmt_tx_info->nrf_wifi_flags |= NRF_WIFI_CMD_FRAME_DONT_WAIT_FOR_ACK;
1430 	}
1431 
1432 	if (no_cck) {
1433 		mgmt_tx_info->nrf_wifi_flags |= NRF_WIFI_CMD_FRAME_TX_NO_CCK_RATE;
1434 	}
1435 
1436 	if (freq) {
1437 		mgmt_tx_info->frequency = freq;
1438 	}
1439 
1440 	if (wait_time) {
1441 		mgmt_tx_info->dur = wait_time;
1442 	}
1443 
1444 	if (data_len) {
1445 		memcpy(mgmt_tx_info->frame.frame, data, data_len);
1446 		mgmt_tx_info->frame.frame_len = data_len;
1447 	}
1448 
1449 	mgmt_tx_info->freq_params.frequency = freq;
1450 	mgmt_tx_info->freq_params.channel_width = NRF_WIFI_CHAN_WIDTH_20;
1451 	mgmt_tx_info->freq_params.center_frequency1 = freq;
1452 	mgmt_tx_info->freq_params.center_frequency2 = 0;
1453 	mgmt_tx_info->freq_params.channel_type = NRF_WIFI_CHAN_HT20;
1454 
1455 	/* Going to RPU */
1456 	mgmt_tx_info->host_cookie = cookie;
1457 	vif_ctx_zep->cookie_resp_received = false;
1458 
1459 	LOG_DBG("%s: Sending frame to RPU: cookie=%d wait_time=%d no_ack=%d", __func__,
1460 		    cookie, wait_time, noack);
1461 	status = nrf_wifi_sys_fmac_mgmt_tx(rpu_ctx_zep->rpu_ctx,
1462 			vif_ctx_zep->vif_idx,
1463 			mgmt_tx_info);
1464 
1465 	if (status == NRF_WIFI_STATUS_FAIL) {
1466 		LOG_ERR("%s: nrf_wifi_sys_fmac_mgmt_tx failed", __func__);
1467 		goto out;
1468 	}
1469 
1470 	/* Both are needed as we use this to send_action where noack is hardcoded
1471 	 * to 0 always.
1472 	 */
1473 	if (wait_time || !noack) {
1474 		if (!noack && !wait_time) {
1475 			wait_time = ACTION_FRAME_RESP_TIMEOUT_MS;
1476 		}
1477 
1478 		while (!vif_ctx_zep->cookie_resp_received &&
1479 			timeout++ < wait_time) {
1480 			k_sleep(K_MSEC(1));
1481 		}
1482 
1483 		if (!vif_ctx_zep->cookie_resp_received) {
1484 			LOG_ERR("%s: cookie response not received (%dms)", __func__,
1485 				timeout);
1486 			status = NRF_WIFI_STATUS_FAIL;
1487 			goto out;
1488 		}
1489 		status = NRF_WIFI_STATUS_SUCCESS;
1490 	}
1491 
1492 out:
1493 	if (mgmt_tx_info) {
1494 		nrf_wifi_osal_mem_free(mgmt_tx_info);
1495 	}
1496 	k_mutex_unlock(&mgmt_tx_lock);
1497 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1498 	return status;
1499 }
1500 
nrf_wifi_parse_sband(struct nrf_wifi_event_supported_band * event,struct wpa_supp_event_supported_band * band)1501 enum nrf_wifi_status nrf_wifi_parse_sband(
1502 	struct nrf_wifi_event_supported_band *event,
1503 	struct wpa_supp_event_supported_band *band
1504 	)
1505 {
1506 	int count;
1507 
1508 	if (event && (event->nrf_wifi_n_bitrates == 0 || event->nrf_wifi_n_channels == 0)) {
1509 		return NRF_WIFI_STATUS_FAIL;
1510 	}
1511 	memset(band, 0, sizeof(*band));
1512 
1513 	band->wpa_supp_n_channels = event->nrf_wifi_n_channels;
1514 	band->wpa_supp_n_bitrates = event->nrf_wifi_n_bitrates;
1515 
1516 	for (count = 0; count < band->wpa_supp_n_channels; count++) {
1517 		struct wpa_supp_event_channel *chan = &band->channels[count];
1518 
1519 		if (count >= WPA_SUPP_SBAND_MAX_CHANNELS) {
1520 			LOG_ERR("%s: Failed to add channel", __func__);
1521 			break;
1522 		}
1523 
1524 		chan->wpa_supp_flags = event->channels[count].nrf_wifi_flags;
1525 		chan->wpa_supp_max_power = event->channels[count].nrf_wifi_max_power;
1526 		chan->wpa_supp_time = event->channels[count].nrf_wifi_time;
1527 		chan->dfs_cac_msec = event->channels[count].dfs_cac_msec;
1528 		chan->ch_valid = event->channels[count].ch_valid;
1529 		chan->center_frequency = event->channels[count].center_frequency;
1530 		chan->dfs_state = event->channels[count].dfs_state;
1531 	}
1532 
1533 	for (count = 0; count < band->wpa_supp_n_bitrates; count++) {
1534 		struct wpa_supp_event_rate *rate = &band->bitrates[count];
1535 
1536 		if (count >= WPA_SUPP_SBAND_MAX_RATES) {
1537 			LOG_ERR("%s: Failed to add bitrate", __func__);
1538 			break;
1539 		}
1540 
1541 		rate->wpa_supp_flags = event->bitrates[count].nrf_wifi_flags;
1542 		rate->wpa_supp_bitrate = event->bitrates[count].nrf_wifi_bitrate;
1543 	}
1544 
1545 	band->ht_cap.wpa_supp_ht_supported = event->ht_cap.nrf_wifi_ht_supported;
1546 	band->ht_cap.wpa_supp_cap = event->ht_cap.nrf_wifi_cap;
1547 	band->ht_cap.mcs.wpa_supp_rx_highest = event->ht_cap.mcs.nrf_wifi_rx_highest;
1548 
1549 	for (count = 0; count < WPA_SUPP_HT_MCS_MASK_LEN; count++) {
1550 		band->ht_cap.mcs.wpa_supp_rx_mask[count] =
1551 			event->ht_cap.mcs.nrf_wifi_rx_mask[count];
1552 	}
1553 
1554 	band->ht_cap.mcs.wpa_supp_tx_params = event->ht_cap.mcs.nrf_wifi_tx_params;
1555 
1556 	for (count = 0; count < NRF_WIFI_HT_MCS_RES_LEN; count++) {
1557 
1558 		if (count >= WPA_SUPP_HT_MCS_RES_LEN) {
1559 			LOG_ERR("%s: Failed to add reserved bytes", __func__);
1560 			break;
1561 		}
1562 
1563 		band->ht_cap.mcs.wpa_supp_reserved[count] =
1564 			event->ht_cap.mcs.nrf_wifi_reserved[count];
1565 	}
1566 
1567 	band->ht_cap.wpa_supp_ampdu_factor = event->ht_cap.nrf_wifi_ampdu_factor;
1568 	band->ht_cap.wpa_supp_ampdu_density = event->ht_cap.nrf_wifi_ampdu_density;
1569 
1570 	band->vht_cap.wpa_supp_vht_supported = event->vht_cap.nrf_wifi_vht_supported;
1571 	band->vht_cap.wpa_supp_cap = event->vht_cap.nrf_wifi_cap;
1572 
1573 	band->vht_cap.vht_mcs.rx_mcs_map = event->vht_cap.vht_mcs.rx_mcs_map;
1574 	band->vht_cap.vht_mcs.rx_highest = event->vht_cap.vht_mcs.rx_highest;
1575 	band->vht_cap.vht_mcs.tx_mcs_map = event->vht_cap.vht_mcs.tx_mcs_map;
1576 	band->vht_cap.vht_mcs.tx_highest = event->vht_cap.vht_mcs.tx_highest;
1577 
1578 	band->band = event->band;
1579 
1580 	return WLAN_STATUS_SUCCESS;
1581 }
1582 
nrf_wifi_wpa_supp_event_get_wiphy(void * if_priv,struct nrf_wifi_event_get_wiphy * wiphy_info,unsigned int event_len)1583 void nrf_wifi_wpa_supp_event_get_wiphy(void *if_priv,
1584 		struct nrf_wifi_event_get_wiphy *wiphy_info,
1585 		unsigned int event_len)
1586 {
1587 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1588 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1589 	struct wpa_supp_event_supported_band band;
1590 
1591 	if (!if_priv || !wiphy_info || !event_len) {
1592 		LOG_ERR("%s: Invalid parameters", __func__);
1593 		return;
1594 	}
1595 
1596 	vif_ctx_zep = if_priv;
1597 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1598 
1599 	memset(&band, 0, sizeof(band));
1600 
1601 	for (int i = 0; i < NRF_WIFI_EVENT_GET_WIPHY_NUM_BANDS; i++) {
1602 		if (nrf_wifi_parse_sband(&wiphy_info->sband[i], &band) != WLAN_STATUS_SUCCESS) {
1603 			continue;
1604 		}
1605 		if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.get_wiphy_res) {
1606 			vif_ctx_zep->supp_callbk_fns.get_wiphy_res(vif_ctx_zep->supp_drv_if_ctx,
1607 									&band);
1608 		}
1609 	}
1610 
1611 	if ((wiphy_info->params_valid & NRF_WIFI_GET_WIPHY_VALID_EXTENDED_CAPABILITIES) &&
1612 	    rpu_ctx_zep->extended_capa == NULL) {
1613 		/* To avoid overflowing the 100 column limit */
1614 		unsigned char ec_len = wiphy_info->extended_capabilities_len;
1615 
1616 		rpu_ctx_zep->extended_capa = nrf_wifi_osal_mem_alloc(ec_len);
1617 
1618 		if (rpu_ctx_zep->extended_capa) {
1619 			memcpy(rpu_ctx_zep->extended_capa, wiphy_info->extended_capabilities,
1620 			       ec_len);
1621 		}
1622 
1623 		rpu_ctx_zep->extended_capa_mask = nrf_wifi_osal_mem_alloc(ec_len);
1624 
1625 		if (rpu_ctx_zep->extended_capa_mask) {
1626 			memcpy(rpu_ctx_zep->extended_capa_mask,
1627 			       wiphy_info->extended_capabilities_mask,
1628 			       ec_len);
1629 		} else {
1630 			nrf_wifi_osal_mem_free(rpu_ctx_zep->extended_capa);
1631 			rpu_ctx_zep->extended_capa = NULL;
1632 			rpu_ctx_zep->extended_capa_len = 0;
1633 		}
1634 	}
1635 
1636 	if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.get_wiphy_res) {
1637 		vif_ctx_zep->supp_callbk_fns.get_wiphy_res(vif_ctx_zep->supp_drv_if_ctx, NULL);
1638 	}
1639 }
1640 
nrf_wifi_supp_get_wiphy(void * if_priv)1641 int nrf_wifi_supp_get_wiphy(void *if_priv)
1642 {
1643 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1644 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1645 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1646 
1647 	if (!if_priv) {
1648 		LOG_ERR("%s: Missing interface context", __func__);
1649 		return -1;
1650 	}
1651 
1652 	vif_ctx_zep = if_priv;
1653 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1654 	if (!rpu_ctx_zep) {
1655 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1656 		return -1;
1657 	}
1658 
1659 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1660 	if (!rpu_ctx_zep->rpu_ctx) {
1661 		LOG_DBG("%s: RPU context not initialized", __func__);
1662 		goto out;
1663 	}
1664 
1665 	status = nrf_wifi_sys_fmac_get_wiphy(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx);
1666 
1667 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1668 		LOG_ERR("%s: nrf_wifi_sys_fmac_get_wiphy failed", __func__);
1669 		goto out;
1670 	}
1671 out:
1672 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1673 	return status;
1674 }
1675 
nrf_wifi_supp_register_frame(void * if_priv,u16 type,const u8 * match,size_t match_len,bool multicast)1676 int nrf_wifi_supp_register_frame(void *if_priv,
1677 			u16 type, const u8 *match, size_t match_len,
1678 			bool multicast)
1679 {
1680 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1681 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1682 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1683 	struct nrf_wifi_umac_mgmt_frame_info frame_info;
1684 
1685 	if (!if_priv || !match || !match_len) {
1686 		LOG_ERR("%s: Invalid parameters", __func__);
1687 		return -1;
1688 	}
1689 
1690 	vif_ctx_zep = if_priv;
1691 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1692 	if (!rpu_ctx_zep) {
1693 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1694 		return -1;
1695 	}
1696 
1697 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1698 	if (!rpu_ctx_zep->rpu_ctx) {
1699 		LOG_DBG("%s: RPU context not initialized", __func__);
1700 		goto out;
1701 	}
1702 
1703 	memset(&frame_info, 0, sizeof(frame_info));
1704 
1705 	frame_info.frame_type = type;
1706 	frame_info.frame_match.frame_match_len = match_len;
1707 	memcpy(frame_info.frame_match.frame_match, match, match_len);
1708 
1709 	status = nrf_wifi_sys_fmac_register_frame(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx,
1710 			&frame_info);
1711 
1712 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1713 		LOG_ERR("%s: nrf_wifi_sys_fmac_register_frame failed", __func__);
1714 		goto out;
1715 	}
1716 out:
1717 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1718 	return status;
1719 }
1720 
nrf_wifi_wpa_supp_event_mgmt_rx_callbk_fn(void * if_priv,struct nrf_wifi_umac_event_mlme * mlme_event,unsigned int event_len)1721 void nrf_wifi_wpa_supp_event_mgmt_rx_callbk_fn(void *if_priv,
1722 					       struct nrf_wifi_umac_event_mlme *mlme_event,
1723 					       unsigned int event_len)
1724 {
1725 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1726 
1727 	if (!if_priv) {
1728 		LOG_ERR("%s: Missing interface context", __func__);
1729 		return;
1730 	}
1731 
1732 	vif_ctx_zep = if_priv;
1733 
1734 	if (!mlme_event || !event_len) {
1735 		LOG_ERR("%s: Missing MLME event data", __func__);
1736 		return;
1737 	}
1738 
1739 	if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.mgmt_rx) {
1740 		vif_ctx_zep->supp_callbk_fns.mgmt_rx(vif_ctx_zep->supp_drv_if_ctx,
1741 				mlme_event->frame.frame,
1742 				mlme_event->frame.frame_len,
1743 				mlme_event->frequency,
1744 				mlme_event->rx_signal_dbm);
1745 	}
1746 }
1747 
nrf_wifi_supp_get_capa(void * if_priv,struct wpa_driver_capa * capa)1748 int nrf_wifi_supp_get_capa(void *if_priv, struct wpa_driver_capa *capa)
1749 {
1750 	enum nrf_wifi_status status = NRF_WIFI_STATUS_SUCCESS;
1751 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1752 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1753 
1754 	if (!if_priv || !capa) {
1755 		LOG_ERR("%s: Invalid parameters", __func__);
1756 		return -1;
1757 	}
1758 
1759 	memset(capa, 0, sizeof(*capa));
1760 
1761 	vif_ctx_zep = if_priv;
1762 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1763 	if (!rpu_ctx_zep) {
1764 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1765 		return -1;
1766 	}
1767 
1768 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1769 	if (!rpu_ctx_zep->rpu_ctx) {
1770 		LOG_DBG("%s: RPU context not initialized", __func__);
1771 		goto out;
1772 	}
1773 
1774 	/* TODO: Get these from RPU*/
1775 	/* Use SME */
1776 	capa->flags = 0;
1777 	capa->flags |= WPA_DRIVER_FLAGS_SME;
1778 	capa->flags |= WPA_DRIVER_FLAGS_SAE;
1779 	capa->flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
1780 	capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_RRM;
1781 	capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT;
1782 	if (IS_ENABLED(CONFIG_NRF70_AP_MODE)) {
1783 		capa->flags |= WPA_DRIVER_FLAGS_AP;
1784 	}
1785 
1786 	capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
1787 			WPA_DRIVER_CAPA_ENC_WEP104 |
1788 			WPA_DRIVER_CAPA_ENC_TKIP |
1789 			WPA_DRIVER_CAPA_ENC_CCMP |
1790 			WPA_DRIVER_CAPA_ENC_CCMP |
1791 			WPA_DRIVER_CAPA_ENC_CCMP_256 |
1792 			WPA_DRIVER_CAPA_ENC_GCMP_256;
1793 
1794 	if (rpu_ctx_zep->extended_capa && rpu_ctx_zep->extended_capa_mask) {
1795 		capa->extended_capa = rpu_ctx_zep->extended_capa;
1796 		capa->extended_capa_mask = rpu_ctx_zep->extended_capa_mask;
1797 		capa->extended_capa_len = rpu_ctx_zep->extended_capa_len;
1798 	}
1799 out:
1800 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1801 	return status;
1802 }
1803 
1804 
nrf_wifi_wpa_supp_event_mac_chgd(void * if_priv)1805 void nrf_wifi_wpa_supp_event_mac_chgd(void *if_priv)
1806 {
1807 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1808 
1809 	if (!if_priv) {
1810 		LOG_ERR("%s: Invalid parameters", __func__);
1811 		return;
1812 	}
1813 
1814 	vif_ctx_zep = if_priv;
1815 
1816 	if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.mac_changed) {
1817 		vif_ctx_zep->supp_callbk_fns.mac_changed(vif_ctx_zep->supp_drv_if_ctx);
1818 	}
1819 
1820 }
1821 
1822 
nrf_wifi_supp_get_conn_info(void * if_priv,struct wpa_conn_info * info)1823 int nrf_wifi_supp_get_conn_info(void *if_priv, struct wpa_conn_info *info)
1824 {
1825 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1826 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1827 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1828 	enum nrf_wifi_status ret = NRF_WIFI_STATUS_FAIL;
1829 	int sem_ret;
1830 
1831 	if (!if_priv || !info) {
1832 		LOG_ERR("%s: Invalid params", __func__);
1833 		return ret;
1834 	}
1835 
1836 	vif_ctx_zep = if_priv;
1837 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1838 	if (!rpu_ctx_zep) {
1839 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1840 		return ret;
1841 	}
1842 
1843 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1844 	if (!rpu_ctx_zep->rpu_ctx) {
1845 		LOG_DBG("%s: RPU context not initialized", __func__);
1846 		goto out;
1847 	}
1848 
1849 	fmac_dev_ctx = rpu_ctx_zep->rpu_ctx;
1850 
1851 	vif_ctx_zep->conn_info = info;
1852 	ret = nrf_wifi_sys_fmac_get_conn_info(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx);
1853 	if (ret != NRF_WIFI_STATUS_SUCCESS) {
1854 		LOG_ERR("%s: nrf_wifi_sys_fmac_get_conn_info failed", __func__);
1855 		goto out;
1856 	}
1857 
1858 	sem_ret = k_sem_take(&wait_for_event_sem, K_MSEC(RPU_RESP_EVENT_TIMEOUT));
1859 	if (sem_ret) {
1860 		LOG_ERR("%s: Timeout: failed to get connection info, ret = %d", __func__, sem_ret);
1861 		ret = NRF_WIFI_STATUS_FAIL;
1862 		goto out;
1863 	}
1864 
1865 out:
1866 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1867 	return ret;
1868 }
1869 
nrf_wifi_supp_set_country(void * if_priv,const char * alpha2)1870 int nrf_wifi_supp_set_country(void *if_priv, const char *alpha2)
1871 {
1872 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1873 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1874 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1875 	struct nrf_wifi_fmac_reg_info reg_domain_info = {0};
1876 
1877 	if (!if_priv || !alpha2) {
1878 		LOG_ERR("%s: Invalid params", __func__);
1879 		return -1;
1880 	}
1881 
1882 	vif_ctx_zep = if_priv;
1883 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1884 	if (!rpu_ctx_zep) {
1885 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1886 		return -1;
1887 	}
1888 
1889 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1890 	if (!rpu_ctx_zep->rpu_ctx) {
1891 		LOG_DBG("%s: RPU context not initialized", __func__);
1892 		goto out;
1893 	}
1894 
1895 	memcpy(reg_domain_info.alpha2, alpha2, NRF_WIFI_COUNTRY_CODE_LEN);
1896 
1897 	status = nrf_wifi_fmac_set_reg(rpu_ctx_zep->rpu_ctx, &reg_domain_info);
1898 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1899 		LOG_ERR("%s: nrf_wifi_fmac_set_reg failed", __func__);
1900 		goto out;
1901 	}
1902 out:
1903 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1904 	return status;
1905 }
1906 
nrf_wifi_supp_get_country(void * if_priv,char * alpha2)1907 int nrf_wifi_supp_get_country(void *if_priv, char *alpha2)
1908 {
1909 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1910 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1911 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1912 	struct nrf_wifi_fmac_reg_info reg_domain_info = {0};
1913 
1914 	if (!if_priv || !alpha2) {
1915 		LOG_ERR("%s: Invalid params", __func__);
1916 		return -1;
1917 	}
1918 
1919 	vif_ctx_zep = if_priv;
1920 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1921 	if (!rpu_ctx_zep) {
1922 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1923 		return -1;
1924 	}
1925 
1926 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1927 	if (!rpu_ctx_zep->rpu_ctx) {
1928 		LOG_DBG("%s: RPU context not initialized", __func__);
1929 		goto out;
1930 	}
1931 
1932 	status = nrf_wifi_fmac_get_reg(rpu_ctx_zep->rpu_ctx, &reg_domain_info);
1933 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1934 		LOG_ERR("%s: nrf_wifi_fmac_get_reg failed", __func__);
1935 		goto out;
1936 	}
1937 
1938 	memcpy(alpha2, reg_domain_info.alpha2, NRF_WIFI_COUNTRY_CODE_LEN);
1939 out:
1940 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1941 	return status;
1942 }
1943 
nrf_wifi_supp_event_proc_get_conn_info(void * if_priv,struct nrf_wifi_umac_event_conn_info * info,unsigned int event_len)1944 void nrf_wifi_supp_event_proc_get_conn_info(void *if_priv,
1945 					   struct nrf_wifi_umac_event_conn_info *info,
1946 					   unsigned int event_len)
1947 {
1948 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1949 	struct wpa_conn_info *conn_info = NULL;
1950 
1951 	if (!if_priv || !info) {
1952 		LOG_ERR("%s: Invalid params", __func__);
1953 		k_sem_give(&wait_for_event_sem);
1954 		return;
1955 	}
1956 	vif_ctx_zep = if_priv;
1957 	conn_info = vif_ctx_zep->conn_info;
1958 
1959 	conn_info->beacon_interval = info->beacon_interval;
1960 	conn_info->dtim_period = info->dtim_interval;
1961 	conn_info->twt_capable = info->twt_capable;
1962 	k_sem_give(&wait_for_event_sem);
1963 }
1964 
1965 #ifdef CONFIG_NRF70_AP_MODE
nrf_wifi_vif_state_change(struct nrf_wifi_vif_ctx_zep * vif_ctx_zep,enum nrf_wifi_fmac_if_op_state state)1966 static int nrf_wifi_vif_state_change(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep,
1967 	enum nrf_wifi_fmac_if_op_state state)
1968 {
1969 	struct nrf_wifi_umac_chg_vif_state_info vif_state_info = {0};
1970 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1971 	unsigned int timeout = 0;
1972 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
1973 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1974 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1975 	int ret = -1;
1976 
1977 	if (!vif_ctx_zep) {
1978 		LOG_ERR("%s: Invalid params", __func__);
1979 		return ret;
1980 	}
1981 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1982 	if (!rpu_ctx_zep) {
1983 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
1984 		return ret;
1985 	}
1986 
1987 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1988 	if (!rpu_ctx_zep->rpu_ctx) {
1989 		LOG_DBG("%s: RPU context not initialized", __func__);
1990 		goto out;
1991 	}
1992 
1993 	sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx);
1994 	vif_ctx = sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx];
1995 
1996 	vif_state_info.state = state;
1997 	vif_state_info.if_index = vif_ctx_zep->vif_idx;
1998 	vif_ctx->ifflags = false;
1999 	status = nrf_wifi_sys_fmac_chg_vif_state(rpu_ctx_zep->rpu_ctx,
2000 					     vif_ctx_zep->vif_idx,
2001 					     &vif_state_info);
2002 
2003 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2004 		LOG_ERR("%s: nrf_wifi_sys_fmac_chg_vif_state failed",
2005 			__func__);
2006 		goto out;
2007 	}
2008 
2009 	while (!vif_ctx->ifflags && timeout++ < SET_IFACE_EVENT_TIMEOUT_MS) {
2010 		k_sleep(K_MSEC(1));
2011 	}
2012 
2013 	if (!vif_ctx->ifflags) {
2014 		LOG_ERR("%s: set interface state event not received (%dms)", __func__, timeout);
2015 		goto out;
2016 	}
2017 	ret = 0;
2018 out:
2019 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2020 	return ret;
2021 }
2022 
nrf_wifi_iftype_change(struct nrf_wifi_vif_ctx_zep * vif_ctx_zep,int iftype)2023 static int nrf_wifi_iftype_change(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep, int iftype)
2024 {
2025 	struct nrf_wifi_umac_chg_vif_attr_info chg_vif_info = {0};
2026 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2027 	int ret = -1;
2028 	unsigned int timeout = 0;
2029 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2030 
2031 	if (!vif_ctx_zep) {
2032 		LOG_ERR("%s: Invalid params", __func__);
2033 		return ret;
2034 	}
2035 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2036 	if (!rpu_ctx_zep) {
2037 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
2038 		return ret;
2039 	}
2040 
2041 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2042 	if (!rpu_ctx_zep->rpu_ctx) {
2043 		LOG_DBG("%s: RPU context not initialized", __func__);
2044 		goto out;
2045 	}
2046 
2047 	ret = nrf_wifi_vif_state_change(vif_ctx_zep, NRF_WIFI_FMAC_IF_OP_STATE_DOWN);
2048 	if (ret) {
2049 		LOG_ERR("%s: Failed to set interface down", __func__);
2050 		goto out;
2051 	}
2052 
2053 	chg_vif_info.iftype = iftype;
2054 	vif_ctx_zep->set_if_event_received = false;
2055 	vif_ctx_zep->set_if_status = 0;
2056 	status = nrf_wifi_sys_fmac_chg_vif(rpu_ctx_zep->rpu_ctx,
2057 					   vif_ctx_zep->vif_idx,
2058 					   &chg_vif_info);
2059 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2060 		LOG_ERR("%s: nrf_wifi_sys_fmac_chg_vif failed", __func__);
2061 		goto out;
2062 	}
2063 
2064 	while (!vif_ctx_zep->set_if_event_received &&
2065 		  timeout++ < SET_IFACE_EVENT_TIMEOUT_MS) {
2066 		k_sleep(K_MSEC(1));
2067 	}
2068 
2069 	if (!vif_ctx_zep->set_if_event_received) {
2070 		LOG_ERR("%s: set interface event not received (%dms)", __func__, timeout);
2071 		goto out;
2072 	}
2073 
2074 	if (vif_ctx_zep->set_if_status != NRF_WIFI_STATUS_SUCCESS) {
2075 		LOG_ERR("%s: set interface failed: %d", __func__, vif_ctx_zep->set_if_status);
2076 		goto out;
2077 	}
2078 
2079 	ret = nrf_wifi_vif_state_change(vif_ctx_zep, NRF_WIFI_FMAC_IF_OP_STATE_UP);
2080 	if (ret) {
2081 		LOG_ERR("%s: Failed to set interface up", __func__);
2082 		goto out;
2083 	}
2084 	ret = 0;
2085 out:
2086 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2087 	return ret;
2088 }
2089 
nrf_wifi_wait_for_carrier_status(struct nrf_wifi_vif_ctx_zep * vif_ctx_zep,enum nrf_wifi_fmac_if_carr_state carrier_status)2090 static int nrf_wifi_wait_for_carrier_status(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep,
2091 	enum nrf_wifi_fmac_if_carr_state carrier_status)
2092 {
2093 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2094 	int ret = -1;
2095 	unsigned int timeout = 0;
2096 
2097 	if (!vif_ctx_zep) {
2098 		LOG_ERR("%s: Invalid params", __func__);
2099 		return ret;
2100 	}
2101 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2102 	if (!rpu_ctx_zep) {
2103 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
2104 		return ret;
2105 	}
2106 
2107 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2108 	if (!rpu_ctx_zep->rpu_ctx) {
2109 		LOG_DBG("%s: RPU context not initialized", __func__);
2110 		goto out;
2111 	}
2112 
2113 	while (vif_ctx_zep->if_carr_state != carrier_status &&
2114 	       timeout++ < CARR_ON_TIMEOUT_MS) {
2115 		k_sleep(K_MSEC(1));
2116 	}
2117 
2118 	if (vif_ctx_zep->if_carr_state != carrier_status) {
2119 		LOG_ERR("%s: Carrier %s event not received in %dms", __func__,
2120 			carrier_status == NRF_WIFI_FMAC_IF_CARR_STATE_ON ? "ON" : "OFF",
2121 			timeout);
2122 		goto out;
2123 	}
2124 
2125 	ret = 0;
2126 out:
2127 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2128 	return ret;
2129 }
2130 
nrf_wifi_wpa_supp_init_ap(void * if_priv,struct wpa_driver_associate_params * params)2131 int nrf_wifi_wpa_supp_init_ap(void *if_priv, struct wpa_driver_associate_params *params)
2132 {
2133 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2134 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2135 
2136 	int ret = -1;
2137 
2138 	if (!if_priv || !params) {
2139 		LOG_ERR("%s: Invalid params", __func__);
2140 		return ret;
2141 	}
2142 
2143 	if (params->mode != IEEE80211_MODE_AP) {
2144 		LOG_ERR("%s: Invalid mode", __func__);
2145 		return ret;
2146 	}
2147 
2148 	vif_ctx_zep = if_priv;
2149 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2150 	if (!rpu_ctx_zep) {
2151 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
2152 		return ret;
2153 	}
2154 
2155 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2156 	if (!rpu_ctx_zep->rpu_ctx) {
2157 		LOG_DBG("%s: RPU context not initialized", __func__);
2158 		goto out;
2159 	}
2160 
2161 	ret = nrf_wifi_iftype_change(vif_ctx_zep, NRF_WIFI_IFTYPE_AP);
2162 	if (ret) {
2163 		LOG_ERR("%s: Failed to set interface type to AP: %d", __func__, ret);
2164 		goto out;
2165 	}
2166 
2167 out:
2168 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2169 	return ret;
2170 }
2171 
wpas_cipher_to_nrf(int cipher)2172 static int wpas_cipher_to_nrf(int cipher)
2173 {
2174 	switch (cipher) {
2175 	case WPA_CIPHER_NONE:
2176 		return 0;
2177 	case WPA_CIPHER_WEP40:
2178 		return NRF_WIFI_FMAC_CIPHER_SUITE_WEP40;
2179 	case WPA_CIPHER_WEP104:
2180 		return NRF_WIFI_FMAC_CIPHER_SUITE_WEP104;
2181 	case WPA_CIPHER_TKIP:
2182 		return NRF_WIFI_FMAC_CIPHER_SUITE_TKIP;
2183 	case WPA_CIPHER_CCMP:
2184 		return NRF_WIFI_FMAC_CIPHER_SUITE_CCMP;
2185 	case WPA_CIPHER_CCMP_256:
2186 		return NRF_WIFI_FMAC_CIPHER_SUITE_CCMP_256;
2187 	default:
2188 		return -1;
2189 	}
2190 }
2191 
nrf_wifi_set_beacon_data(const struct wpa_driver_ap_params * params,struct nrf_wifi_beacon_data * beacon_data)2192 static int nrf_wifi_set_beacon_data(const struct wpa_driver_ap_params *params,
2193 		struct nrf_wifi_beacon_data *beacon_data)
2194 {
2195 	int ret = -1;
2196 
2197 	if (params->head_len > ARRAY_SIZE(beacon_data->head)) {
2198 		LOG_ERR("%s: head_len too big", __func__);
2199 		goto out;
2200 	}
2201 
2202 	if (params->tail_len > ARRAY_SIZE(beacon_data->tail)) {
2203 		LOG_ERR("%s: tail_len too big", __func__);
2204 		goto out;
2205 	}
2206 
2207 	if (params->proberesp_len > ARRAY_SIZE(beacon_data->probe_resp)) {
2208 		LOG_ERR("%s: proberesp_len too big", __func__);
2209 		goto out;
2210 	}
2211 
2212 	beacon_data->head_len = params->head_len;
2213 	beacon_data->tail_len = params->tail_len;
2214 	beacon_data->probe_resp_len = params->proberesp_len;
2215 
2216 	if (params->head_len) {
2217 		memcpy(&beacon_data->head, params->head,
2218 		       params->head_len);
2219 	}
2220 
2221 	if (params->tail_len) {
2222 		memcpy(&beacon_data->tail, params->tail,
2223 		       params->tail_len);
2224 	}
2225 
2226 	if (params->proberesp_len) {
2227 		memcpy(&beacon_data->probe_resp, params->proberesp_ies,
2228 		       params->proberesp_len);
2229 	}
2230 
2231 	ret = 0;
2232 out:
2233 	return ret;
2234 }
2235 
nrf_wifi_supp_register_mgmt_frame(void * if_priv,u16 frame_type,size_t match_len,const u8 * match)2236 int nrf_wifi_supp_register_mgmt_frame(void *if_priv,
2237 	u16 frame_type, size_t match_len, const u8 *match)
2238 {
2239 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2240 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2241 	struct nrf_wifi_umac_mgmt_frame_info mgmt_frame_info = {0};
2242 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2243 	int ret = -1;
2244 
2245 	if (!if_priv || (match_len && !match)) {
2246 		LOG_ERR("%s: Invalid params", __func__);
2247 		return ret;
2248 	}
2249 
2250 	vif_ctx_zep = if_priv;
2251 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2252 	if (!rpu_ctx_zep) {
2253 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
2254 		return ret;
2255 	}
2256 
2257 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2258 	if (!rpu_ctx_zep->rpu_ctx) {
2259 		LOG_DBG("%s: RPU context not initialized", __func__);
2260 		goto out;
2261 	}
2262 
2263 	mgmt_frame_info.frame_type = frame_type;
2264 	mgmt_frame_info.frame_match.frame_match_len = match_len;
2265 	if (match_len >= NRF_WIFI_FRAME_MATCH_MAX_LEN) {
2266 		LOG_ERR("%s: match_len too big: %d (max %d)", __func__, match_len,
2267 			NRF_WIFI_FRAME_MATCH_MAX_LEN);
2268 		goto out;
2269 	}
2270 	memcpy(mgmt_frame_info.frame_match.frame_match, match, match_len);
2271 
2272 	status = nrf_wifi_sys_fmac_mgmt_frame_reg(rpu_ctx_zep->rpu_ctx,
2273 					      vif_ctx_zep->vif_idx,
2274 					      &mgmt_frame_info);
2275 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2276 		LOG_ERR("%s: nrf_wifi_sys_fmac_mgmt_frame_reg failed", __func__);
2277 		goto out;
2278 	}
2279 
2280 	ret = 0;
2281 out:
2282 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2283 	return ret;
2284 }
2285 
2286 /* As per current design default is always STA */
is_ap_dynamic_iface(struct nrf_wifi_vif_ctx_zep * vif_ctx_zep)2287 static int is_ap_dynamic_iface(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep)
2288 {
2289 	return (vif_ctx_zep->vif_idx != 0);
2290 }
2291 
nrf_wifi_set_bss(struct nrf_wifi_vif_ctx_zep * vif_ctx_zep,struct wpa_driver_ap_params * params)2292 static int nrf_wifi_set_bss(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep,
2293 	 struct wpa_driver_ap_params *params)
2294 {
2295 	struct nrf_wifi_umac_bss_info bss_info = {0};
2296 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2297 	int ret = -1;
2298 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2299 	int i;
2300 
2301 	if (!vif_ctx_zep || !params) {
2302 		LOG_ERR("%s: Invalid params", __func__);
2303 		return ret;
2304 	}
2305 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2306 	if (!rpu_ctx_zep) {
2307 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
2308 		return ret;
2309 	}
2310 
2311 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2312 	if (!rpu_ctx_zep->rpu_ctx) {
2313 		LOG_DBG("%s: RPU context not initialized", __func__);
2314 		goto out;
2315 	}
2316 
2317 	if (params->basic_rates) {
2318 		for (i = 0; params->basic_rates[i] != -1; i++) {
2319 			if (i >= ARRAY_SIZE(bss_info.basic_rates)) {
2320 				LOG_ERR("%s: basic_rates too big: %d (max %d)", __func__, i,
2321 					ARRAY_SIZE(bss_info.basic_rates));
2322 				goto out;
2323 			}
2324 			bss_info.basic_rates[i] = params->basic_rates[i];
2325 		}
2326 		bss_info.num_basic_rates = i;
2327 	}
2328 	bss_info.p2p_go_ctwindow = params->p2p_go_ctwindow;
2329 	bss_info.ht_opmode = params->ht_opmode;
2330 	bss_info.nrf_wifi_cts = params->cts_protect;
2331 	bss_info.preamble = params->preamble;
2332 	bss_info.nrf_wifi_slot = params->short_slot_time;
2333 	bss_info.ap_isolate = params->isolate;
2334 
2335 	status = nrf_wifi_sys_fmac_set_bss(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &bss_info);
2336 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2337 		LOG_ERR("%s: nrf_wifi_sys_fmac_set_bss failed", __func__);
2338 		goto out;
2339 	}
2340 
2341 	ret = 0;
2342 out:
2343 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2344 	return ret;
2345 }
2346 
2347 
wpa_supp_chan_width_to_nrf(enum hostapd_hw_mode mode,int bandwidth,int cfreq1,int cfreq2)2348 static enum nrf_wifi_chan_width wpa_supp_chan_width_to_nrf(enum hostapd_hw_mode mode,
2349 	int bandwidth, int cfreq1, int cfreq2)
2350 {
2351 	switch (bandwidth) {
2352 	case 20:
2353 		if (mode == HOSTAPD_MODE_IEEE80211B) {
2354 			return NRF_WIFI_CHAN_WIDTH_20_NOHT;
2355 		} else {
2356 			return NRF_WIFI_CHAN_WIDTH_20;
2357 		};
2358 	case 40:
2359 		return NRF_WIFI_CHAN_WIDTH_40;
2360 	case 80:
2361 		if (cfreq2) {
2362 			return NRF_WIFI_CHAN_WIDTH_80P80;
2363 		} else {
2364 			return NRF_WIFI_CHAN_WIDTH_80;
2365 		}
2366 	case 160:
2367 		return NRF_WIFI_CHAN_WIDTH_160;
2368 	};
2369 
2370 	return NRF_WIFI_CHAN_WIDTH_20;
2371 }
2372 
nrf_wifi_wpa_supp_start_ap(void * if_priv,struct wpa_driver_ap_params * params)2373 int nrf_wifi_wpa_supp_start_ap(void *if_priv, struct wpa_driver_ap_params *params)
2374 {
2375 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2376 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2377 	int ret = -1;
2378 	struct nrf_wifi_umac_start_ap_info start_ap_info = {0};
2379 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2380 	int ch_width = 0;
2381 
2382 	if (!if_priv || !params) {
2383 		LOG_ERR("%s: Invalid params", __func__);
2384 		return ret;
2385 	}
2386 
2387 	vif_ctx_zep = if_priv;
2388 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2389 	if (!rpu_ctx_zep) {
2390 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
2391 		return ret;
2392 	}
2393 
2394 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2395 	if (!rpu_ctx_zep->rpu_ctx) {
2396 		LOG_DBG("%s: RPU context not initialized", __func__);
2397 		goto out;
2398 	}
2399 
2400 	nrf_wifi_set_beacon_data(params, &start_ap_info.beacon_data);
2401 	start_ap_info.beacon_interval = params->beacon_int;
2402 	start_ap_info.dtim_period = params->dtim_period;
2403 	start_ap_info.ssid.nrf_wifi_ssid_len = params->ssid_len;
2404 	memcpy(start_ap_info.ssid.nrf_wifi_ssid, params->ssid, params->ssid_len);
2405 	for (int i = 0; i < 32; i++) {
2406 		if ((params->pairwise_ciphers & BIT(i)) &&
2407 		    start_ap_info.connect_common_info.num_cipher_suites_pairwise < 7) {
2408 			if (wpas_cipher_to_nrf(i) < 0) {
2409 				LOG_DBG("%s: Unsupported cipher %d ignored", __func__, i);
2410 				continue;
2411 			}
2412 			start_ap_info.connect_common_info.cipher_suites_pairwise[i] =
2413 				wpas_cipher_to_nrf(i);
2414 			start_ap_info.connect_common_info.num_cipher_suites_pairwise++;
2415 		}
2416 	}
2417 
2418 	ch_width = wpa_supp_chan_width_to_nrf(params->freq->mode, params->freq->bandwidth,
2419 			params->freq->center_freq1, params->freq->center_freq2);
2420 
2421 	start_ap_info.freq_params.frequency = params->freq->freq;
2422 	start_ap_info.freq_params.channel_width = ch_width;
2423 	start_ap_info.freq_params.center_frequency1 = params->freq->center_freq1;
2424 	start_ap_info.freq_params.center_frequency2 = params->freq->center_freq2;
2425 	start_ap_info.freq_params.channel_type = params->freq->ht_enabled ? NRF_WIFI_CHAN_HT20 :
2426 						NRF_WIFI_CHAN_NO_HT;
2427 	start_ap_info.freq_params.valid_fields = NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID |
2428 		NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_WIDTH_VALID |
2429 		NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ1_VALID |
2430 		NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ2_VALID |
2431 		NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_TYPE_VALID;
2432 
2433 	vif_ctx_zep->if_carr_state = NRF_WIFI_FMAC_IF_CARR_STATE_OFF;
2434 	status = nrf_wifi_sys_fmac_start_ap(rpu_ctx_zep->rpu_ctx,
2435 					    vif_ctx_zep->vif_idx,
2436 					    &start_ap_info);
2437 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2438 		LOG_ERR("%s: nrf_wifi_sys_fmac_start_ap failed", __func__);
2439 		goto out;
2440 	}
2441 
2442 	ret = nrf_wifi_wait_for_carrier_status(vif_ctx_zep, NRF_WIFI_FMAC_IF_CARR_STATE_ON);
2443 	if (ret) {
2444 		goto out;
2445 	}
2446 
2447 	ret = nrf_wifi_set_bss(vif_ctx_zep, params);
2448 	if (ret) {
2449 		LOG_ERR("%s: Failed to set BSS", __func__);
2450 		goto out;
2451 	}
2452 
2453 	ret = 0;
2454 out:
2455 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2456 	return ret;
2457 }
2458 
nrf_wifi_wpa_supp_change_beacon(void * if_priv,struct wpa_driver_ap_params * params)2459 int nrf_wifi_wpa_supp_change_beacon(void *if_priv, struct wpa_driver_ap_params *params)
2460 {
2461 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2462 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2463 	int ret = -1;
2464 	struct nrf_wifi_umac_set_beacon_info chg_bcn_info = {0};
2465 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2466 
2467 	if (!if_priv || !params) {
2468 		LOG_ERR("%s: Invalid params", __func__);
2469 		return ret;
2470 	}
2471 
2472 	vif_ctx_zep = if_priv;
2473 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2474 	if (!rpu_ctx_zep) {
2475 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
2476 		return ret;
2477 	}
2478 
2479 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2480 	if (!rpu_ctx_zep->rpu_ctx) {
2481 		LOG_DBG("%s: RPU context not initialized", __func__);
2482 		goto out;
2483 	}
2484 
2485 	nrf_wifi_set_beacon_data(params, &chg_bcn_info.beacon_data);
2486 
2487 	status = nrf_wifi_sys_fmac_chg_bcn(rpu_ctx_zep->rpu_ctx,
2488 					   vif_ctx_zep->vif_idx,
2489 					   &chg_bcn_info);
2490 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2491 		LOG_ERR("%s: nrf_wifi_sys_fmac_chg_bcn failed", __func__);
2492 		goto out;
2493 	}
2494 
2495 	ret = 0;
2496 out:
2497 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2498 	return ret;
2499 }
2500 
nrf_wifi_wpa_supp_stop_ap(void * if_priv)2501 int nrf_wifi_wpa_supp_stop_ap(void *if_priv)
2502 {
2503 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2504 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2505 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2506 	int ret = -1;
2507 
2508 	if (!if_priv) {
2509 		LOG_ERR("%s: Invalid params", __func__);
2510 		return ret;
2511 	}
2512 
2513 	vif_ctx_zep = if_priv;
2514 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2515 	if (!rpu_ctx_zep) {
2516 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
2517 		return ret;
2518 	}
2519 
2520 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2521 	if (!rpu_ctx_zep->rpu_ctx) {
2522 		LOG_DBG("%s: RPU context not initialized", __func__);
2523 		goto out;
2524 	}
2525 
2526 	status = nrf_wifi_sys_fmac_stop_ap(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx);
2527 
2528 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2529 		LOG_ERR("%s: nrf_wifi_sys_fmac_stop_ap failed", __func__);
2530 		goto out;
2531 	}
2532 
2533 	ret = nrf_wifi_wait_for_carrier_status(vif_ctx_zep, NRF_WIFI_FMAC_IF_CARR_STATE_OFF);
2534 	if (ret) {
2535 		goto out;
2536 	}
2537 
2538 	ret = 0;
2539 out:
2540 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2541 	return ret;
2542 }
2543 
nrf_wifi_wpa_supp_deinit_ap(void * if_priv)2544 int nrf_wifi_wpa_supp_deinit_ap(void *if_priv)
2545 {
2546 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2547 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2548 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2549 	int ret = -1;
2550 
2551 	if (!if_priv) {
2552 		LOG_ERR("%s: Invalid params", __func__);
2553 		return ret;
2554 	}
2555 
2556 	vif_ctx_zep = if_priv;
2557 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2558 	if (!rpu_ctx_zep) {
2559 		LOG_DBG("%s: rpu_ctx_zep is NULL", __func__);
2560 		return ret;
2561 	}
2562 
2563 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2564 	if (!rpu_ctx_zep->rpu_ctx) {
2565 		LOG_DBG("%s: RPU context not initialized", __func__);
2566 		goto out;
2567 	}
2568 
2569 	status = nrf_wifi_wpa_supp_stop_ap(if_priv);
2570 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2571 		LOG_ERR("%s: Failed to stop AP", __func__);
2572 		goto out;
2573 	}
2574 
2575 	if (!is_ap_dynamic_iface(vif_ctx_zep)) {
2576 		ret = nrf_wifi_iftype_change(vif_ctx_zep, NRF_WIFI_IFTYPE_STATION);
2577 		if (ret) {
2578 			LOG_ERR("%s: Failed to set interface type to STATION: %d", __func__, ret);
2579 			goto out;
2580 		}
2581 	}
2582 	ret = 0;
2583 out:
2584 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2585 	return ret;
2586 }
2587 
nrf_wifi_sta_flags_to_nrf(int wpas_sta_flags)2588 int nrf_wifi_sta_flags_to_nrf(int wpas_sta_flags)
2589 {
2590 	int nrf_sta_flags = 0;
2591 
2592 	if (wpas_sta_flags & WPA_STA_AUTHORIZED) {
2593 		nrf_sta_flags |= NRF_WIFI_STA_FLAG_AUTHORIZED;
2594 	}
2595 	if (wpas_sta_flags & WPA_STA_WMM) {
2596 		nrf_sta_flags |= NRF_WIFI_STA_FLAG_WME;
2597 	}
2598 	if (wpas_sta_flags & WPA_STA_SHORT_PREAMBLE) {
2599 		nrf_sta_flags |= NRF_WIFI_STA_FLAG_SHORT_PREAMBLE;
2600 	}
2601 	if (wpas_sta_flags & WPA_STA_MFP) {
2602 		nrf_sta_flags |= NRF_WIFI_STA_FLAG_MFP;
2603 	}
2604 	if (wpas_sta_flags & WPA_STA_TDLS_PEER) {
2605 		nrf_sta_flags |= NRF_WIFI_STA_FLAG_TDLS_PEER;
2606 	}
2607 	/* Note: Do not set flags > NRF_WIFI_STA_FLAG_TDLS_PEER, else
2608 	 * nrf_wifi_sys_fmac_chg_sta will fail. This is equivalent to not
2609 	 * setting WPA_DRIVER_FLAGS_FULL_AP_CLIENT_STATE flag.
2610 	 */
2611 
2612 	return nrf_sta_flags;
2613 }
2614 
nrf_wifi_wpa_supp_sta_add(void * if_priv,struct hostapd_sta_add_params * params)2615 int nrf_wifi_wpa_supp_sta_add(void *if_priv, struct hostapd_sta_add_params *params)
2616 {
2617 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2618 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2619 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2620 	struct nrf_wifi_umac_add_sta_info sta_info = {0};
2621 	int ret = -1;
2622 	int i;
2623 
2624 	if (!if_priv || !params) {
2625 		LOG_ERR("%s: Invalid params", __func__);
2626 		return ret;
2627 	}
2628 
2629 	vif_ctx_zep = if_priv;
2630 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2631 	if (!rpu_ctx_zep) {
2632 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
2633 		return ret;
2634 	}
2635 
2636 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2637 	if (!rpu_ctx_zep->rpu_ctx) {
2638 		LOG_DBG("%s: RPU context not initialized", __func__);
2639 		goto out;
2640 	}
2641 
2642 	sta_info.nrf_wifi_listen_interval = params->listen_interval;
2643 	sta_info.aid = params->aid;
2644 	sta_info.sta_capability = params->capability;
2645 	sta_info.supp_rates.nrf_wifi_num_rates = params->supp_rates_len;
2646 	/* TODO: sta_info.supp_rates.band */
2647 	for (i = 0; i < params->supp_rates_len; i++) {
2648 		sta_info.supp_rates.rates[i] = params->supp_rates[i] & 0x7f;
2649 	}
2650 
2651 	sta_info.ext_capability.ext_capability_len = params->ext_capab_len;
2652 	if (params->ext_capab_len >= NRF_WIFI_EXT_CAPABILITY_MAX_LEN) {
2653 		LOG_ERR("%s: ext_capab_len too big: %d (max %d)", __func__,
2654 			params->ext_capab_len, NRF_WIFI_EXT_CAPABILITY_MAX_LEN);
2655 		goto out;
2656 	}
2657 	memcpy(sta_info.ext_capability.ext_capability, params->ext_capab,
2658 	       params->ext_capab_len);
2659 
2660 	sta_info.supported_channels.supported_channels_len = params->supp_channels_len;
2661 	if (params->supp_channels_len >= NRF_WIFI_SUPPORTED_CHANNELS_MAX_LEN) {
2662 		LOG_ERR("%s: supp_channels_len too big: %d (max %d)", __func__,
2663 			params->supp_channels_len, NRF_WIFI_SUPPORTED_CHANNELS_MAX_LEN);
2664 		goto out;
2665 	}
2666 	memcpy(sta_info.supported_channels.supported_channels, params->supp_channels,
2667 	       params->supp_channels_len);
2668 
2669 	sta_info.supported_oper_classes.supported_oper_classes_len = params->supp_oper_classes_len;
2670 	if (params->supp_oper_classes_len >= NRF_WIFI_OPER_CLASSES_MAX_LEN) {
2671 		LOG_ERR("%s: supp_oper_classes_len too big: %d (max %d)", __func__,
2672 			params->supp_oper_classes_len, NRF_WIFI_OPER_CLASSES_MAX_LEN);
2673 		goto out;
2674 	}
2675 	memcpy(sta_info.supported_oper_classes.supported_oper_classes, params->supp_oper_classes,
2676 	       params->supp_oper_classes_len);
2677 
2678 	sta_info.sta_flags2.nrf_wifi_set = nrf_wifi_sta_flags_to_nrf(params->flags);
2679 	sta_info.sta_flags2.nrf_wifi_mask = sta_info.sta_flags2.nrf_wifi_set |
2680 		nrf_wifi_sta_flags_to_nrf(params->flags_mask);
2681 
2682 	if (params->ht_capabilities) {
2683 		memcpy(sta_info.ht_capability,
2684 			   params->ht_capabilities,
2685 			   sizeof(sta_info.ht_capability));
2686 	}
2687 
2688 	if (params->vht_capabilities) {
2689 		memcpy(sta_info.vht_capability,
2690 			   params->vht_capabilities,
2691 			   sizeof(sta_info.vht_capability));
2692 	}
2693 
2694 	memcpy(sta_info.mac_addr, params->addr, sizeof(sta_info.mac_addr));
2695 
2696 	LOG_DBG("%s: %x, %x", __func__,
2697 		sta_info.sta_flags2.nrf_wifi_set, sta_info.sta_flags2.nrf_wifi_mask);
2698 
2699 	if (params->set) {
2700 		status = nrf_wifi_sys_fmac_chg_sta(rpu_ctx_zep->rpu_ctx,
2701 					vif_ctx_zep->vif_idx,
2702 					(struct nrf_wifi_umac_chg_sta_info *)&sta_info);
2703 	} else {
2704 		status = nrf_wifi_sys_fmac_add_sta(rpu_ctx_zep->rpu_ctx,
2705 					vif_ctx_zep->vif_idx,
2706 					&sta_info);
2707 	}
2708 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2709 		LOG_ERR("%s: nrf_wifi_sys_fmac_add_sta failed", __func__);
2710 		goto out;
2711 	}
2712 
2713 	ret = 0;
2714 out:
2715 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2716 	return ret;
2717 }
2718 
nrf_wifi_wpa_supp_sta_remove(void * if_priv,const u8 * addr)2719 int nrf_wifi_wpa_supp_sta_remove(void *if_priv, const u8 *addr)
2720 {
2721 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2722 	struct nrf_wifi_umac_del_sta_info del_sta = {0};
2723 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2724 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2725 	int ret = -1;
2726 
2727 	if (!if_priv || !addr) {
2728 		LOG_ERR("%s: Invalid params", __func__);
2729 		return ret;
2730 	}
2731 
2732 	vif_ctx_zep = if_priv;
2733 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2734 	if (!rpu_ctx_zep) {
2735 		LOG_DBG("%s: rpu_ctx_zep is NULL", __func__);
2736 		return ret;
2737 	}
2738 
2739 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2740 	if (!rpu_ctx_zep->rpu_ctx) {
2741 		LOG_DBG("%s: RPU context not initialized", __func__);
2742 		goto out;
2743 	}
2744 
2745 	memcpy(del_sta.mac_addr, addr, sizeof(del_sta.mac_addr));
2746 
2747 	status = nrf_wifi_sys_fmac_del_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &del_sta);
2748 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2749 		LOG_ERR("%s: nrf_wifi_sys_fmac_del_sta failed", __func__);
2750 		goto out;
2751 	}
2752 
2753 	ret = 0;
2754 
2755 out:
2756 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2757 	return ret;
2758 }
2759 
nrf_wifi_wpa_supp_sta_set_flags(void * if_priv,const u8 * addr,unsigned int total_flags,unsigned int flags_or,unsigned int flags_and)2760 int nrf_wifi_wpa_supp_sta_set_flags(void *if_priv, const u8 *addr,
2761 			unsigned int total_flags, unsigned int flags_or,
2762 			unsigned int flags_and)
2763 {
2764 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2765 	struct nrf_wifi_umac_chg_sta_info chg_sta = {0};
2766 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2767 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2768 	int ret = -1;
2769 
2770 	if (!if_priv || !addr) {
2771 		LOG_ERR("%s: Invalid params", __func__);
2772 		return ret;
2773 	}
2774 
2775 	vif_ctx_zep = if_priv;
2776 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2777 	if (!rpu_ctx_zep) {
2778 		LOG_DBG("%s: rpu_ctx_zep is NULL", __func__);
2779 		return ret;
2780 	}
2781 
2782 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2783 	if (!rpu_ctx_zep->rpu_ctx) {
2784 		LOG_DBG("%s: RPU context not initialized", __func__);
2785 		goto out;
2786 	}
2787 
2788 	memcpy(chg_sta.mac_addr, addr, sizeof(chg_sta.mac_addr));
2789 
2790 	chg_sta.sta_flags2.nrf_wifi_mask = nrf_wifi_sta_flags_to_nrf(flags_or | ~flags_and);
2791 	chg_sta.sta_flags2.nrf_wifi_set = nrf_wifi_sta_flags_to_nrf(flags_or);
2792 
2793 	LOG_DBG("%s %x, %x", __func__,
2794 		chg_sta.sta_flags2.nrf_wifi_set, chg_sta.sta_flags2.nrf_wifi_mask);
2795 
2796 	status = nrf_wifi_sys_fmac_chg_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &chg_sta);
2797 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2798 		LOG_ERR("%s: nrf_wifi_sys_fmac_chg_sta failed", __func__);
2799 		goto out;
2800 	}
2801 
2802 	ret = 0;
2803 
2804 out:
2805 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2806 	return ret;
2807 }
2808 
nrf_wifi_wpa_supp_sta_get_inact_sec(void * if_priv,const u8 * addr)2809 int nrf_wifi_wpa_supp_sta_get_inact_sec(void *if_priv, const u8 *addr)
2810 {
2811 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
2812 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
2813 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
2814 	int ret = -1, sem_ret;
2815 	int inactive_time_sec = -1;
2816 
2817 	if (!if_priv || !addr) {
2818 		LOG_ERR("%s: Invalid params", __func__);
2819 		return ret;
2820 	}
2821 
2822 	vif_ctx_zep = if_priv;
2823 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
2824 	if (!rpu_ctx_zep) {
2825 		LOG_DBG("%s: rpu_ctx_zep is NULL", __func__);
2826 		return ret;
2827 	}
2828 
2829 	k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
2830 	if (!rpu_ctx_zep->rpu_ctx) {
2831 		LOG_DBG("%s: RPU context not initialized", __func__);
2832 		goto out;
2833 	}
2834 
2835 	status = nrf_wifi_sys_fmac_get_station(rpu_ctx_zep->rpu_ctx,
2836 					       vif_ctx_zep->vif_idx,
2837 					       (unsigned char *) addr);
2838 	if (status != NRF_WIFI_STATUS_SUCCESS) {
2839 		LOG_ERR("%s: nrf_wifi_sys_fmac_get_station failed", __func__);
2840 		goto out;
2841 	}
2842 
2843 	sem_ret = k_sem_take(&wait_for_event_sem, K_MSEC(RPU_RESP_EVENT_TIMEOUT));
2844 	if (sem_ret) {
2845 		LOG_ERR("%s: Timed out to get station info, ret = %d", __func__, sem_ret);
2846 		ret = NRF_WIFI_STATUS_FAIL;
2847 		goto out;
2848 	}
2849 
2850 	inactive_time_sec = vif_ctx_zep->inactive_time_sec;
2851 out:
2852 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
2853 	return inactive_time_sec;
2854 }
2855 #endif /* CONFIG_NRF70_AP_MODE */
2856