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, ®_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, ®_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