1 /** @file rtos_wpa_supp_if.c
2 *
3 * @brief This file provides RTOS WPA Supplicant interface wifi APIs
4 *
5 *
6 * Copyright 2008-2024 NXP
7 *
8 * SPDX-License-Identifier: BSD-3-Clause
9 *
10 */
11
12 #include <stdlib.h>
13 #include "fsl_os_abstraction.h"
14 #include "wifi.h"
15 #include <wm_net.h>
16
17 #if CONFIG_WPA_SUPP
18
19 #include "rtos_wpa_supp_if.h"
20 #include "wifi-internal.h"
21 #include "supp_main.h"
22
23 #define MAX_MGMT_TX_FRAME_SIZE 1500
24
25 static uint8_t *g_extended_capa = NULL;
26 static uint8_t *g_extended_capa_mask = NULL;
27
get_algo_from_auth_type(int wpa_auth_alg)28 static unsigned char get_algo_from_auth_type(int wpa_auth_alg)
29 {
30 if (wpa_auth_alg & WPA_AUTH_ALG_OPEN)
31 {
32 return MLAN_AUTH_MODE_OPEN;
33 }
34 if (wpa_auth_alg & WPA_AUTH_ALG_SHARED)
35 {
36 return MLAN_AUTH_MODE_SHARED;
37 }
38 if (wpa_auth_alg & WPA_AUTH_ALG_LEAP)
39 {
40 return MLAN_AUTH_MODE_NETWORKEAP;
41 }
42 if (wpa_auth_alg & WPA_AUTH_ALG_FT)
43 {
44 return MLAN_AUTH_MODE_FT;
45 }
46 if (wpa_auth_alg & WPA_AUTH_ALG_SAE)
47 {
48 return MLAN_AUTH_MODE_SAE;
49 }
50
51 return MLAN_AUTH_MODE_AUTO;
52 }
53
wpa_alg_to_cipher_suite(enum wpa_alg alg,size_t key_len)54 static unsigned int wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
55 {
56 unsigned flags = 0;
57
58 if (alg == WPA_ALG_GCMP)
59 {
60 flags |= KEY_FLAG_GCMP;
61 }
62 else if (alg == WPA_ALG_GCMP_256)
63 {
64 flags |= KEY_FLAG_GCMP_256;
65 }
66
67 if (alg == WPA_ALG_CCMP_256)
68 {
69 flags |= KEY_FLAG_CCMP_256;
70 }
71
72 if ((alg == WPA_ALG_BIP_CMAC_128) || (alg == WPA_ALG_BIP_CMAC_256) || (alg == WPA_ALG_BIP_GMAC_128) ||
73 (alg == WPA_ALG_BIP_GMAC_256))
74 {
75 flags |= KEY_FLAG_AES_MCAST_IGTK;
76
77 if (alg == WPA_ALG_BIP_GMAC_128)
78 {
79 flags |= KEY_FLAG_GMAC_128;
80 }
81 else if (alg == WPA_ALG_BIP_GMAC_256)
82 {
83 flags |= KEY_FLAG_GMAC_256;
84 }
85 }
86
87 return flags;
88 }
89
wifi_nxp_wpa_supp_event_proc_mac_changed(void * if_priv)90 void wifi_nxp_wpa_supp_event_proc_mac_changed(void *if_priv)
91 {
92 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
93
94 if (!if_priv)
95 {
96 supp_e("%s: Missing interface context", __func__);
97 return;
98 }
99
100 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
101
102 #ifdef CONFIG_WPA_SUPP_AP
103 if (wifi_if_ctx_rtos->hostapd)
104 {
105 wifi_if_ctx_rtos->hostapd_callbk_fns.mac_changed(wifi_if_ctx_rtos->hapd_drv_if_ctx);
106 }
107 else
108 #endif
109 {
110 wifi_if_ctx_rtos->supp_callbk_fns.mac_changed(wifi_if_ctx_rtos->supp_drv_if_ctx);
111 }
112 }
113
114 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
drv2supp_chan_width(int width)115 static enum chan_width drv2supp_chan_width(int width)
116 {
117 switch (width) {
118 case NXP_WIFI_CHAN_WIDTH_20_NOHT:
119 return CHAN_WIDTH_20_NOHT;
120 case NXP_WIFI_CHAN_WIDTH_20:
121 return CHAN_WIDTH_20;
122 case NXP_WIFI_CHAN_WIDTH_40:
123 return CHAN_WIDTH_40;
124 case NXP_WIFI_CHAN_WIDTH_80:
125 return CHAN_WIDTH_80;
126 case NXP_WIFI_CHAN_WIDTH_80P80:
127 return CHAN_WIDTH_80P80;
128 case NXP_WIFI_CHAN_WIDTH_160:
129 return CHAN_WIDTH_160;
130 default:
131 break;
132 }
133 return CHAN_WIDTH_UNKNOWN;
134 }
135 #endif
136
wifi_nxp_wpa_supp_event_proc_chan_list_changed(void * if_priv,const char * alpha2)137 void wifi_nxp_wpa_supp_event_proc_chan_list_changed(void *if_priv, const char *alpha2)
138 {
139 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
140 union wpa_event_data event;
141
142 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
143
144 if (!if_priv)
145 {
146 supp_e("%s: Missing interface context", __func__);
147 return;
148 }
149
150 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
151
152 memset(&event, 0, sizeof(event));
153
154 if (!alpha2)
155 {
156 supp_e("%s: Missing alpha2 data", __func__);
157 return;
158 }
159
160 event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
161 event.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
162 event.channel_list_changed.alpha2[0] = alpha2[0];
163 event.channel_list_changed.alpha2[1] = alpha2[1];
164 event.channel_list_changed.alpha2[2] = alpha2[2];
165
166 #if CONFIG_WPA_SUPP_AP
167 if (wifi_if_ctx_rtos->hostapd)
168 {
169 wifi_if_ctx_rtos->hostapd_callbk_fns.chan_list_changed(wifi_if_ctx_rtos->hapd_drv_if_ctx, &event);
170 }
171 else
172 #endif
173 {
174 wifi_if_ctx_rtos->supp_callbk_fns.chan_list_changed(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
175 }
176 }
177
wifi_nxp_wpa_supp_event_proc_scan_start(void * if_priv)178 void wifi_nxp_wpa_supp_event_proc_scan_start(void *if_priv)
179 {
180 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
181 struct os_time t;
182
183 if (!if_priv)
184 {
185 supp_e("%s: Missing interface context", __func__);
186 return;
187 }
188
189 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
190
191 os_get_time(&t);
192
193 memcpy(&wifi_if_ctx_rtos->scan_start_tsf_bssid, &wifi_if_ctx_rtos->assoc_bssid, ETH_ALEN);
194
195 wifi_if_ctx_rtos->scan_start_tsf = t.sec * 1000;
196
197 if (wifi_if_ctx_rtos->supp_callbk_fns.scan_start)
198 {
199 wifi_if_ctx_rtos->supp_callbk_fns.scan_start(wifi_if_ctx_rtos->supp_drv_if_ctx);
200 }
201 }
202
wifi_nxp_wpa_supp_event_proc_scan_done(void * if_priv,int aborted,int external_scan)203 void wifi_nxp_wpa_supp_event_proc_scan_done(void *if_priv, int aborted, int external_scan)
204 {
205 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
206 union wpa_event_data event;
207 struct scan_info *info = NULL;
208
209 if (!if_priv)
210 {
211 supp_e("%s: Missing interface context", __func__);
212 return;
213 }
214
215 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
216
217 memset(&event, 0, sizeof(event));
218
219 info = &event.scan_info;
220 info->aborted = aborted;
221 info->external_scan = external_scan;
222 info->nl_scan_event = 1;
223
224 memcpy(&info->scan_start_tsf, &wifi_if_ctx_rtos->scan_start_tsf, sizeof(info->scan_start_tsf));
225
226 memcpy(&info->scan_start_tsf_bssid, &wifi_if_ctx_rtos->scan_start_tsf_bssid, ETH_ALEN);
227
228 wifi_if_ctx_rtos->scan_in_progress = false;
229
230 wifi_nxp_reset_scan_flag();
231
232 #if CONFIG_WPA_SUPP_AP
233 if (wifi_if_ctx_rtos->hostapd)
234 {
235 wifi_if_ctx_rtos->hostapd_callbk_fns.scan_done(wifi_if_ctx_rtos->hapd_drv_if_ctx, &event);
236 }
237 else
238 #endif
239 {
240 wifi_if_ctx_rtos->supp_callbk_fns.scan_done(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
241 }
242 }
243
244 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
wifi_nxp_wpa_supp_event_proc_survey_res(void * if_priv,nxp_wifi_event_new_survey_result_t * survey_res,unsigned int event_len,bool more_res)245 void wifi_nxp_wpa_supp_event_proc_survey_res(void *if_priv,
246 nxp_wifi_event_new_survey_result_t *survey_res,
247 unsigned int event_len,
248 bool more_res)
249 {
250 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
251 struct freq_survey *survey = NULL;
252
253 if (!if_priv)
254 {
255 supp_e("%s: Missing interface context", __func__);
256 return;
257 }
258
259 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
260
261 if (survey_res == NULL)
262 {
263 #if CONFIG_WPA_SUPP_AP
264 if (wifi_if_ctx_rtos->hostapd)
265 {
266 wifi_if_ctx_rtos->hostapd_callbk_fns.survey_res(wifi_if_ctx_rtos->hapd_drv_if_ctx, survey, more_res);
267 }
268 else
269 #endif
270 {
271 wifi_if_ctx_rtos->supp_callbk_fns.survey_res(wifi_if_ctx_rtos->supp_drv_if_ctx, survey, more_res);
272 }
273 return;
274 }
275
276 survey = (struct freq_survey *)OSA_MemoryAllocate(sizeof(*survey));
277
278 if (!survey)
279 {
280 supp_e("%s: Unable to calloc memory for survey result\n", __func__);
281 return;
282 }
283
284 survey->freq = survey_res->freq;
285
286 if (survey_res->nf)
287 {
288 survey->nf = survey_res->nf;
289 survey->filled |= SURVEY_HAS_NF;
290 }
291
292 if (survey_res->channel_time)
293 {
294 (void)memcpy((void *)&survey->channel_time, (const void *)&survey_res->channel_time,
295 sizeof(survey->channel_time));
296 survey->filled |= SURVEY_HAS_CHAN_TIME;
297 }
298
299 if (survey_res->channel_time_busy)
300 {
301 (void)memcpy((void *)&survey->channel_time_busy, (const void *)&survey_res->channel_time_busy,
302 sizeof(survey->channel_time_busy));
303 survey->filled |= SURVEY_HAS_CHAN_TIME_BUSY;
304 }
305
306 if (survey_res->channel_time_rx)
307 {
308 (void)memcpy((void *)&survey->channel_time_rx, (const void *)&survey_res->channel_time_rx,
309 sizeof(survey->channel_time_rx));
310 survey->filled |= SURVEY_HAS_CHAN_TIME_RX;
311 }
312
313 if (survey_res->channel_time_tx)
314 {
315 (void)memcpy((void *)&survey->channel_time_tx, (const void *)&survey_res->channel_time_tx,
316 sizeof(survey->channel_time_tx));
317 survey->filled |= SURVEY_HAS_CHAN_TIME_TX;
318 }
319
320 #if CONFIG_WPA_SUPP_AP
321 if (wifi_if_ctx_rtos->hostapd)
322 {
323 wifi_if_ctx_rtos->hostapd_callbk_fns.survey_res(wifi_if_ctx_rtos->hapd_drv_if_ctx, survey, more_res);
324 }
325 else
326 #endif
327 {
328 wifi_if_ctx_rtos->supp_callbk_fns.survey_res(wifi_if_ctx_rtos->supp_drv_if_ctx, survey, more_res);
329 }
330 }
331 #endif
332
wifi_nxp_wpa_supp_free_pairwise_key_params(struct wpa_driver_set_key_params * params)333 static void wifi_nxp_wpa_supp_free_pairwise_key_params(struct wpa_driver_set_key_params *params)
334 {
335 if (params->ifname)
336 {
337 os_free((void *)params->ifname);
338 }
339
340 if (params->addr)
341 {
342 os_free((void *)params->addr);
343 }
344
345 if (params->seq)
346 {
347 os_free((void *)params->seq);
348 }
349
350 if (params->key)
351 {
352 os_free((void *)params->key);
353 }
354
355 os_free(params);
356 }
357
wifi_nxp_wpa_supp_event_proc_auth_resp(void * if_priv,nxp_wifi_event_mlme_t * auth_resp,unsigned int event_len)358 void wifi_nxp_wpa_supp_event_proc_auth_resp(void *if_priv, nxp_wifi_event_mlme_t *auth_resp, unsigned int event_len)
359 {
360 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
361 union wpa_event_data event;
362 const struct ieee80211_mgmt *mgmt = NULL;
363 const unsigned char *frame = NULL;
364 unsigned int frame_len = 0;
365
366 if (!if_priv)
367 {
368 supp_e("%s: Missing interface context", __func__);
369 return;
370 }
371
372 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
373
374 frame = (const unsigned char *)auth_resp->frame.frame;
375 frame_len = auth_resp->frame.frame_len;
376 mgmt = (const struct ieee80211_mgmt *)frame;
377
378 if (frame_len < 4 + (2 * WIFI_ETH_ADDR_LEN))
379 {
380 supp_e("%s: MLME event too short", __func__);
381 return;
382 }
383
384 if (frame_len < 24 + sizeof(mgmt->u.auth))
385 {
386 supp_e("%s: Authentication response frame too short", __func__);
387 return;
388 }
389
390 memset(&event, 0, sizeof(event));
391
392 memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
393
394 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
395
396 event.auth.auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
397
398 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
399
400 if (frame_len > 24 + sizeof(mgmt->u.auth))
401 {
402 event.auth.ies = mgmt->u.auth.variable;
403 event.auth.ies_len = (frame_len - 24 - sizeof(mgmt->u.auth));
404 }
405
406 wifi_if_ctx_rtos->supp_callbk_fns.auth_resp(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
407 }
408
wifi_nxp_wpa_supp_event_proc_assoc_resp(void * if_priv,nxp_wifi_assoc_event_mlme_t * assoc_resp,unsigned int event_len)409 void wifi_nxp_wpa_supp_event_proc_assoc_resp(void *if_priv,
410 nxp_wifi_assoc_event_mlme_t *assoc_resp,
411 unsigned int event_len)
412 {
413 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
414 union wpa_event_data event;
415 const struct ieee80211_mgmt *mgmt = NULL;
416 const unsigned char *frame = NULL;
417 const unsigned char *req_frame = NULL;
418 const unsigned char *bssid = NULL;
419 unsigned int frame_len = 0;
420 unsigned short status = WLAN_STATUS_UNSPECIFIED_FAILURE;
421 enum sta_connect_fail_reason_codes reason_code = STA_CONNECT_FAIL_REASON_UNSPECIFIED;
422
423 if (!if_priv)
424 {
425 supp_e("%s: Missing interface context", __func__);
426 return;
427 }
428
429 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
430
431 frame = (const unsigned char *)assoc_resp->frame.frame;
432 frame_len = assoc_resp->frame.frame_len;
433 req_frame = (const unsigned char *)assoc_resp->req_ie;
434
435 mgmt = (const struct ieee80211_mgmt *)frame;
436
437 memset(&event, 0, sizeof(event));
438 memset(&wifi_if_ctx_rtos->assoc_bssid, 0, ETH_ALEN);
439
440 if (frame_len < 24 + sizeof(mgmt->u.assoc_resp))
441 {
442 supp_d("%s: Association response frame too short", __func__);
443 bssid = (unsigned char *)&wifi_if_ctx_rtos->attempt_bssid;
444 reason_code = STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED;
445 goto fail;
446 }
447
448 status = le_to_host16(mgmt->u.assoc_resp.status_code);
449
450 bssid = mgmt->bssid;
451
452 if (status != WLAN_STATUS_SUCCESS)
453 {
454 fail:
455 wifi_if_ctx_rtos->associated = false;
456 event.assoc_reject.bssid = bssid;
457
458 if (frame_len > 24 + sizeof(mgmt->u.assoc_resp))
459 {
460 event.assoc_reject.resp_ies = (unsigned char *)mgmt->u.assoc_resp.variable;
461 event.assoc_reject.resp_ies_len = (frame_len - 24 - sizeof(mgmt->u.assoc_resp));
462 }
463
464 event.assoc_reject.status_code = status;
465 event.assoc_reject.reason_code = reason_code;
466 event.assoc_reject.timeout_reason = NULL;
467 if (wifi_if_ctx_rtos->ft_roaming)
468 {
469 wifi_if_ctx_rtos->ft_roaming = false;
470 wifi_nxp_wpa_supp_free_pairwise_key_params(wifi_if_ctx_rtos->key_params);
471 wifi_if_ctx_rtos->key_params = NULL;
472 }
473 }
474 else
475 {
476 wifi_if_ctx_rtos->associated = true;
477 memcpy(&wifi_if_ctx_rtos->assoc_bssid, mgmt->bssid, ETH_ALEN);
478
479 event.assoc_info.addr = mgmt->bssid;
480 event.assoc_info.resp_frame = frame;
481 event.assoc_info.resp_frame_len = frame_len;
482 event.assoc_info.freq = wifi_if_ctx_rtos->assoc_freq;
483
484 if (frame_len > 24 + sizeof(mgmt->u.assoc_resp))
485 {
486 event.assoc_info.resp_ies = (unsigned char *)mgmt->u.assoc_resp.variable;
487 event.assoc_info.resp_ies_len = (frame_len - 24 - sizeof(mgmt->u.assoc_resp));
488 }
489 if (assoc_resp->req_ie_len)
490 {
491 event.assoc_info.req_ies = (unsigned char *)req_frame;
492 event.assoc_info.req_ies_len = assoc_resp->req_ie_len;
493 }
494 }
495
496 wifi_if_ctx_rtos->supp_callbk_fns.assoc_resp(wifi_if_ctx_rtos->supp_drv_if_ctx, &event, status);
497 }
498
wifi_nxp_wpa_supp_event_proc_deauth(void * if_priv,nxp_wifi_event_mlme_t * deauth,unsigned int event_len)499 void wifi_nxp_wpa_supp_event_proc_deauth(void *if_priv, nxp_wifi_event_mlme_t *deauth, unsigned int event_len)
500 {
501 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
502 union wpa_event_data event;
503 const struct ieee80211_mgmt *mgmt = NULL;
504 const unsigned char *frame = NULL;
505 unsigned int frame_len = 0;
506
507 if (!if_priv)
508 {
509 supp_e("%s: Missing interface context", __func__);
510 return;
511 }
512
513 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
514
515 frame = (const unsigned char *)deauth->frame.frame;
516 frame_len = deauth->frame.frame_len;
517 mgmt = (const struct ieee80211_mgmt *)frame;
518
519 if (frame_len < 24 + sizeof(mgmt->u.deauth))
520 {
521 supp_e("%s: Deauthentication response frame too short", __func__);
522 return;
523 }
524
525 memset(&event, 0, sizeof(event));
526
527 event.deauth_info.addr = &mgmt->sa[0];
528 event.deauth_info.reason_code = le_to_host16(WLAN_REASON_DEAUTH_LEAVING);
529 if (frame + frame_len > mgmt->u.deauth.variable)
530 {
531 event.deauth_info.ie = mgmt->u.deauth.variable;
532 event.deauth_info.ie_len = (frame + frame_len - mgmt->u.deauth.variable);
533 }
534
535 (void)wifi_event_completion(WIFI_EVENT_DEAUTHENTICATION, le_to_host16(mgmt->u.deauth.reason_code), NULL);
536
537 wifi_if_ctx_rtos->supp_callbk_fns.deauth(wifi_if_ctx_rtos->supp_drv_if_ctx, &event, mgmt);
538 }
539
wifi_nxp_wpa_supp_event_proc_disassoc(void * if_priv,nxp_wifi_event_mlme_t * disassoc,unsigned int event_len)540 void wifi_nxp_wpa_supp_event_proc_disassoc(void *if_priv, nxp_wifi_event_mlme_t *disassoc, unsigned int event_len)
541 {
542 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
543 union wpa_event_data event;
544 const struct ieee80211_mgmt *mgmt = NULL;
545 const unsigned char *frame = NULL;
546 unsigned int frame_len = 0;
547
548 if (!if_priv)
549 {
550 supp_e("%s: Missing interface context", __func__);
551 return;
552 }
553
554 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
555
556 frame = (const unsigned char *)disassoc->frame.frame;
557 frame_len = disassoc->frame.frame_len;
558 mgmt = (const struct ieee80211_mgmt *)frame;
559
560 if (frame_len < 24 + sizeof(mgmt->u.disassoc))
561 {
562 supp_e("%s: Dis-association response frame too short", __func__);
563 return;
564 }
565
566 memset(&event, 0, sizeof(event));
567
568 event.disassoc_info.addr = &mgmt->sa[0];
569 event.disassoc_info.reason_code = le_to_host16(mgmt->u.disassoc.reason_code);
570 if (frame + frame_len > mgmt->u.disassoc.variable)
571 {
572 event.disassoc_info.ie = mgmt->u.disassoc.variable;
573 event.disassoc_info.ie_len = (frame + frame_len - mgmt->u.disassoc.variable);
574 }
575
576 wifi_if_ctx_rtos->supp_callbk_fns.disassoc(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
577 }
578
579 #if 0
580 void wifi_nxp_wpa_supp_event_proc_remain_on_channel(void *if_priv, int cancel_channel)
581 {
582 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
583 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
584 union wpa_event_data event;
585 os_memset(&event, 0, sizeof(event));
586 event.remain_on_channel.freq = wifi_if_ctx_rtos->remain_on_channel_freq;
587 event.remain_on_channel.duration = wifi_if_ctx_rtos->remain_on_channel_duration;
588 wifi_if_ctx_rtos->supp_callbk_fns.remain_on_channel(wifi_if_ctx_rtos->supp_drv_if_ctx, cancel_channel, &event);
589 }
590 #endif
591
wifi_nxp_supp_state(void)592 int wifi_nxp_supp_state(void)
593 {
594 struct net_if *iface = (struct net_if *)(void *)net_get_sta_interface();
595 struct wpa_supplicant *wpa_s;
596 char if_name[CONFIG_NET_INTERFACE_NAME_LEN + 1];
597 int ret;
598
599 if (!get_supp_ready_state())
600 {
601 return 0;
602 }
603
604 ret = net_if_get_name(iface, if_name, sizeof(if_name));
605 if (!ret) {
606 supp_e("Cannot get interface name (%d)", ret);
607 return 0;
608 }
609
610 wpa_s = zephyr_get_handle_by_ifname(if_name);
611 if (!wpa_s) {
612 supp_e("Interface %s not found", if_name);
613 return 0;
614 }
615
616 return wpa_s->wpa_state;
617 }
618
wifi_nxp_hapd_state(void)619 int wifi_nxp_hapd_state(void)
620 {
621 #if CONFIG_WIFI_NM_HOSTAPD_AP
622 struct net_if *iface = (struct net_if *)(void *)net_get_uap_interface();
623 struct hostapd_iface *hapd_if;
624 char if_name[CONFIG_NET_INTERFACE_NAME_LEN + 1];
625 int ret;
626
627 ret = net_if_get_name(iface, if_name, sizeof(if_name));
628 if (!ret) {
629 supp_e("Cannot get interface name (%d)", ret);
630 return 0;
631 }
632
633 hapd_if = zephyr_get_hapd_handle_by_ifname(if_name);
634 if (!hapd_if) {
635 supp_e("Interface %s not found", if_name);
636 return 0;
637 }
638
639 return hapd_if->state;
640 #else
641 return 0;
642 #endif
643 }
644
wifi_nxp_wpa_supp_dev_init(void * supp_drv_if_ctx,const char * iface_name,rtos_wpa_supp_dev_callbk_fns * supp_callbk_fns)645 void *wifi_nxp_wpa_supp_dev_init(void *supp_drv_if_ctx,
646 const char *iface_name,
647 rtos_wpa_supp_dev_callbk_fns *supp_callbk_fns)
648 {
649 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
650 const struct netif *iface = NULL;
651 u8 extended_capa[10] = {0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
652 u8 extended_capa_mask[10] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
653
654 iface = net_if_get_binding(iface_name);
655
656 if (!iface)
657 {
658 supp_e("%s: Interface %s not found", __func__, iface_name);
659 return NULL;
660 }
661
662 if (strstr(iface_name, "ml"))
663 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)wm_wifi.if_priv;
664 else
665 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)wm_wifi.hapd_if_priv;
666
667 if (!wifi_if_ctx_rtos)
668 {
669 supp_e("%s: Interface %s not properly initialized", __func__, iface_name);
670 return NULL;
671 }
672
673 memset(wifi_if_ctx_rtos, 0x00, sizeof(struct wifi_nxp_ctx_rtos));
674
675 wifi_if_ctx_rtos->iface_ctx = iface;
676 wifi_if_ctx_rtos->supp_drv_if_ctx = supp_drv_if_ctx;
677
678 if (strstr(iface_name, "ml"))
679 {
680 wifi_if_ctx_rtos->bss_type = BSS_TYPE_STA;
681 }
682 else
683 {
684 wifi_if_ctx_rtos->bss_type = BSS_TYPE_UAP;
685 }
686 wifi_if_ctx_rtos->last_mgmt_tx_data = (uint8_t *)OSA_MemoryAllocate(MAX_MGMT_TX_FRAME_SIZE);
687
688 if (!wifi_if_ctx_rtos->last_mgmt_tx_data)
689 {
690 supp_e("%s: Buffer to store mgmt tx failed", __func__);
691 return NULL;
692 }
693
694 g_extended_capa = (uint8_t *)OSA_MemoryAllocate(sizeof(extended_capa));
695 if (g_extended_capa)
696 {
697 os_memcpy(g_extended_capa, extended_capa, sizeof(extended_capa));
698 }
699
700 g_extended_capa_mask = (uint8_t *)OSA_MemoryAllocate(sizeof(extended_capa_mask));
701 if (g_extended_capa_mask)
702 {
703 os_memcpy(g_extended_capa_mask, extended_capa_mask, sizeof(extended_capa_mask));
704 }
705
706 memcpy(&wifi_if_ctx_rtos->supp_callbk_fns, supp_callbk_fns, sizeof(wifi_if_ctx_rtos->supp_callbk_fns));
707 return wifi_if_ctx_rtos;
708 }
709
wifi_nxp_wpa_supp_dev_deinit(void * if_priv)710 void wifi_nxp_wpa_supp_dev_deinit(void *if_priv)
711 {
712 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
713
714 if (wifi_if_ctx_rtos != NULL)
715 {
716 if (wifi_if_ctx_rtos->last_mgmt_tx_data != NULL)
717 {
718 OSA_MemoryFree(wifi_if_ctx_rtos->last_mgmt_tx_data);
719 }
720 memset(wifi_if_ctx_rtos, 0x00, sizeof(struct wifi_nxp_ctx_rtos));
721 }
722
723 if (g_extended_capa != NULL)
724 {
725 OSA_MemoryFree(g_extended_capa);
726 g_extended_capa = NULL;
727 }
728
729 if (g_extended_capa_mask != NULL)
730 {
731 OSA_MemoryFree(g_extended_capa_mask);
732 g_extended_capa_mask = NULL;
733 }
734 }
735
wifi_nxp_sort_channels(t_u8 channels[],unsigned char num_chans)736 static void wifi_nxp_sort_channels(t_u8 channels[], unsigned char num_chans)
737 {
738 t_u8 i, j;
739
740 /* Bubble sort */
741 for (i = 0; i < num_chans; i++)
742 {
743 for (j = 1; j < num_chans - i; j++)
744 {
745 if ((t_u8)channels[j - 1] > (t_u8)channels[j])
746 {
747 SWAP_U8(channels[j - 1], channels[j]);
748 }
749 }
750 }
751 }
752
wifi_nxp_wpa_supp_scan2(void * if_priv,struct wpa_driver_scan_params * params)753 int wifi_nxp_wpa_supp_scan2(void *if_priv, struct wpa_driver_scan_params *params)
754 {
755 int status = -WM_FAIL;
756 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
757 int ret = -1;
758 int i = 0;
759 unsigned char num_chans = 0;
760 t_u8 bss_mode = BSS_INFRASTRUCTURE;
761 const char *ssid = NULL;
762 char ssid_v[(MLAN_MAX_SSID_LENGTH + 1) * MRVDRV_MAX_SSID_LIST_LENGTH] = {0};
763 const t_u8 *bssid = NULL;
764 wifi_scan_channel_list_t *chan_list = NULL;
765 t_u8 channels[WIFI_SCAN_MAX_NUM_CHAN] = {0};
766 mlan_scan_type scan_type = MLAN_SCAN_TYPE_ACTIVE;
767
768 if (!if_priv || !params)
769 {
770 supp_e("%s: Invalid params", __func__);
771 goto out;
772 }
773
774 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
775
776 if (wifi_if_ctx_rtos->scan_in_progress)
777 {
778 supp_d("%s: Scan already in progress", __func__);
779 ret = -EBUSY;
780 goto out;
781 }
782
783 if (wifi_is_remain_on_channel())
784 {
785 supp_e("%s: Block scan while remaining on channel", __func__);
786 ret = -EBUSY;
787 goto out;
788 }
789
790 wifi_d("initiating wifi-scan");
791
792 if (params->freqs)
793 {
794 for (i = 0; params->freqs[i] && i < WIFI_SCAN_MAX_NUM_CHAN; i++)
795 {
796 channels[i] = freq_to_chan(params->freqs[i]);
797 }
798
799 num_chans = i;
800 }
801 else
802 {
803 num_chans = 0;
804 }
805 uint8_t ssid_off = 0;
806 for (i = 0; i < params->num_ssids; i++)
807 {
808 memcpy(ssid_v+ssid_off, (const char *)params->ssids[i].ssid, params->ssids[i].ssid_len);
809 ssid_off += params->ssids[i].ssid_len;
810 ssid_v[ssid_off] = '\0';
811 ssid_off++;
812 }
813 #if CONFIG_ROAMING
814 if (wlan_get_roaming_status() && mlan_adap->priv[0]->media_connected)
815 {
816 if (params->num_ssids == 1 && params->ssids[0].ssid_len == 0)
817 {
818 ssid_off = 0;
819 memcpy(ssid_v+ssid_off,
820 mlan_adap->priv[0]->curr_bss_params.bss_descriptor.ssid.ssid,
821 mlan_adap->priv[0]->curr_bss_params.bss_descriptor.ssid.ssid_len);
822 ssid_off += mlan_adap->priv[0]->curr_bss_params.bss_descriptor.ssid.ssid_len;
823 ssid_v[ssid_off] = '\0';
824 ssid_off++;
825 }
826 }
827 #endif
828 ssid = (const char *)&ssid_v;
829 #if 0
830 #if CONFIG_COMBO_SCAN
831 if (params->num_filter_ssids > 1)
832 {
833 if (params->filter_ssids[1].ssid_len)
834 {
835 memcpy(ssid_v2, (const char *)params->filter_ssids[1].ssid, params->filter_ssids[1].ssid_len);
836 ssid2 = (const char *)&ssid_v2;
837 }
838 }
839 #endif
840 #endif
841 /*
842 * no ssids means passive scan
843 * refer to woal_cfg80211_scan
844 */
845 if (!params->num_ssids)
846 {
847 scan_type = MLAN_SCAN_TYPE_PASSIVE;
848 }
849
850 bssid = params->bssid;
851
852 if (num_chans != 0)
853 {
854 chan_list = OSA_MemoryAllocate(sizeof(wifi_scan_channel_list_t) * num_chans);
855
856 if (chan_list != NULL)
857 {
858 wifi_nxp_sort_channels(channels, num_chans);
859 for (i = 0; i < num_chans; i++)
860 {
861 chan_list[i].chan_number = channels[i];
862 chan_list[i].scan_type = scan_type;
863 chan_list[i].scan_time = 100;
864 }
865 }
866 }
867
868 if (params->extra_ies_len)
869 {
870 status = wifi_set_scan_ies((void *)params->extra_ies, params->extra_ies_len);
871
872 if (status != WM_SUCCESS)
873 {
874 wifi_d("wifi set scan IEs failed");
875 goto out;
876 }
877 }
878
879 wm_wifi.external_scan = false;
880 wm_wifi.wpa_supp_scan = true;
881
882 #if CONFIG_WPA_SUPP_AP
883 wm_wifi.hostapd_op = false;
884
885 if (wifi_if_ctx_rtos->hostapd)
886 {
887 wm_wifi.hostapd_op = true;
888 }
889 #endif
890
891 status = wifi_send_scan_cmd(bss_mode, bssid, ssid, params->num_ssids, num_chans, chan_list, 0,
892 #if CONFIG_SCAN_WITH_RSSIFILTER
893 params->filter_rssi,
894 #endif
895 #if CONFIG_SCAN_CHANNEL_GAP
896 50U,
897 #endif
898 false, false);
899 if (status != WM_SUCCESS)
900 {
901 wifi_d("wifi send scan cmd failed");
902 goto out;
903 }
904
905 wifi_if_ctx_rtos->scan_in_progress = true;
906 ret = 0;
907 out:
908 if (chan_list != NULL)
909 {
910 OSA_MemoryFree((void *)chan_list);
911 }
912
913 return ret;
914 }
915
wifi_nxp_wpa_supp_set_default_scan_ies(void * priv,const u8 * ies,size_t ies_len)916 int wifi_nxp_wpa_supp_set_default_scan_ies(void *priv, const u8 *ies, size_t ies_len)
917 {
918 int ret = -1;
919
920 if ((!priv) || (!ies))
921 {
922 supp_e("%s: Invalid params", __func__);
923 goto out;
924 }
925
926 ret = wifi_nxp_set_default_scan_ies(ies, ies_len);
927
928 if (ret != WM_SUCCESS)
929 {
930 supp_e("%s: Default scan ies set failed", __func__);
931 }
932 else
933 {
934 supp_d("%s: Default scan ies set successfully", __func__);
935 }
936 out:
937 return ret;
938 }
939
wifi_nxp_wpa_supp_sched_scan(void * if_priv,struct wpa_driver_scan_params * params)940 int wifi_nxp_wpa_supp_sched_scan(void *if_priv, struct wpa_driver_scan_params *params)
941 {
942 int status = -WM_FAIL;
943 // struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
944 int ret = -1;
945 int i = 0;
946 nxp_wifi_trigger_sched_scan_t *wifi_sched_scan_params;
947
948 if (!if_priv || !params)
949 {
950 supp_e("%s: Invalid params", __func__);
951 goto out;
952 }
953
954 // wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
955
956 wifi_sched_scan_params = (nxp_wifi_trigger_sched_scan_t *)OSA_MemoryAllocate(sizeof(nxp_wifi_trigger_sched_scan_t));
957
958 if (!wifi_sched_scan_params)
959 {
960 supp_e("%s: wifi sched scan params calloc failed", __func__);
961 goto out;
962 }
963
964 if (params->num_ssids != 0U)
965 {
966 wifi_sched_scan_params->num_ssids = MIN(WIFI_SCAN_MAX_NUM_SSIDS, params->num_ssids);
967
968 for (i = 0; i < wifi_sched_scan_params->num_ssids; i++)
969 {
970 memcpy(wifi_sched_scan_params->scan_ssids[i].ssid, (const unsigned char *)params->ssids[i].ssid,
971 params->ssids[i].ssid_len);
972
973 wifi_sched_scan_params->scan_ssids[i].ssid_len = params->ssids[i].ssid_len;
974 }
975 }
976
977 for (i = 0; params->freqs[i] && i < WIFI_SCAN_MAX_NUM_CHAN; i++)
978 {
979 wifi_sched_scan_params->chan_list[i] = freq_to_chan(params->freqs[i]);
980 }
981
982 wifi_sched_scan_params->num_chans = i;
983
984 if ((params->extra_ies) && (params->extra_ies_len))
985 {
986 memcpy(wifi_sched_scan_params->extra_ies.ie, params->extra_ies, params->extra_ies_len);
987 wifi_sched_scan_params->extra_ies.ie_len = params->extra_ies_len;
988 }
989
990 wifi_sched_scan_params->chan_per_scan = MIN(WLAN_BG_SCAN_CHAN_MAX, wifi_sched_scan_params->num_chans);
991
992 wifi_sched_scan_params->scan_interval = MIN_BGSCAN_INTERVAL;
993 wifi_sched_scan_params->repeat_count = 2;
994
995 wifi_sched_scan_params->report_condition = BG_SCAN_SSID_MATCH | BG_SCAN_WAIT_ALL_CHAN_DONE;
996
997 wifi_sched_scan_params->filter_rssi = params->filter_rssi;
998
999 status = wifi_send_sched_scan_cmd(wifi_sched_scan_params);
1000 if (status != WM_SUCCESS)
1001 {
1002 supp_e("%s: Sched Scan trigger failed", __func__);
1003 goto out;
1004 }
1005 ret = 0;
1006 out:
1007 return ret;
1008 }
1009
wifi_nxp_wpa_supp_stop_sched_scan(void * if_priv)1010 int wifi_nxp_wpa_supp_stop_sched_scan(void *if_priv)
1011 {
1012 int status = WM_SUCCESS;
1013 int ret = -1;
1014
1015 if (!if_priv)
1016 {
1017 supp_e("%s: Invalid params", __func__);
1018 goto out;
1019 }
1020
1021 status = wifi_send_stop_sched_scan_cmd();
1022 if (status != WM_SUCCESS)
1023 {
1024 supp_e("%s: wifi_supp_stop_sched_scan failed", __func__);
1025 goto out;
1026 }
1027 ret = 0;
1028 out:
1029 return ret;
1030 }
1031
wifi_nxp_wpa_supp_scan_abort(void * if_priv)1032 int wifi_nxp_wpa_supp_scan_abort(void *if_priv)
1033 {
1034 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1035 int status = -WM_FAIL;
1036
1037 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1038
1039 if (!wifi_if_ctx_rtos || (!wifi_if_ctx_rtos->scan_in_progress))
1040 {
1041 supp_e("%s:Ignore scan abort, no scan in progress", __func__);
1042 goto out;
1043 }
1044
1045 wlan_abort_split_scan();
1046 wifi_user_scan_config_cleanup();
1047
1048 status = WM_SUCCESS;
1049
1050 out:
1051 return status;
1052 }
1053
wifi_nxp_wpa_supp_proc_scan_res(nxp_wifi_event_new_scan_result_t * scan_res,struct wifi_nxp_ctx_rtos * wifi_if_ctx_rtos)1054 struct wpa_scan_res *wifi_nxp_wpa_supp_proc_scan_res(nxp_wifi_event_new_scan_result_t *scan_res,
1055 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos)
1056 {
1057 struct wpa_scan_res *r = NULL;
1058 const unsigned char *ie = NULL;
1059 unsigned int ie_len = 0;
1060 unsigned char *pos = NULL;
1061
1062 if (scan_res->ies.ie_len != 0U)
1063 {
1064 ie = (const unsigned char *)scan_res->ies.ie;
1065 ie_len = scan_res->ies.ie_len;
1066 }
1067
1068 r = (struct wpa_scan_res *)OSA_MemoryAllocate(sizeof(*r) + ie_len);
1069
1070 if (!r)
1071 {
1072 supp_e("%s: Unable to calloc memory for scan result\n", __func__);
1073 if (ie)
1074 {
1075 OSA_MemoryFree((void *)ie);
1076 }
1077 return NULL;
1078 }
1079
1080 memcpy(r->bssid, scan_res->mac_addr, ETH_ALEN);
1081
1082 r->freq = scan_res->frequency;
1083
1084 r->beacon_int = scan_res->beacon_interval;
1085
1086 r->caps = scan_res->capability;
1087
1088 if (scan_res->noise == 0)
1089 {
1090 r->flags |= WPA_SCAN_NOISE_INVALID;
1091 }
1092 else
1093 {
1094 r->noise = scan_res->noise;
1095 }
1096
1097 r->level = scan_res->rssi;
1098
1099 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
1100
1101 (void)memcpy((void *)&r->tsf, (const void *)&scan_res->ies_tsf, sizeof(r->tsf));
1102
1103 if (scan_res->beacon_ies_tsf > r->tsf)
1104 {
1105 (void)memcpy((void *)&r->tsf, (const void *)&scan_res->beacon_ies_tsf, sizeof(r->tsf));
1106 }
1107
1108 if (scan_res->seen_ms_ago)
1109 {
1110 r->age = scan_res->seen_ms_ago;
1111 }
1112
1113 (void)memcpy((void *)&r->parent_tsf, (const void *)&scan_res->ies_tsf, sizeof(r->parent_tsf));
1114
1115 memcpy(r->tsf_bssid, wifi_if_ctx_rtos->scan_start_tsf_bssid, ETH_ALEN);
1116
1117 r->ie_len = ie_len;
1118
1119 pos = (unsigned char *)(r + 1);
1120
1121 if (ie_len)
1122 {
1123 memcpy(pos, ie, ie_len);
1124
1125 pos += ie_len;
1126
1127 OSA_MemoryFree((void *)ie);
1128 }
1129
1130 if (scan_res->status)
1131 {
1132 r->flags |= WPA_SCAN_ASSOCIATED;
1133 }
1134
1135 return r;
1136 }
1137
wifi_nxp_wpa_supp_scan_results_get(void * if_priv)1138 int wifi_nxp_wpa_supp_scan_results_get(void *if_priv)
1139 {
1140 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1141 int ret = -1;
1142 unsigned int i, num;
1143 nxp_wifi_event_new_scan_result_t scan_res;
1144 struct wpa_scan_res *sr = NULL;
1145
1146 if (!if_priv)
1147 {
1148 supp_e("%s: Invalid params", __func__);
1149 goto out;
1150 }
1151
1152 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1153
1154 num = wifi_nxp_scan_res_num();
1155
1156 if (num == 0)
1157 {
1158 supp_d("%s: No networks found", __func__);
1159 goto out;
1160 }
1161
1162 for (i = 0; i < num; i++)
1163 {
1164 memset(&scan_res, 0, sizeof(nxp_wifi_event_new_scan_result_t));
1165 (void)wifi_nxp_scan_res_get2(i, &scan_res);
1166
1167 sr = wifi_nxp_wpa_supp_proc_scan_res(&scan_res, wifi_if_ctx_rtos);
1168
1169 if (sr)
1170 {
1171 wifi_if_ctx_rtos->supp_callbk_fns.scan_res(wifi_if_ctx_rtos->supp_drv_if_ctx, sr, i == num -1 ? false : true);
1172 OSA_MemoryFree((void *)sr);
1173 sr = NULL;
1174 }
1175 }
1176
1177 ret = 0;
1178 out:
1179 return ret;
1180 }
1181
wifi_nxp_wpa_supp_survey_results_get(void * if_priv)1182 int wifi_nxp_wpa_supp_survey_results_get(void *if_priv)
1183 {
1184 int status = WM_SUCCESS;
1185 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1186 int ret = -1;
1187 nxp_wifi_trigger_op_t *wifi_survey_params;
1188
1189 if (!if_priv)
1190 {
1191 supp_e("%s: Invalid params", __func__);
1192 goto out;
1193 }
1194
1195 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1196
1197 wifi_survey_params = (nxp_wifi_trigger_op_t *)OSA_MemoryAllocate(sizeof(nxp_wifi_trigger_op_t));
1198
1199 if (!wifi_survey_params)
1200 {
1201 supp_e("%s: wifi survey params calloc failed", __func__);
1202 goto out;
1203 }
1204
1205 wifi_survey_params->hostapd = wifi_if_ctx_rtos->hostapd;
1206
1207 status = wifi_event_completion(WIFI_EVENT_SURVEY_RESULT_GET, WIFI_EVENT_REASON_SUCCESS, wifi_survey_params);
1208 if (status != WM_SUCCESS)
1209 {
1210 supp_e("%s: wifi_supp_survey_res_get failed", __func__);
1211 OSA_MemoryFree(wifi_survey_params);
1212 goto out;
1213 }
1214 ret = 0;
1215 out:
1216 return ret;
1217 }
1218
wifi_nxp_wpa_supp_deauthenticate(void * if_priv,const char * addr,unsigned short reason_code)1219 int wifi_nxp_wpa_supp_deauthenticate(void *if_priv, const char *addr, unsigned short reason_code)
1220 {
1221 int status = -WM_FAIL;
1222 int ret = -1;
1223 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1224
1225 if ((!if_priv) || (!addr))
1226 {
1227 supp_e("%s: Invalid params", __func__);
1228 goto out;
1229 }
1230
1231 wifi_d("initiating wifi-deauth");
1232
1233 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1234 if (wifi_if_ctx_rtos->ft_roaming)
1235 {
1236 wifi_if_ctx_rtos->ft_roaming = false;
1237 }
1238
1239 status = wifi_nxp_deauthenticate(MLAN_BSS_TYPE_STA, (const unsigned char *)addr, reason_code);
1240
1241 if (status != WM_SUCCESS)
1242 {
1243 supp_e("%s: wifi_nxp_wpa_supp_deauthenticate failed", __func__);
1244 goto out;
1245 }
1246 ret = 0;
1247 out:
1248 return ret;
1249 }
1250
1251 #if 0
1252 int wifi_nxp_wpa_supp_add_key(struct nxp_wifi_umac_key_info *key_info, enum wpa_alg alg,
1253 int key_idx,
1254 int defkey, const unsigned char *seq, size_t seq_len,
1255 const unsigned char *key, size_t key_len)
1256 {
1257 unsigned int suite = 0;
1258
1259 suite = wpa_alg_to_cipher_suite(alg, key_len);
1260
1261 if (!suite) {
1262 return -1;
1263 }
1264
1265 if (defkey && alg == WPA_ALG_BIP_CMAC_128) {
1266 key_info->nxp_wifi_flags = NXP_WIFI_KEY_DEFAULT_MGMT;
1267 } else if (defkey) {
1268 key_info->nxp_wifi_flags = NXP_WIFI_KEY_DEFAULT;
1269 }
1270
1271 key_info->key_idx = key_idx;
1272 key_info->cipher_suite = suite;
1273
1274 if (key && key_len) {
1275 memcpy(key_info->key.nxp_wifi_key, key, key_len);
1276 key_info->key.nxp_wifi_key_len = key_len;
1277 }
1278 if (seq && seq_len) {
1279 memcpy(key_info->seq.nxp_wifi_seq, seq, seq_len);
1280 key_info->seq.nxp_wifi_seq_len = seq_len;
1281 }
1282
1283 return 0;
1284 }
1285 #endif
1286
wifi_nxp_wpa_supp_save_pairwise_key_params(struct wifi_nxp_ctx_rtos * if_ctx,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)1287 static int wifi_nxp_wpa_supp_save_pairwise_key_params(struct wifi_nxp_ctx_rtos *if_ctx,
1288 const unsigned char *ifname,
1289 enum wpa_alg alg,
1290 const unsigned char *addr,
1291 int key_idx,
1292 int set_tx,
1293 const unsigned char *seq,
1294 size_t seq_len,
1295 const unsigned char *key,
1296 size_t key_len,
1297 enum key_flag key_flag)
1298 {
1299 int ret = -1;
1300
1301 if (if_ctx->key_params)
1302 {
1303 wifi_nxp_wpa_supp_free_pairwise_key_params(if_ctx->key_params);
1304 if_ctx->key_params = NULL;
1305 }
1306
1307 if_ctx->key_params = (struct wpa_driver_set_key_params *)os_zalloc(sizeof(struct wpa_driver_set_key_params));
1308
1309 if (!if_ctx->key_params)
1310 {
1311 wpa_printf(MSG_DEBUG, "%s: failed to alloc", __func__);
1312 return -1;
1313 }
1314
1315 if (ifname)
1316 {
1317 if_ctx->key_params->ifname = os_strdup(ifname);
1318 if (!if_ctx->key_params->ifname)
1319 {
1320 wpa_printf(MSG_DEBUG, "%s: failed to alloc ifname", __func__);
1321 goto out;
1322 }
1323 }
1324
1325 if (addr)
1326 {
1327 if_ctx->key_params->addr = os_memdup(addr, ETH_ALEN);
1328 if (!if_ctx->key_params->addr)
1329 {
1330 wpa_printf(MSG_DEBUG, "%s: failed to alloc addr", __func__);
1331 goto out;
1332 }
1333 }
1334
1335 if (seq)
1336 {
1337 if_ctx->key_params->seq = os_memdup(seq, seq_len);
1338 if (!if_ctx->key_params->seq)
1339 {
1340 wpa_printf(MSG_DEBUG, "%s: failed to alloc seq", __func__);
1341 goto out;
1342 }
1343 if_ctx->key_params->seq_len = seq_len;
1344 }
1345
1346 if (key)
1347 {
1348 if_ctx->key_params->key = os_memdup(key, key_len);
1349 if (!if_ctx->key_params->key)
1350 {
1351 wpa_printf(MSG_DEBUG, "%s: failed to alloc key", __func__);
1352 goto out;
1353 }
1354 if_ctx->key_params->key_len = key_len;
1355 }
1356
1357 if_ctx->key_params->alg = alg;
1358 if_ctx->key_params->key_idx = key_idx;
1359 if_ctx->key_params->set_tx = set_tx;
1360 if_ctx->key_params->key_flag = key_flag;
1361
1362 ret = 0;
1363 out:
1364 if (ret)
1365 {
1366 wifi_nxp_wpa_supp_free_pairwise_key_params(if_ctx->key_params);
1367 if_ctx->key_params = NULL;
1368 }
1369 return ret;
1370 }
1371
wifi_nxp_wpa_supp_authenticate(void * if_priv,struct wpa_driver_auth_params * params,struct wpa_bss * curr_bss)1372 int wifi_nxp_wpa_supp_authenticate(void *if_priv, struct wpa_driver_auth_params *params, struct wpa_bss *curr_bss)
1373 {
1374 int status = -WM_FAIL;
1375 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1376 unsigned char *pos = NULL;
1377 unsigned char auth_alg;
1378 unsigned char auth_trans_num[2] = {1, 0};
1379 unsigned char status_code[2] = {0, 0};
1380 int ret = -1;
1381 unsigned short len = 0;
1382 int channel;
1383
1384 if ((!if_priv) || (!params))
1385 {
1386 supp_e("%s: Invalid params", __func__);
1387 goto out;
1388 }
1389
1390 if (params->local_state_change)
1391 {
1392 /* This is just a notify info */
1393 ret = 0;
1394 goto out;
1395 }
1396
1397 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1398 auth_alg = get_algo_from_auth_type(params->auth_alg);
1399
1400 wifi_if_ctx_rtos->ft_roaming = false;
1401 if (params->auth_alg == WPA_AUTH_ALG_FT)
1402 {
1403 pos = (unsigned char *)params->ie;
1404 len = params->ie_len;
1405 wifi_if_ctx_rtos->ft_roaming = true;
1406 }
1407 else if ((params->auth_data != NULL) && (params->auth_data_len >= 4))
1408 {
1409 pos = (unsigned char *)params->auth_data;
1410
1411 auth_trans_num[0] = pos[0];
1412 auth_trans_num[1] = pos[1];
1413 status_code[0] = pos[2];
1414 status_code[1] = pos[3];
1415 pos += 4;
1416 len = params->auth_data_len - 4;
1417 }
1418
1419 channel = freq_to_chan(params->freq);
1420
1421 wifi_d("initiating wifi-auth");
1422
1423 status = wifi_send_mgmt_auth_request(channel, auth_alg, auth_trans_num, status_code, params->bssid,
1424 (const unsigned char *)pos, len);
1425
1426 if (status != WM_SUCCESS)
1427 {
1428 supp_e("%s: MLME command failed (auth): ret=%d", __func__, ret);
1429 ret = -1;
1430 }
1431 else
1432 {
1433 supp_d("%s:Authentication request sent successfully", __func__);
1434 ret = 0;
1435 }
1436 out:
1437 return ret;
1438 }
1439
wifi_nxp_wpa_supp_associate(void * if_priv,struct wpa_driver_associate_params * params)1440 int wifi_nxp_wpa_supp_associate(void *if_priv, struct wpa_driver_associate_params *params)
1441 {
1442 int status = -WM_FAIL;
1443 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1444 nxp_wifi_assoc_info_t *assoc_params;
1445 int ret = -1;
1446 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
1447 t_u8 mfpc, mfpr;
1448 #endif
1449 if ((!if_priv) || (!params))
1450 {
1451 supp_e("%s: Invalid params", __func__);
1452 goto out;
1453 }
1454
1455 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1456
1457 assoc_params = (nxp_wifi_assoc_info_t *)OSA_MemoryAllocate(sizeof(nxp_wifi_assoc_info_t));
1458
1459 if (!assoc_params)
1460 {
1461 supp_e("%s: assoc params calloc failed", __func__);
1462 goto out;
1463 }
1464
1465 wifi_if_ctx_rtos->associated = false;
1466
1467 if (params->auth_alg & WPA_AUTH_ALG_FT)
1468 {
1469 assoc_params->is_ft = true;
1470 }
1471
1472 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
1473 if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
1474 {
1475 mfpc = 1;
1476 mfpr = 1;
1477 }
1478 else if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_OPTIONAL)
1479 {
1480 mfpc = 1;
1481 mfpr = 0;
1482 }
1483 else
1484 {
1485 mfpc = 0;
1486 mfpr = 0;
1487 }
1488 wifi_set_pmfcfg(mfpc, mfpr);
1489 #endif
1490
1491 if (params->bssid)
1492 {
1493 memcpy(&wifi_if_ctx_rtos->attempt_bssid, params->bssid, ETH_ALEN);
1494
1495 memcpy(assoc_params->bssid, params->bssid, WIFI_ETH_ADDR_LEN);
1496 }
1497
1498 if (params->prev_bssid)
1499 {
1500 memcpy(assoc_params->prev_bssid, params->prev_bssid, sizeof(assoc_params->prev_bssid));
1501 }
1502
1503 if (params->freq.freq)
1504 {
1505 int channel = freq_to_chan(params->freq.freq);
1506 assoc_params->channel = channel;
1507
1508 wifi_if_ctx_rtos->assoc_freq = params->freq.freq;
1509 }
1510 else
1511 {
1512 wifi_if_ctx_rtos->assoc_freq = 0;
1513 }
1514
1515 if (params->ssid)
1516 {
1517 assoc_params->ssid.ssid_len = params->ssid_len;
1518
1519 memcpy(assoc_params->ssid.ssid, params->ssid, params->ssid_len);
1520 }
1521
1522 if (params->wpa_ie)
1523 {
1524 assoc_params->wpa_ie.ie_len = params->wpa_ie_len;
1525 memcpy(assoc_params->wpa_ie.ie, params->wpa_ie, params->wpa_ie_len);
1526 }
1527
1528 assoc_params->control_port = 1;
1529
1530 wifi_d("initiating wifi-assoc");
1531
1532 status = wifi_nxp_send_assoc(assoc_params);
1533
1534 if (status != WM_SUCCESS)
1535 {
1536 supp_e("%s: MLME command failed (assoc)", __func__);
1537 }
1538 else
1539 {
1540 supp_d("%s: Association request sent successfully", __func__);
1541 ret = 0;
1542 }
1543 OSA_MemoryFree((void *)assoc_params);
1544
1545 out:
1546 return ret;
1547 }
1548
_wifi_nxp_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)1549 static int _wifi_nxp_wpa_supp_set_key(void *if_priv,
1550 const unsigned char *ifname,
1551 enum wpa_alg alg,
1552 const unsigned char *addr,
1553 int key_idx,
1554 int set_tx,
1555 const unsigned char *seq,
1556 size_t seq_len,
1557 const unsigned char *key,
1558 size_t key_len,
1559 enum key_flag key_flag)
1560
1561 {
1562 int status = -WM_FAIL;
1563 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1564 unsigned int flags = 0;
1565 int ret = -1;
1566 bool is_pairwise = false;
1567 int skip_set_key = 1;
1568
1569 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1570 if ((key_flag & KEY_FLAG_PAIRWISE_MASK) == KEY_FLAG_PAIRWISE_RX_TX_MODIFY)
1571 {
1572 supp_d("SET_KEY (pairwise RX/TX modify)");
1573 }
1574 else if (alg == WPA_ALG_NONE && (key_flag & KEY_FLAG_RX_TX))
1575 {
1576 supp_d("%s: invalid key_flag to delete key", __func__);
1577 ret = -1;
1578 goto out;
1579 }
1580 else if (alg == WPA_ALG_NONE)
1581 {
1582 supp_d("DEL_KEY");
1583
1584 status = wifi_remove_key(wifi_if_ctx_rtos->bss_type, is_pairwise, key_idx, addr);
1585
1586 if (status != WM_SUCCESS)
1587 {
1588 supp_e("%s: wifi_nxp_del_key failed", __func__);
1589 }
1590 else
1591 {
1592 ret = 0;
1593 }
1594 }
1595 else
1596 {
1597 flags = wpa_alg_to_cipher_suite(alg, key_len);
1598
1599 /* TODO: Implement/check set_tx */
1600 if (addr && !is_broadcast_ether_addr(addr))
1601 {
1602 is_pairwise = true;
1603 if ((key_flag & KEY_FLAG_PAIRWISE_MASK) == KEY_FLAG_PAIRWISE_RX ||
1604 (key_flag & KEY_FLAG_PAIRWISE_MASK) == KEY_FLAG_PAIRWISE_RX_TX_MODIFY)
1605 {
1606 }
1607 else if ((key_flag & KEY_FLAG_GROUP_MASK) == KEY_FLAG_GROUP_RX)
1608 {
1609 }
1610 else if (!(key_flag & KEY_FLAG_PAIRWISE))
1611 {
1612 supp_d(" key_flag missing PAIRWISE when setting a pairwise key");
1613 ret = -1;
1614 goto out;
1615 }
1616 else if (alg == WPA_ALG_WEP && (key_flag & KEY_FLAG_RX_TX) == KEY_FLAG_RX_TX)
1617 {
1618 supp_d(" unicast WEP key");
1619 skip_set_key = 0;
1620 }
1621 else
1622 {
1623 supp_d(" pairwise key");
1624 }
1625 }
1626 else if ((key_flag & KEY_FLAG_PAIRWISE) || !(key_flag & KEY_FLAG_GROUP))
1627 {
1628 supp_d(" invalid key_flag for a broadcast key");
1629 ret = -1;
1630 goto out;
1631 }
1632 else
1633 {
1634 supp_d(" broadcast key");
1635 is_pairwise = false;
1636 if (key_flag & KEY_FLAG_DEFAULT)
1637 skip_set_key = 0;
1638 }
1639
1640 status =
1641 wifi_set_key(wifi_if_ctx_rtos->bss_type, is_pairwise, key_idx, key, key_len, seq, seq_len, addr, flags);
1642
1643 if (status != WM_SUCCESS)
1644 {
1645 supp_e("%s: wifi_set_key failed", __func__);
1646 }
1647 else
1648 {
1649 ret = 0;
1650 }
1651
1652 if (ret || skip_set_key)
1653 return ret;
1654 }
1655 out:
1656 return ret;
1657 }
1658
wifi_nxp_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)1659 int wifi_nxp_wpa_supp_set_key(void *if_priv,
1660 const unsigned char *ifname,
1661 enum wpa_alg alg,
1662 const unsigned char *addr,
1663 int key_idx,
1664 int set_tx,
1665 const unsigned char *seq,
1666 size_t seq_len,
1667 const unsigned char *key,
1668 size_t key_len,
1669 enum key_flag key_flag)
1670
1671 {
1672 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1673
1674 if ((!if_priv) || (!ifname))
1675 {
1676 supp_e("%s: Invalid params", __func__);
1677 return -1;
1678 }
1679
1680 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1681
1682 if (wifi_if_ctx_rtos->ft_roaming && (key_flag & KEY_FLAG_PAIRWISE)) {
1683 return wifi_nxp_wpa_supp_save_pairwise_key_params(wifi_if_ctx_rtos, ifname, alg,
1684 addr, key_idx, set_tx, seq, seq_len,
1685 key, key_len, key_flag);
1686 }
1687
1688 if (wifi_if_ctx_rtos->ft_roaming && (key_flag & KEY_FLAG_GROUP)) {
1689 if (wifi_if_ctx_rtos->key_params &&
1690 (wifi_if_ctx_rtos->key_params->key_flag & KEY_FLAG_PAIRWISE)) {
1691 _wifi_nxp_wpa_supp_set_key(if_priv, (const unsigned char *)wifi_if_ctx_rtos->key_params->ifname,
1692 wifi_if_ctx_rtos->key_params->alg, wifi_if_ctx_rtos->key_params->addr,
1693 wifi_if_ctx_rtos->key_params->key_idx, wifi_if_ctx_rtos->key_params->set_tx,
1694 wifi_if_ctx_rtos->key_params->seq, wifi_if_ctx_rtos->key_params->seq_len,
1695 wifi_if_ctx_rtos->key_params->key, wifi_if_ctx_rtos->key_params->key_len,
1696 wifi_if_ctx_rtos->key_params->key_flag);
1697 wifi_nxp_wpa_supp_free_pairwise_key_params(wifi_if_ctx_rtos->key_params);
1698 wifi_if_ctx_rtos->key_params = NULL;
1699 }
1700 }
1701 return _wifi_nxp_wpa_supp_set_key(if_priv, ifname, alg, addr, key_idx, set_tx, seq, seq_len, key, key_len, key_flag);
1702 }
1703
wifi_nxp_wpa_supp_del_key(void * if_priv,const unsigned char * addr,int key_idx)1704 int wifi_nxp_wpa_supp_del_key(void *if_priv, const unsigned char *addr, int key_idx)
1705
1706 {
1707 int status = -WM_FAIL;
1708 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1709 int ret = -1;
1710
1711 if (!if_priv)
1712 {
1713 supp_e("%s: Invalid params", __func__);
1714 goto out;
1715 }
1716
1717 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1718
1719 status = wifi_remove_key(wifi_if_ctx_rtos->bss_type, 0, key_idx, addr);
1720
1721 if (status != WM_SUCCESS)
1722 {
1723 supp_e("%s: wifi_nxp_del_key failed", __func__);
1724 }
1725 else
1726 {
1727 ret = 0;
1728 }
1729
1730 out:
1731 return ret;
1732 }
1733
wifi_nxp_wpa_supp_set_rekey_info(void * if_priv,const u8 * kek,size_t kek_len,const u8 * kck,size_t kck_len,const u8 * replay_ctr)1734 int wifi_nxp_wpa_supp_set_rekey_info(
1735 void *if_priv, const u8 *kek, size_t kek_len, const u8 *kck, size_t kck_len, const u8 *replay_ctr)
1736 {
1737 int status = -WM_FAIL;
1738 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1739 int ret = -1;
1740
1741 if ((!if_priv) || (!kek) || (!kck) || (!replay_ctr))
1742 {
1743 supp_e("%s: Invalid params", __func__);
1744 goto out;
1745 }
1746
1747 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1748
1749 status = wifi_set_rekey_info(wifi_if_ctx_rtos->bss_type, kek, kek_len, kck, kck_len, replay_ctr);
1750
1751 if (status != WM_SUCCESS)
1752 {
1753 supp_e("%s: wifi_set_rekey_info failed", __func__);
1754 goto out;
1755 }
1756 else
1757 {
1758 ret = 0;
1759 }
1760
1761 out:
1762 return ret;
1763 }
1764
wifi_nxp_wpa_supp_set_supp_port(void * if_priv,int authorized,char * bssid)1765 int wifi_nxp_wpa_supp_set_supp_port(void *if_priv, int authorized, char *bssid)
1766 {
1767 int ret = -1;
1768 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1769
1770 if ((!if_priv) || (!bssid))
1771 {
1772 supp_e("%s: Invalid params", __func__);
1773 goto out;
1774 }
1775
1776 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1777
1778 wifi_d("initiating wifi-set-port authorized: %d", authorized);
1779
1780 if (wifi_if_ctx_rtos->associated)
1781 {
1782 #if CONFIG_WPA_SUPP_WPS
1783 if (!wifi_nxp_wps_session_enable())
1784 {
1785 #endif
1786 if (authorized)
1787 {
1788 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
1789 (void)wifi_event_completion(WIFI_EVENT_AUTHENTICATION, WIFI_EVENT_REASON_SUCCESS, NULL);
1790 #endif
1791 }
1792 #if CONFIG_WPA_SUPP_WPS
1793 }
1794 #endif
1795 }
1796 if (authorized == 0U)
1797 {
1798 wlan_abort_split_scan();
1799 wifi_user_scan_config_cleanup();
1800 }
1801
1802 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
1803 wlan_subscribe_rssi_low_event();
1804 #endif
1805 ret = 0;
1806 out:
1807 return ret;
1808 }
1809
wifi_nxp_wpa_supp_set_country(void * if_priv,const char * alpha2)1810 int wifi_nxp_wpa_supp_set_country(void *if_priv, const char *alpha2)
1811 {
1812 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1813 int ret = -WM_FAIL;
1814 char *country = NULL;
1815
1816 country = OSA_MemoryAllocate(COUNTRY_CODE_LEN);
1817 (void)memcpy(country, alpha2, COUNTRY_CODE_LEN - 1);
1818
1819 if ((!if_priv) || (!alpha2))
1820 {
1821 supp_e("%s: Invalid params", __func__);
1822 goto out;
1823 }
1824
1825 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1826
1827 #if CONFIG_WPA_SUPP_AP
1828 wm_wifi.hostapd_op = false;
1829
1830 if (wifi_if_ctx_rtos->hostapd)
1831 {
1832 wm_wifi.hostapd_op = true;
1833 }
1834 #endif
1835
1836 ret = wifi_nxp_set_country(wifi_if_ctx_rtos->bss_type, alpha2);
1837
1838 if (ret == WM_SUCCESS)
1839 {
1840 (void)wifi_event_completion(WIFI_EVENT_REGION_POWER_CFG, WIFI_EVENT_REASON_SUCCESS, (void *)country);
1841 }
1842
1843 return ret;
1844
1845 out:
1846 return -1;
1847 }
1848
wifi_nxp_wpa_supp_get_country(void * if_priv,char * alpha2)1849 int wifi_nxp_wpa_supp_get_country(void *if_priv, char *alpha2)
1850 {
1851 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1852
1853 if ((!if_priv) || (!alpha2))
1854 {
1855 supp_e("%s: Invalid params", __func__);
1856 goto out;
1857 }
1858
1859 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1860
1861 return wifi_nxp_get_country(wifi_if_ctx_rtos->bss_type, alpha2);
1862
1863 out:
1864 return -1;
1865 }
1866
wifi_rate_to_signal_info(wlan_ds_rate * ds_rate,struct wpa_signal_info * si)1867 static int wifi_rate_to_signal_info(wlan_ds_rate *ds_rate, struct wpa_signal_info *si)
1868 {
1869 wifi_data_rate_t *datarate = (wifi_data_rate_t *)&ds_rate->param.data_rate;
1870 /* refer to legacy rates */
1871 int lg_rate[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54};
1872
1873 if (datarate->tx_rate_format == MLAN_RATE_FORMAT_LG && datarate->tx_data_rate < 12)
1874 {
1875 /* Legacy rates */
1876 si->current_txrate = lg_rate[datarate->tx_data_rate];
1877 }
1878 else if (datarate->tx_rate_format <= 3)
1879 {
1880 /* HT, VHT, HE rates */
1881 si->current_txrate = datarate->tx_data_rate >> 1;
1882 }
1883
1884 return WM_SUCCESS;
1885 }
1886
wifi_nxp_wpa_supp_signal_poll(void * if_priv,struct wpa_signal_info * si,unsigned char * bssid)1887 int wifi_nxp_wpa_supp_signal_poll(void *if_priv, struct wpa_signal_info *si, unsigned char *bssid)
1888 {
1889 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1890 int ret = -WM_FAIL;
1891 nxp_wifi_signal_info_t signal_params;
1892 wlan_ds_rate ds_rate = {0};
1893
1894 if (!if_priv || !si || !bssid)
1895 {
1896 supp_e("%s: Invalid params\r\n", __func__);
1897 goto out;
1898 }
1899
1900 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1901
1902 ret = wifi_nxp_get_signal(wifi_if_ctx_rtos->bss_type, &signal_params);
1903 if (ret != WM_SUCCESS)
1904 {
1905 supp_e("%s: wifi_nxp_get_signal failed", __func__);
1906 goto out;
1907 }
1908
1909 memset(si, 0x00, sizeof(struct wpa_signal_info));
1910
1911 si->frequency = wifi_if_ctx_rtos->assoc_freq;
1912 si->current_signal = signal_params.current_signal;
1913 si->avg_signal = signal_params.avg_signal;
1914 si->avg_beacon_signal = signal_params.avg_beacon_signal;
1915 si->current_noise = signal_params.current_noise;
1916
1917 ds_rate.sub_command = WIFI_DS_GET_DATA_RATE;
1918 ret = wlan_get_data_rate(&ds_rate, WLAN_BSS_TYPE_STA);
1919 if (ret != WM_SUCCESS)
1920 {
1921 supp_e("%s: wifi_nxp_get_signal rate failed", __func__);
1922 goto out;
1923 }
1924
1925 ret = wifi_rate_to_signal_info(&ds_rate, si);
1926 if (ret != WM_SUCCESS)
1927 {
1928 supp_e("%s: wifi_nxp_get_signal rate convert failed", __func__);
1929 goto out;
1930 }
1931
1932 out:
1933 return ret;
1934 }
1935
wifi_nxp_wpa_supp_event_acs_channel_selected(void * if_priv,nxp_wifi_acs_params * acs_params)1936 void wifi_nxp_wpa_supp_event_acs_channel_selected(void *if_priv, nxp_wifi_acs_params *acs_params)
1937 {
1938 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1939 union wpa_event_data event;
1940
1941 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1942
1943 if (!if_priv)
1944 {
1945 supp_e("%s: Missing interface context", __func__);
1946 return;
1947 }
1948
1949 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1950
1951 memset(&event, 0, sizeof(event));
1952
1953 if (!acs_params)
1954 {
1955 supp_e("%s: Missing acs params data", __func__);
1956 return;
1957 }
1958
1959 event.acs_selected_channels.pri_freq = acs_params->pri_freq;
1960 event.acs_selected_channels.sec_freq = acs_params->sec_freq;
1961 event.acs_selected_channels.ch_width = acs_params->ch_width;
1962 event.acs_selected_channels.hw_mode = (enum hostapd_hw_mode)acs_params->hw_mode;
1963
1964 if (wifi_if_ctx_rtos->hostapd)
1965 {
1966 wifi_if_ctx_rtos->hostapd_callbk_fns.acs_channel_sel(wifi_if_ctx_rtos->hapd_drv_if_ctx, &event);
1967 }
1968 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
1969 else
1970 {
1971 wifi_if_ctx_rtos->supp_callbk_fns.acs_channel_sel(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
1972 }
1973 #endif
1974 }
1975
wifi_nxp_wpa_supp_event_mgmt_tx_status(void * if_priv,nxp_wifi_event_mlme_t * mlme_event,unsigned int event_len)1976 void wifi_nxp_wpa_supp_event_mgmt_tx_status(void *if_priv, nxp_wifi_event_mlme_t *mlme_event, unsigned int event_len)
1977 {
1978 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
1979
1980 if (!if_priv)
1981 {
1982 supp_e("%s: Missing interface context", __func__);
1983 return;
1984 }
1985
1986 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
1987
1988 if (!mlme_event)
1989 {
1990 supp_e("%s: Missing MLME event data", __func__);
1991 return;
1992 }
1993
1994 if (wifi_if_ctx_rtos->mgmt_tx_status == 0U)
1995 {
1996 supp_d("%s: Only send mgmt tx status", __func__);
1997 return;
1998 }
1999
2000 if (wifi_if_ctx_rtos->last_mgmt_tx_data_len && wifi_if_ctx_rtos->mgmt_tx_status)
2001 {
2002 memcpy((void *)mlme_event->frame.frame, (const void *)wifi_if_ctx_rtos->last_mgmt_tx_data,
2003 (size_t)wifi_if_ctx_rtos->last_mgmt_tx_data_len);
2004 mlme_event->frame.frame_len = wifi_if_ctx_rtos->last_mgmt_tx_data_len;
2005 wifi_if_ctx_rtos->last_mgmt_tx_data_len = 0;
2006 wifi_if_ctx_rtos->mgmt_tx_status = 0;
2007 }
2008
2009 wifi_if_ctx_rtos->mgmt_tx_status = 0;
2010
2011 if (mlme_event->frame.frame_len == 0)
2012 {
2013 supp_d("%s: mgmt tx status frame invalid", __func__);
2014 return;
2015 }
2016
2017 #if CONFIG_WPA_SUPP_AP
2018 if (wifi_if_ctx_rtos->hostapd)
2019 {
2020 wifi_if_ctx_rtos->hostapd_callbk_fns.mgmt_tx_status(wifi_if_ctx_rtos->hapd_drv_if_ctx,
2021 (const unsigned char *)mlme_event->frame.frame,
2022 mlme_event->frame.frame_len, true);
2023 }
2024 else
2025 #endif
2026 {
2027 wifi_if_ctx_rtos->supp_callbk_fns.mgmt_tx_status(wifi_if_ctx_rtos->supp_drv_if_ctx,
2028 (const unsigned char *)mlme_event->frame.frame,
2029 mlme_event->frame.frame_len, true);
2030 }
2031 }
2032
wifi_nxp_wpa_supp_event_proc_unprot_mgmt(void * if_priv,nxp_wifi_event_mlme_t * unprot_mgmt,unsigned int event_len)2033 void wifi_nxp_wpa_supp_event_proc_unprot_mgmt(void *if_priv, nxp_wifi_event_mlme_t *unprot_mgmt, unsigned int event_len)
2034 {
2035 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2036 union wpa_event_data event;
2037 const struct ieee80211_mgmt *mgmt = NULL;
2038 const unsigned char *frame = NULL;
2039 unsigned int frame_len = 0;
2040
2041 if (!if_priv)
2042 {
2043 supp_e("%s: Missing interface context", __func__);
2044 return;
2045 }
2046
2047 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2048
2049 frame = (const unsigned char *)unprot_mgmt->frame.frame;
2050 frame_len = unprot_mgmt->frame.frame_len;
2051
2052 mgmt = (const struct ieee80211_mgmt *)frame;
2053
2054 if (frame_len < 24 + sizeof(mgmt->u.deauth))
2055 {
2056 supp_e("%s: Unprotected mgmt frame too short", __func__);
2057 return;
2058 }
2059
2060 memset(&event, 0, sizeof(event));
2061
2062 event.unprot_deauth.sa = &mgmt->sa[0];
2063 event.unprot_deauth.da = &mgmt->da[0];
2064
2065 // if (cmd_evnt == NXP_WIFI_EVENT_UNPROT_DEAUTHENTICATE) {
2066 event.unprot_deauth.reason_code = le_to_host16(mgmt->u.deauth.reason_code);
2067 wifi_if_ctx_rtos->supp_callbk_fns.unprot_deauth(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
2068 // } else if (cmd_evnt == NXP_WIFI_EVENT_UNPROT_DISASSOCIATE) {
2069 event.unprot_disassoc.reason_code = le_to_host16(mgmt->u.deauth.reason_code);
2070 wifi_if_ctx_rtos->supp_callbk_fns.unprot_disassoc(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
2071 // }
2072 }
2073
wifi_nxp_wpa_supp_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)2074 int wifi_nxp_wpa_supp_send_mlme(void *if_priv,
2075 const u8 *data,
2076 size_t data_len,
2077 int noack,
2078 unsigned int freq,
2079 int no_cck,
2080 int offchanok,
2081 unsigned int wait_time,
2082 int cookie)
2083 {
2084 int status = -WM_FAIL;
2085 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2086 const struct ieee80211_hdr *hdr;
2087 u16 fc, stype;
2088
2089 hdr = (const struct ieee80211_hdr *)data;
2090 fc = le_to_host16(hdr->frame_control);
2091 stype = WLAN_FC_GET_STYPE(fc);
2092
2093 if (!if_priv)
2094 {
2095 supp_e("%s: Missing interface context", __func__);
2096 goto out;
2097 }
2098
2099 if (data_len > 1500)
2100 {
2101 supp_d("%s: Invalid data length", __func__);
2102 goto out;
2103 }
2104
2105 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2106
2107 wifi_if_ctx_rtos->mgmt_tx_status = 0;
2108
2109 status = wifi_nxp_send_mlme(wifi_if_ctx_rtos->bss_type, freq_to_chan(freq), wait_time, data, data_len);
2110
2111 if (status == -WM_FAIL)
2112 {
2113 wifi_if_ctx_rtos->last_mgmt_tx_data_len = 0;
2114 wifi_if_ctx_rtos->mgmt_tx_status = 0;
2115 supp_e("%s: wifi_inject_frame failed", __func__);
2116 goto out;
2117 }
2118
2119 if (((wifi_if_ctx_rtos->bss_type == BSS_TYPE_UAP) &&
2120 ((stype == WLAN_FC_STYPE_ASSOC_RESP) || (stype == WLAN_FC_STYPE_REASSOC_RESP))) ||
2121 (stype == WLAN_FC_STYPE_ACTION))
2122 {
2123 memcpy((void *)wifi_if_ctx_rtos->last_mgmt_tx_data, (const void *)data, (size_t)data_len);
2124 wifi_if_ctx_rtos->last_mgmt_tx_data_len = data_len;
2125 wifi_if_ctx_rtos->mgmt_tx_status = 1;
2126 }
2127 else
2128 {
2129 wifi_if_ctx_rtos->last_mgmt_tx_data_len = 0;
2130 }
2131
2132 out:
2133 return status;
2134 }
2135
wifi_nxp_parse_sband(struct wifi_nxp_event_supported_band * event,struct wpa_supp_event_supported_band * band)2136 int wifi_nxp_parse_sband( struct wifi_nxp_event_supported_band *event,
2137 struct wpa_supp_event_supported_band *band)
2138 {
2139 int count;
2140
2141 if (event && (event->wifi_nxp_n_bitrates == 0 || event->wifi_nxp_n_channels == 0))
2142 {
2143 return -WM_FAIL;
2144 }
2145
2146 memset(band, 0, sizeof(*band));
2147
2148 band->wpa_supp_n_channels = event->wifi_nxp_n_channels;
2149 band->wpa_supp_n_bitrates = event->wifi_nxp_n_bitrates;
2150
2151 for (count = 0; count < band->wpa_supp_n_channels; count++) {
2152 struct wpa_supp_event_channel *chan = &band->channels[count];
2153
2154 if (count >= WPA_SUPP_SBAND_MAX_CHANNELS)
2155 {
2156 supp_e("%s: Failed to add channel", __func__);
2157 break;
2158 }
2159
2160 chan->wpa_supp_flags = event->channels[count].wifi_nxp_flags;
2161 chan->wpa_supp_max_power = event->channels[count].wifi_nxp_max_power;
2162 chan->wpa_supp_time = event->channels[count].wifi_nxp_time;
2163 chan->dfs_cac_msec = event->channels[count].dfs_cac_msec;
2164 chan->ch_valid = event->channels[count].ch_valid;
2165 chan->center_frequency = event->channels[count].center_frequency;
2166 chan->dfs_state = event->channels[count].dfs_state;
2167 }
2168
2169 for (count = 0; count < band->wpa_supp_n_bitrates; count++) {
2170 struct wpa_supp_event_rate *rate = &band->bitrates[count];
2171
2172 if (count >= WPA_SUPP_SBAND_MAX_RATES) {
2173 supp_e("%s: Failed to add bitrate", __func__);
2174 break;
2175 }
2176
2177 rate->wpa_supp_flags = event->bitrates[count].wifi_nxp_flags;
2178 rate->wpa_supp_bitrate = event->bitrates[count].wifi_nxp_bitrate;
2179 }
2180
2181 band->ht_cap.wpa_supp_ht_supported = event->ht_cap.wifi_nxp_ht_supported;
2182 band->ht_cap.wpa_supp_cap = event->ht_cap.wifi_nxp_cap;
2183 band->ht_cap.mcs.wpa_supp_rx_highest = event->ht_cap.mcs.wifi_nxp_rx_highest;
2184
2185 for (count = 0; count < WPA_SUPP_HT_MCS_MASK_LEN; count++) {
2186 band->ht_cap.mcs.wpa_supp_rx_mask[count] =
2187 event->ht_cap.mcs.wifi_nxp_rx_mask[count];
2188 }
2189
2190 band->ht_cap.mcs.wpa_supp_tx_params = event->ht_cap.mcs.wifi_nxp_tx_params;
2191
2192 for (count = 0; count < WIFI_NXP_HT_MCS_RES_LEN; count++) {
2193
2194 if (count >= WPA_SUPP_HT_MCS_RES_LEN) {
2195 supp_e("%s: Failed to add reserved bytes", __func__);
2196 break;
2197 }
2198
2199 band->ht_cap.mcs.wpa_supp_reserved[count] =
2200 event->ht_cap.mcs.wifi_nxp_reserved[count];
2201 }
2202
2203 band->ht_cap.wpa_supp_ampdu_factor = event->ht_cap.wifi_nxp_ampdu_factor;
2204 band->ht_cap.wpa_supp_ampdu_density = event->ht_cap.wifi_nxp_ampdu_density;
2205
2206 band->vht_cap.wpa_supp_vht_supported = event->vht_cap.wifi_nxp_vht_supported;
2207 band->vht_cap.wpa_supp_cap = event->vht_cap.wifi_nxp_cap;
2208
2209 band->vht_cap.vht_mcs.rx_mcs_map = event->vht_cap.vht_mcs.rx_mcs_map;
2210 band->vht_cap.vht_mcs.rx_highest = event->vht_cap.vht_mcs.rx_highest;
2211 band->vht_cap.vht_mcs.tx_mcs_map = event->vht_cap.vht_mcs.tx_mcs_map;
2212 band->vht_cap.vht_mcs.tx_highest = event->vht_cap.vht_mcs.tx_highest;
2213
2214 band->he_cap.wpa_supp_he_supported = event->he_cap.wifi_nxp_he_supported;
2215 band->he_cap.he_6ghz_capa = event->he_cap.he_6ghz_capa;
2216 memcpy(band->he_cap.mac_cap, event->he_cap.mac_cap, WIFI_NXP_HE_MAX_MAC_CAPAB_SIZE);
2217 memcpy(band->he_cap.phy_cap, event->he_cap.phy_cap, WIFI_NXP_HE_MAX_PHY_CAPAB_SIZE);
2218 memcpy(band->he_cap.mcs, event->he_cap.mcs, WIFI_NXP_HE_MAX_MCS_CAPAB_SIZE);
2219 memcpy(band->he_cap.ppet, event->he_cap.ppet, WIFI_NXP_HE_MAX_PPET_CAPAB_SIZE);
2220
2221 band->band = event->band;
2222
2223 return WM_SUCCESS;
2224 }
2225
wifi_nxp_wpa_supp_event_get_wiphy(void * if_priv,struct wifi_nxp_event_get_wiphy * wiphy_info,unsigned int event_len)2226 void wifi_nxp_wpa_supp_event_get_wiphy(void *if_priv,
2227 struct wifi_nxp_event_get_wiphy *wiphy_info,
2228 unsigned int event_len)
2229 {
2230 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2231 struct wpa_supp_event_supported_band band;
2232
2233 if (!if_priv || !wiphy_info || !event_len) {
2234 supp_e("%s: Invalid parameters", __func__);
2235 return;
2236 }
2237
2238 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2239
2240 memset(&band, 0, sizeof(band));
2241
2242 for (int i = 0; i < WIFI_NXP_EVENT_GET_WIPHY_NUM_BANDS; i++) {
2243 if (wifi_nxp_parse_sband(&wiphy_info->sband[i], &band) != WM_SUCCESS) {
2244 continue;
2245 }
2246 if (wifi_if_ctx_rtos->bss_type == BSS_TYPE_STA)
2247 {
2248 if (wifi_if_ctx_rtos->supp_drv_if_ctx && wifi_if_ctx_rtos->supp_callbk_fns.get_wiphy_res) {
2249 wifi_if_ctx_rtos->supp_callbk_fns.get_wiphy_res(wifi_if_ctx_rtos->supp_drv_if_ctx, &band);
2250 }
2251 }
2252 else
2253 {
2254 if (wifi_if_ctx_rtos->hapd_drv_if_ctx && wifi_if_ctx_rtos->hostapd_callbk_fns.get_wiphy_res) {
2255 wifi_if_ctx_rtos->hostapd_callbk_fns.get_wiphy_res(wifi_if_ctx_rtos->hapd_drv_if_ctx, &band);
2256 }
2257 }
2258 }
2259
2260 if (wifi_if_ctx_rtos->bss_type == BSS_TYPE_STA)
2261 {
2262 if (wifi_if_ctx_rtos->supp_drv_if_ctx && wifi_if_ctx_rtos->supp_callbk_fns.get_wiphy_res) {
2263 wifi_if_ctx_rtos->supp_callbk_fns.get_wiphy_res(wifi_if_ctx_rtos->supp_drv_if_ctx, NULL);
2264 }
2265 }
2266 else
2267 {
2268 if (wifi_if_ctx_rtos->hapd_drv_if_ctx && wifi_if_ctx_rtos->hostapd_callbk_fns.get_wiphy_res) {
2269 wifi_if_ctx_rtos->hostapd_callbk_fns.get_wiphy_res(wifi_if_ctx_rtos->hapd_drv_if_ctx, NULL);
2270 }
2271 }
2272 }
2273
wifi_nxp_wpa_supp_get_wiphy(void * if_priv)2274 int wifi_nxp_wpa_supp_get_wiphy(void *if_priv)
2275 {
2276 int status = -WM_FAIL;
2277 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2278
2279 if (!if_priv) {
2280 supp_e("%s: Missing interface context", __func__);
2281 goto out;
2282 }
2283
2284 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2285
2286 status = wifi_nxp_get_wiphy(wifi_if_ctx_rtos->bss_type);
2287
2288 if (status != WM_SUCCESS) {
2289 supp_e("%s: wifi nxp get_wiphy failed", __func__);
2290 goto out;
2291 }
2292 out:
2293 return status;
2294 }
2295
2296 #if 0
2297 int wifi_nxp_wpa_supp_register_frame(void *if_priv,
2298 u16 type, const u8 *match, size_t match_len,
2299 bool multicast)
2300 {
2301 enum wifi_nxp_status status = wifi_nxp_STATUS_FAIL;
2302 struct wifi_nxp_wifi_if_ctx_rtos *wifi_if_ctx_rtos = NULL;
2303 struct wifi_nxp_ctx_zep *rpu_ctx_zep = NULL;
2304 struct wifi_nxp_umac_mgmt_frame_info frame_info;
2305
2306 if (!if_priv || !match || !match_len) {
2307 LOG_ERR("%s: Invalid parameters", __func__);
2308 goto out;
2309 }
2310
2311 wifi_if_ctx_rtos = if_priv;
2312 rpu_ctx_zep = wifi_if_ctx_rtos->rpu_ctx_zep;
2313
2314 memset(&frame_info, 0, sizeof(frame_info));
2315
2316 frame_info.frame_type = type;
2317 frame_info.frame_match.frame_match_len = match_len;
2318 memcpy(frame_info.frame_match.frame_match, match, match_len);
2319
2320 status = wifi_nxp_fmac_register_frame(rpu_ctx_zep->rpu_ctx, wifi_if_ctx_rtos->vif_idx,
2321 &frame_info);
2322
2323 if (status != wifi_nxp_STATUS_SUCCESS) {
2324 LOG_ERR("%s: wifi_nxp_fmac_register_frame failed", __func__);
2325 goto out;
2326 }
2327 out:
2328 return status;
2329 }
2330
2331 void wifi_nxp_wpa_supp_event_mgmt_rx_callbk_fn(void *if_priv,
2332 struct wifi_nxp_umac_event_mlme *mlme_event,
2333 unsigned int event_len)
2334 {
2335 struct wifi_nxp_wifi_if_ctx_rtos *wifi_if_ctx_rtos = NULL;
2336
2337 if (!if_priv) {
2338 LOG_ERR("%s: Missing interface context", __func__);
2339 return;
2340 }
2341
2342 wifi_if_ctx_rtos = if_priv;
2343
2344 if (!mlme_event || !event_len) {
2345 LOG_ERR("%s: Missing MLME event data", __func__);
2346 return;
2347 }
2348
2349 if (wifi_if_ctx_rtos->supp_drv_if_ctx && wifi_if_ctx_rtos->supp_callbk_fns.mgmt_rx) {
2350 wifi_if_ctx_rtos->supp_callbk_fns.mgmt_rx(wifi_if_ctx_rtos->supp_drv_if_ctx,
2351 mlme_event->frame.frame,
2352 mlme_event->frame.frame_len,
2353 mlme_event->frequency,
2354 mlme_event->rx_signal_dbm);
2355 }
2356 }
2357 #endif
2358
wifi_nxp_wpa_supp_get_capa(void * if_priv,struct wpa_driver_capa * capa)2359 int wifi_nxp_wpa_supp_get_capa(void *if_priv, struct wpa_driver_capa *capa)
2360 {
2361 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2362
2363 if (!if_priv || !capa) {
2364 supp_e("%s: Invalid parameters", __func__);
2365 goto out;
2366 }
2367
2368 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2369
2370 os_memset(capa, 0, sizeof(*capa));
2371
2372 capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
2373 capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
2374 capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
2375 capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
2376 capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
2377 capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
2378 capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
2379 capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
2380 capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
2381
2382 /* Use SME */
2383 capa->flags = 0;
2384 capa->flags |= WPA_DRIVER_FLAGS_SME;
2385 capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
2386 capa->flags |= WPA_DRIVER_FLAGS_SAE;
2387 capa->flags |= WPA_DRIVER_FLAGS_ACS_OFFLOAD;
2388 capa->flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
2389 //capa->flags |= WPA_DRIVER_FLAGS_AP_UAPSD;
2390 capa->flags |= WPA_DRIVER_FLAGS_INACTIVITY_TIMER;
2391 if (IS_ENABLED(CONFIG_NXP_WIFI_SOFTAP_SUPPORT))
2392 {
2393 capa->flags |= WPA_DRIVER_FLAGS_AP;
2394 capa->flags |= WPA_DRIVER_FLAGS_AP_MLME;
2395 capa->flags |= WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT;
2396 capa->flags |= WPA_DRIVER_FLAGS_AP_CSA;
2397 capa->flags2 |= WPA_DRIVER_FLAGS2_AP_SME;
2398 }
2399 #if !defined(RW610) && !defined(SD8801)
2400 capa->flags |= WPA_DRIVER_FLAGS_HT_2040_COEX;
2401 #endif
2402 capa->flags |= WPA_DRIVER_FLAGS_HE_CAPABILITIES;
2403 capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
2404
2405 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_RRM;
2406 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT;
2407 capa->rrm_flags |= WPA_DRIVER_FLAGS_TX_POWER_INSERTION;
2408
2409 capa->max_scan_ssids = 1;
2410 capa->max_sched_scan_ssids = 1;
2411 capa->sched_scan_supported = 0;
2412 capa->max_remain_on_chan = 5000;
2413 capa->max_stations = 32;
2414 capa->max_acl_mac_addrs = 32;
2415
2416 capa->extended_capa = g_extended_capa;
2417 capa->extended_capa_mask = g_extended_capa_mask;
2418 capa->extended_capa_len = 10;
2419
2420 out:
2421 return 0;
2422 }
2423
wifi_nxp_wpa_supp_get_conn_info(void * if_priv,struct wpa_conn_info * info)2424 int wifi_nxp_wpa_supp_get_conn_info(void *if_priv, struct wpa_conn_info *info)
2425 {
2426 int ret = -WM_FAIL;
2427
2428 if (!if_priv || !info) {
2429 supp_e("%s: Invalid params", __func__);
2430 goto out;
2431 }
2432
2433 ret = wifi_nxp_get_conn_info(&info->beacon_interval, &info->dtim_period, &info->twt_capable);
2434 if (ret != WM_SUCCESS) {
2435 supp_e("%s: Failed to get beacon info", __func__);
2436 goto out;
2437 }
2438
2439 ret = WM_SUCCESS;
2440
2441 out:
2442 return ret;
2443 }
2444
wifi_nxp_wpa_supp_remain_on_channel(void * if_priv,unsigned int freq,unsigned int duration)2445 int wifi_nxp_wpa_supp_remain_on_channel(void *if_priv, unsigned int freq, unsigned int duration)
2446 {
2447 int status = -WM_FAIL;
2448 int ret = -1;
2449 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2450 int channel;
2451
2452 if (!if_priv)
2453 {
2454 supp_e("%s: Invalid params", __func__);
2455 goto out;
2456 }
2457 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2458 if (freq)
2459 {
2460 wifi_if_ctx_rtos->remain_on_channel_freq = freq;
2461 }
2462 wifi_if_ctx_rtos->remain_on_channel_duration = duration;
2463
2464 channel = freq_to_chan(wifi_if_ctx_rtos->remain_on_channel_freq);
2465
2466 wifi_if_ctx_rtos->supp_called_remain_on_chan = true;
2467 wifi_if_ctx_rtos->remain_on_chan_is_canceled = false;
2468 status = wifi_remain_on_channel(true, channel, duration);
2469
2470 if (status != WM_SUCCESS)
2471 {
2472 supp_e("%s: Remain on channel cmd failed", __func__);
2473 ret = -1;
2474 }
2475 else
2476 {
2477 supp_d("%s:Remain on channel sent successfully", __func__);
2478 ret = 0;
2479 }
2480 out:
2481 return ret;
2482 }
2483
wifi_nxp_wpa_supp_cancel_remain_on_channel(void * if_priv)2484 int wifi_nxp_wpa_supp_cancel_remain_on_channel(void *if_priv)
2485 {
2486 int status = -WM_FAIL;
2487 int ret = -1;
2488 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2489
2490 if (!if_priv)
2491 {
2492 supp_e("%s: Invalid params", __func__);
2493 goto out;
2494 }
2495 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2496 if (wifi_if_ctx_rtos->remain_on_chan_is_canceled)
2497 {
2498 supp_d("%s:Already canceled, ignore it", __func__);
2499 ret = 0;
2500 goto out;
2501 }
2502
2503 wifi_if_ctx_rtos->supp_called_remain_on_chan = true;
2504 wifi_if_ctx_rtos->remain_on_chan_is_canceled = true;
2505 status = wifi_remain_on_channel(false, 0, 0);
2506
2507 if (status != WM_SUCCESS)
2508 {
2509 supp_e("%s: Cancel on channel cmd failed", __func__);
2510 ret = -1;
2511 }
2512 else
2513 {
2514 supp_d("%s:Cancel on channel sent successfully", __func__);
2515 ret = 0;
2516 }
2517 out:
2518 return ret;
2519 }
2520
wifi_nxp_wpa_supp_event_proc_mgmt_rx(void * if_priv,nxp_wifi_event_mlme_t * mgmt_rx,unsigned int event_len,int rssi)2521 void wifi_nxp_wpa_supp_event_proc_mgmt_rx(void *if_priv, nxp_wifi_event_mlme_t *mgmt_rx,
2522 unsigned int event_len, int rssi)
2523 {
2524 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2525 struct ieee80211_mgmt *mgmt = NULL;
2526 unsigned char *frame = NULL;
2527 unsigned int frame_len = 0;
2528
2529 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2530
2531 frame = (unsigned char *)mgmt_rx->frame.frame;
2532 frame_len = mgmt_rx->frame.frame_len;
2533 mgmt = (struct ieee80211_mgmt *)frame;
2534
2535 if (frame_len < 4 + (2 * WIFI_ETH_ADDR_LEN))
2536 {
2537 supp_e("%s: MLME event too short", __func__);
2538 return;
2539 }
2540
2541 if (frame_len < 24 + sizeof(mgmt->u.deauth))
2542 {
2543 supp_e("%s: MGMT RX frame too short", __func__);
2544 return;
2545 }
2546
2547 #if CONFIG_WPA_SUPP_AP
2548 if (wifi_if_ctx_rtos->hostapd)
2549 {
2550 wifi_if_ctx_rtos->hostapd_callbk_fns.mgmt_rx(wifi_if_ctx_rtos->hapd_drv_if_ctx,
2551 frame, frame_len, mgmt_rx->frame.freq, rssi);
2552 }
2553 else
2554 #endif
2555 {
2556 wifi_if_ctx_rtos->supp_callbk_fns.mgmt_rx(wifi_if_ctx_rtos->supp_drv_if_ctx,
2557 frame, frame_len, mgmt_rx->frame.freq, rssi);
2558 }
2559 }
2560
wifi_nxp_wpa_supp_event_proc_ecsa_complete(void * if_priv,nxp_wifi_ch_switch_info * ch_switch_info)2561 void wifi_nxp_wpa_supp_event_proc_ecsa_complete(void *if_priv, nxp_wifi_ch_switch_info *ch_switch_info)
2562 {
2563 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2564 union wpa_event_data event;
2565
2566 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2567
2568 memset(&event, 0, sizeof(event));
2569
2570 event.ch_switch.freq = ch_switch_info->center_freq;
2571 event.ch_switch.ht_enabled = ch_switch_info->ht_enabled;
2572 event.ch_switch.ch_offset = ch_switch_info->ch_offset;
2573 event.ch_switch.ch_width = (enum chan_width)ch_switch_info->ch_width;
2574 event.ch_switch.cf1 = ch_switch_info->center_freq1;
2575 event.ch_switch.cf2 = ch_switch_info->center_freq2;
2576
2577 #if CONFIG_WPA_SUPP_AP
2578 if (wifi_if_ctx_rtos->hostapd)
2579 {
2580 wifi_if_ctx_rtos->hostapd_callbk_fns.ecsa_complete(wifi_if_ctx_rtos->hapd_drv_if_ctx, &event);
2581 }
2582 else
2583 #endif
2584 {
2585 wifi_if_ctx_rtos->supp_callbk_fns.ecsa_complete(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
2586 }
2587 }
2588
2589 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
wifi_nxp_wpa_supp_event_proc_eapol_rx(void * if_priv,nxp_wifi_event_eapol_mlme_t * eapol_rx,unsigned int event_len)2590 void wifi_nxp_wpa_supp_event_proc_eapol_rx(void *if_priv, nxp_wifi_event_eapol_mlme_t *eapol_rx, unsigned int event_len)
2591 {
2592 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2593 union wpa_event_data event;
2594
2595 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2596
2597 memset(&event, 0, sizeof(event));
2598
2599 event.eapol_rx.src = (const unsigned char *)eapol_rx->mac_addr;
2600 event.eapol_rx.data = (const unsigned char *)eapol_rx->frame.frame;
2601 event.eapol_rx.data_len = eapol_rx->frame.frame_len;
2602
2603 #if CONFIG_WPA_SUPP_AP
2604 if (wifi_if_ctx_rtos->hostapd)
2605 {
2606 wifi_if_ctx_rtos->hostapd_callbk_fns.eapol_rx(wifi_if_ctx_rtos->hapd_drv_if_ctx, &event);
2607 }
2608 else
2609 #endif
2610 {
2611 wifi_if_ctx_rtos->supp_callbk_fns.eapol_rx(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
2612 }
2613 }
2614 #endif
2615
wifi_nxp_wpa_supp_event_proc_dfs_cac_started(void * if_priv,nxp_wifi_dfs_cac_info * dfs_cac_info)2616 void wifi_nxp_wpa_supp_event_proc_dfs_cac_started(void *if_priv, nxp_wifi_dfs_cac_info *dfs_cac_info)
2617 {
2618 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2619 union wpa_event_data event;
2620
2621 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2622
2623 memset(&event, 0, sizeof(event));
2624
2625 event.dfs_event.freq = dfs_cac_info->center_freq;
2626 event.dfs_event.ht_enabled = dfs_cac_info->ht_enabled;
2627 event.dfs_event.chan_offset = dfs_cac_info->ch_offset;
2628 event.dfs_event.chan_width = (enum chan_width)dfs_cac_info->ch_width;
2629 event.dfs_event.cf1 = dfs_cac_info->center_freq1;
2630 event.dfs_event.cf2 = dfs_cac_info->center_freq2;
2631
2632 #if CONFIG_WPA_SUPP_AP
2633 if (wifi_if_ctx_rtos->hostapd)
2634 {
2635 wifi_if_ctx_rtos->hostapd_callbk_fns.dfs_cac_started(wifi_if_ctx_rtos->hapd_drv_if_ctx, &event);
2636 }
2637 else
2638 #endif
2639 {
2640 wifi_if_ctx_rtos->supp_callbk_fns.dfs_cac_started(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
2641 }
2642 }
2643
wifi_nxp_wpa_supp_event_proc_dfs_cac_finished(void * if_priv,nxp_wifi_dfs_cac_info * dfs_cac_info)2644 void wifi_nxp_wpa_supp_event_proc_dfs_cac_finished(void *if_priv, nxp_wifi_dfs_cac_info *dfs_cac_info)
2645 {
2646 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2647 union wpa_event_data event;
2648
2649 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2650
2651 memset(&event, 0, sizeof(event));
2652
2653 event.dfs_event.freq = dfs_cac_info->center_freq;
2654 event.dfs_event.ht_enabled = dfs_cac_info->ht_enabled;
2655 event.dfs_event.chan_offset = dfs_cac_info->ch_offset;
2656 event.dfs_event.chan_width = (enum chan_width)dfs_cac_info->ch_width;
2657 event.dfs_event.cf1 = dfs_cac_info->center_freq1;
2658 event.dfs_event.cf2 = dfs_cac_info->center_freq2;
2659
2660 #if CONFIG_WPA_SUPP_AP
2661 if (wifi_if_ctx_rtos->hostapd)
2662 {
2663 wifi_if_ctx_rtos->hostapd_callbk_fns.dfs_cac_finished(wifi_if_ctx_rtos->hapd_drv_if_ctx, &event);
2664 }
2665 else
2666 #endif
2667 {
2668 wifi_if_ctx_rtos->supp_callbk_fns.dfs_cac_finished(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
2669 }
2670 }
2671
wifi_nxp_wpa_supp_event_signal_change(void * if_priv,t_s16 * curr_rssi)2672 void wifi_nxp_wpa_supp_event_signal_change(void *if_priv, t_s16 *curr_rssi)
2673 {
2674 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2675 union wpa_event_data event;
2676
2677 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2678
2679 if (wifi_if_ctx_rtos == NULL)
2680 {
2681 wifi_e("%s: wifi_if_ctx_rtos is NULL", __func__);
2682 return;
2683 }
2684 memset(&event, 0, sizeof(event));
2685 event.signal_change.above_threshold = 0;
2686 event.signal_change.current_signal = abs(*curr_rssi);
2687
2688 wifi_if_ctx_rtos->supp_callbk_fns.signal_change(wifi_if_ctx_rtos->supp_drv_if_ctx, &event);
2689 }
2690
2691 #if CONFIG_WIFI_SOFTAP_SUPPORT
wifi_nxp_wpa_supp_init_ap(void * if_priv,struct wpa_driver_associate_params * params)2692 int wifi_nxp_wpa_supp_init_ap(void *if_priv, struct wpa_driver_associate_params *params)
2693 {
2694 int status = -WM_FAIL;
2695 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2696 nxp_wifi_ap_info_t *ap_params = NULL;
2697
2698 dump_hex(params, sizeof(struct wpa_driver_associate_params));
2699
2700 int ret = -1;
2701
2702 if ((!if_priv) || (!params))
2703 {
2704 supp_e("%s: Invalid params", __func__);
2705 goto out;
2706 }
2707
2708 if (params->mode != IEEE80211_MODE_AP) {
2709 supp_e("%s: Invalid mode", __func__);
2710 goto out;
2711 }
2712
2713 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2714
2715 ap_params = (nxp_wifi_ap_info_t *)OSA_MemoryAllocate(sizeof(nxp_wifi_ap_info_t));
2716
2717 if (!ap_params)
2718 {
2719 supp_e("%s: ap params calloc failed", __func__);
2720 goto out;
2721 }
2722
2723 if (params->auth_alg & WPA_AUTH_ALG_FT)
2724 {
2725 // assoc_params->is_ft = true;
2726 }
2727
2728 if (params->bssid)
2729 {
2730 memcpy(ap_params->bssid, params->bssid, WIFI_ETH_ADDR_LEN);
2731 }
2732
2733 if (params->freq.freq)
2734 {
2735 int channel = freq_to_chan(params->freq.freq);
2736 ap_params->chan.channel = channel;
2737 }
2738
2739 if (params->ssid)
2740 {
2741 ap_params->ssid.ssid_len = params->ssid_len;
2742
2743 memcpy(ap_params->ssid.ssid, params->ssid, params->ssid_len);
2744 }
2745
2746 if (params->wpa_ie)
2747 {
2748 // ap_params->wpa_ie.ie_len = params->wpa_ie_len;
2749 // memcpy(ap_params->wpa_ie.ie, params->wpa_ie, params->wpa_ie_len);
2750 }
2751
2752 wifi_d("initiating init ap");
2753
2754 status = wifi_nxp_init_ap(ap_params);
2755
2756 if (status != WM_SUCCESS)
2757 {
2758 supp_e("%s: MLME command failed (init ap)", __func__);
2759 }
2760 else
2761 {
2762 supp_d("%s: Init AP is done successfully", __func__);
2763 ret = 0;
2764 }
2765 OSA_MemoryFree((void *)ap_params);
2766
2767 out:
2768 return ret;
2769 }
2770 #endif
2771
2772 #if CONFIG_WPA_SUPP_AP
wifi_nxp_hostapd_dev_init(void * hapd_drv_if_ctx,const char * iface_name,rtos_hostapd_dev_callbk_fns * hostapd_callbk_fns)2773 void *wifi_nxp_hostapd_dev_init(void *hapd_drv_if_ctx,
2774 const char *iface_name,
2775 rtos_hostapd_dev_callbk_fns *hostapd_callbk_fns)
2776 {
2777 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
2778
2779 const struct netif *iface = NULL;
2780
2781 iface = net_if_get_binding(iface_name);
2782
2783 if (!iface)
2784 {
2785 supp_e("%s: Interface %s not found", __func__, iface_name);
2786 return NULL;
2787 }
2788
2789 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)wm_wifi.hapd_if_priv;
2790
2791 if (!wifi_if_ctx_rtos)
2792 {
2793 supp_e("%s: Interface %s not properly initialized", __func__, iface_name);
2794 return NULL;
2795 }
2796
2797 memset(wifi_if_ctx_rtos, 0x00, sizeof(struct wifi_nxp_ctx_rtos));
2798
2799 wifi_if_ctx_rtos->iface_ctx = iface;
2800
2801 wifi_if_ctx_rtos->hostapd = true;
2802
2803 wifi_if_ctx_rtos->bss_type = BSS_TYPE_UAP;
2804
2805 wifi_if_ctx_rtos->hapd_drv_if_ctx = hapd_drv_if_ctx;
2806
2807 wifi_if_ctx_rtos->last_mgmt_tx_data = (uint8_t *)OSA_MemoryAllocate(MAX_MGMT_TX_FRAME_SIZE);
2808
2809 if (!wifi_if_ctx_rtos->last_mgmt_tx_data)
2810 {
2811 supp_e("%s: Buffer to store mgmt tx failed", __func__);
2812 return NULL;
2813 }
2814
2815 memcpy(&wifi_if_ctx_rtos->hostapd_callbk_fns, hostapd_callbk_fns, sizeof(wifi_if_ctx_rtos->hostapd_callbk_fns));
2816
2817 return wifi_if_ctx_rtos;
2818 }
2819
wifi_nxp_hostapd_dev_deinit(void * if_priv)2820 void wifi_nxp_hostapd_dev_deinit(void *if_priv)
2821 {
2822 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
2823
2824 if (wifi_if_ctx_rtos != NULL)
2825 {
2826 OSA_MemoryFree((void *)wifi_if_ctx_rtos->last_mgmt_tx_data);
2827 memset(wifi_if_ctx_rtos, 0x00, sizeof(struct wifi_nxp_ctx_rtos));
2828 }
2829 }
2830
wifi_nxp_hostapd_set_modes(void * if_priv,struct hostapd_hw_modes * modes)2831 int wifi_nxp_hostapd_set_modes(void *if_priv, struct hostapd_hw_modes *modes)
2832 {
2833 int status = -WM_FAIL;
2834 #if CONFIG_11AX
2835 t_u8 bandwidth = wifi_uap_get_bandwidth();
2836 #endif
2837
2838 if ((!if_priv) || (!modes))
2839 {
2840 supp_e("%s: Invalid params", __func__);
2841 goto out;
2842 }
2843
2844 status = wifi_setup_ht_cap(&modes[HOSTAPD_MODE_IEEE80211G].ht_capab, &modes[HOSTAPD_MODE_IEEE80211G].mcs_set[0],
2845 &modes[HOSTAPD_MODE_IEEE80211G].a_mpdu_params, 0);
2846 if (status != WM_SUCCESS)
2847 {
2848 supp_e("%s: wifi nxp set 2G infra ht cap failed", __func__);
2849 goto out;
2850 }
2851
2852 #if CONFIG_5GHz_SUPPORT
2853 if (!ISSUPP_NO5G(mlan_adap->fw_cap_ext))
2854 {
2855 status = wifi_setup_ht_cap(&modes[HOSTAPD_MODE_IEEE80211A].ht_capab, &modes[HOSTAPD_MODE_IEEE80211A].mcs_set[0],
2856 &modes[HOSTAPD_MODE_IEEE80211A].a_mpdu_params, 1);
2857 if (status != WM_SUCCESS)
2858 {
2859 supp_e("%s: wifi nxp set 5G infra ht cap failed", __func__);
2860 goto out;
2861 }
2862 }
2863 #endif
2864
2865 modes[HOSTAPD_MODE_IEEE80211G].flags |= HOSTAPD_MODE_FLAG_HT_INFO_KNOWN;
2866 #if CONFIG_5GHz_SUPPORT
2867 if (!ISSUPP_NO5G(mlan_adap->fw_cap_ext))
2868 {
2869 modes[HOSTAPD_MODE_IEEE80211A].flags |= HOSTAPD_MODE_FLAG_HT_INFO_KNOWN;
2870 }
2871 #endif
2872
2873 #if CONFIG_11AC
2874 status = wifi_setup_vht_cap((t_u32 *)&modes[HOSTAPD_MODE_IEEE80211G].vht_capab,
2875 modes[HOSTAPD_MODE_IEEE80211G].vht_mcs_set, 0);
2876 if (status != WM_SUCCESS)
2877 {
2878 supp_e("%s: wifi nxp set 2G infra vht cap failed", __func__);
2879 goto out;
2880 }
2881
2882 #if CONFIG_5GHz_SUPPORT
2883 if (!ISSUPP_NO5G(mlan_adap->fw_cap_ext))
2884 {
2885 status = wifi_setup_vht_cap((t_u32 *)&modes[HOSTAPD_MODE_IEEE80211A].vht_capab,
2886 modes[HOSTAPD_MODE_IEEE80211A].vht_mcs_set, 1);
2887 if (status != WM_SUCCESS)
2888 {
2889 supp_e("%s: wifi nxp set 5G infra vht cap failed", __func__);
2890 goto out;
2891 }
2892 }
2893 #endif
2894
2895 modes[HOSTAPD_MODE_IEEE80211G].flags |= HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
2896 #if CONFIG_5GHz_SUPPORT
2897 if (!ISSUPP_NO5G(mlan_adap->fw_cap_ext))
2898 {
2899 modes[HOSTAPD_MODE_IEEE80211A].flags |= HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
2900 }
2901 #endif
2902 #endif
2903
2904 #if CONFIG_11AX
2905 status = wifi_setup_he_cap(
2906 (nxp_wifi_he_capabilities *)&modes[HOSTAPD_MODE_IEEE80211G].he_capab[IEEE80211_MODE_INFRA], 0);
2907 if (status != WM_SUCCESS)
2908 {
2909 supp_e("%s: wifi nxp set 2G infra he cap failed", __func__);
2910 goto out;
2911 }
2912
2913 status =
2914 wifi_setup_he_cap((nxp_wifi_he_capabilities *)&modes[HOSTAPD_MODE_IEEE80211G].he_capab[IEEE80211_MODE_AP], 0);
2915 if (status != WM_SUCCESS)
2916 {
2917 supp_e("%s: wifi nxp set 2G ap he cap failed", __func__);
2918 goto out;
2919 }
2920 if (bandwidth == BANDWIDTH_20MHZ)
2921 {
2922 modes[HOSTAPD_MODE_IEEE80211G].he_capab[IEEE80211_MODE_AP].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] = 0;
2923 }
2924 #if CONFIG_5GHz_SUPPORT
2925 if (!ISSUPP_NO5G(mlan_adap->fw_cap_ext))
2926 {
2927 status = wifi_setup_he_cap(
2928 (nxp_wifi_he_capabilities *)&modes[HOSTAPD_MODE_IEEE80211A].he_capab[IEEE80211_MODE_INFRA], 1);
2929 if (status != WM_SUCCESS)
2930 {
2931 supp_e("%s: wifi nxp set 5G infra he cap failed", __func__);
2932 goto out;
2933 }
2934
2935 status = wifi_setup_he_cap(
2936 (nxp_wifi_he_capabilities *)&modes[HOSTAPD_MODE_IEEE80211A].he_capab[IEEE80211_MODE_AP], 1);
2937 if (status != WM_SUCCESS)
2938 {
2939 supp_e("%s: wifi nxp set 5G ap he cap failed", __func__);
2940 goto out;
2941 }
2942 }
2943 if (bandwidth == BANDWIDTH_20MHZ)
2944 {
2945 modes[HOSTAPD_MODE_IEEE80211A].he_capab[IEEE80211_MODE_AP].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] = 0;
2946 }
2947 #endif
2948 #endif
2949
2950 wifi_setup_channel_info(modes[HOSTAPD_MODE_IEEE80211B].channels, modes[HOSTAPD_MODE_IEEE80211B].num_channels,
2951 BAND_2GHZ);
2952 wifi_setup_channel_info(modes[HOSTAPD_MODE_IEEE80211G].channels, modes[HOSTAPD_MODE_IEEE80211G].num_channels,
2953 BAND_2GHZ);
2954 #if CONFIG_5GHz_SUPPORT
2955 if (!ISSUPP_NO5G(mlan_adap->fw_cap_ext))
2956 {
2957 wifi_setup_channel_info(modes[HOSTAPD_MODE_IEEE80211A].channels, modes[HOSTAPD_MODE_IEEE80211A].num_channels,
2958 BAND_5GHZ);
2959 }
2960 #endif
2961
2962 status = WM_SUCCESS;
2963
2964 out:
2965 return status;
2966 }
2967
wifi_nxp_set_acs_params(nxp_wifi_acs_params * acs_params)2968 static void wifi_nxp_set_acs_params(nxp_wifi_acs_params *acs_params)
2969 {
2970 mlan_private *pmpriv = mlan_adap->priv[0];
2971 unsigned int channel = pmpriv->curr_bss_params.bss_descriptor.channel;
2972
2973 memset(acs_params, 0, sizeof(nxp_wifi_acs_params));
2974 acs_params->pri_freq = pmpriv->curr_bss_params.bss_descriptor.freq;
2975 acs_params->hw_mode = channel <= MAX_CHANNELS_BG ? 1 : 2;
2976 #if defined(RW610)
2977 acs_params->ch_width = 20;
2978 #else
2979 t_u8 chan_offset;
2980
2981 chan_offset = wifi_get_sec_channel_offset(channel);
2982 if (chan_offset == SEC_CHAN_ABOVE)
2983 {
2984 acs_params->sec_freq = acs_params->pri_freq + 20;
2985 }
2986 else if (chan_offset == SEC_CHAN_BELOW)
2987 {
2988 acs_params->sec_freq = acs_params->pri_freq - 20;
2989 }
2990 else
2991 {
2992 acs_params->sec_freq = acs_params->pri_freq;
2993 }
2994 #if CONFIG_5GHz_SUPPORT
2995 if (channel > MAX_CHANNELS_BG)
2996 {
2997 #if CONFIG_11AC
2998 if (wm_wifi.bandwidth == BANDWIDTH_80MHZ)
2999 {
3000 acs_params->ch_width = 80;
3001 }
3002 #endif
3003 }
3004 #endif
3005 if (wm_wifi.bandwidth == BANDWIDTH_40MHZ)
3006 {
3007 acs_params->ch_width = 40;
3008 }
3009 else
3010 {
3011 acs_params->sec_freq = 0;
3012 acs_params->ch_width = 20;
3013 }
3014 #endif
3015 }
3016
wifi_nxp_hostapd_do_acs(void * if_priv,struct drv_acs_params * params)3017 int wifi_nxp_hostapd_do_acs(void *if_priv, struct drv_acs_params *params)
3018 {
3019 int status = -WM_FAIL;
3020
3021 if ((!if_priv) || (!params))
3022 {
3023 supp_e("%s: Invalid params", __func__);
3024 goto out;
3025 }
3026
3027 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
3028 if(mlan_adap->priv[0]->media_connected)
3029 {
3030 nxp_wifi_acs_params acs_params;
3031
3032 wifi_nxp_set_acs_params(&acs_params);
3033 if (wm_wifi.supp_if_callbk_fns->acs_channel_sel_callbk_fn)
3034 {
3035 wm_wifi.supp_if_callbk_fns->acs_channel_sel_callbk_fn(wm_wifi.hapd_if_priv, &acs_params);
3036 }
3037 status = WM_SUCCESS;
3038 goto out;
3039 }
3040 #endif
3041
3042 status = wifi_uap_do_acs(params->freq_list);
3043 if (status != WM_SUCCESS)
3044 {
3045 supp_e("%s: wifi uap do acs failed", __func__);
3046 goto out;
3047 }
3048
3049 status = WM_SUCCESS;
3050
3051 out:
3052 return status;
3053 }
3054
3055 #define BSSID_OFFSET 16
3056
wifi_nxp_hostapd_set_ap(void * if_priv,int beacon_set,struct wpa_driver_ap_params * params)3057 int wifi_nxp_hostapd_set_ap(void *if_priv, int beacon_set, struct wpa_driver_ap_params *params)
3058 {
3059 int status = -WM_FAIL;
3060 int ret = -1;
3061 nxp_wifi_ap_info_t *ap_params = NULL;
3062 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
3063
3064 if ((!if_priv) || (!params))
3065 {
3066 supp_e("%s: Invalid params", __func__);
3067 goto out;
3068 }
3069
3070 ap_params = (nxp_wifi_ap_info_t *)OSA_MemoryAllocate(sizeof(nxp_wifi_ap_info_t));
3071
3072 if (!ap_params)
3073 {
3074 supp_e("%s: ap params calloc failed", __func__);
3075 goto out;
3076 }
3077
3078 ap_params->beacon_set = beacon_set;
3079
3080 memcpy(ap_params->bssid, params->head + BSSID_OFFSET, WIFI_ETH_ADDR_LEN);
3081
3082 memcpy(ap_params->head_ie.ie, params->head, params->head_len);
3083
3084 ap_params->head_ie.ie_len = params->head_len;
3085
3086 memcpy(ap_params->tail_ie.ie, params->tail, params->tail_len);
3087
3088 ap_params->tail_ie.ie_len = params->tail_len;
3089
3090 ap_params->dtim_period = params->dtim_period;
3091
3092 ap_params->beacon_int = params->beacon_int;
3093
3094 if (params->proberesp && params->proberesp_len)
3095 {
3096 memcpy(ap_params->proberesp.ie, params->proberesp, params->proberesp_len);
3097
3098 ap_params->proberesp_ies.ie_len = params->proberesp_len;
3099 }
3100
3101 if (params->ssid && params->ssid_len)
3102 {
3103 memcpy((void *)ap_params->ssid.ssid, (const void *)params->ssid, (size_t)params->ssid_len);
3104
3105 ap_params->ssid.ssid_len = params->ssid_len;
3106 }
3107
3108 ap_params->hide_ssid = params->hide_ssid;
3109
3110 ap_params->pairwise_ciphers = params->pairwise_ciphers;
3111 ap_params->group_cipher = params->group_cipher;
3112 ap_params->key_mgmt_suites = params->key_mgmt_suites;
3113 ap_params->auth_algs = params->auth_algs;
3114 ap_params->wpa_version = params->wpa_version;
3115 ap_params->privacy = params->privacy;
3116
3117 if (params->beacon_ies)
3118 {
3119 memcpy(ap_params->beacon_ies.ie, params->beacon_ies->buf, params->beacon_ies->used);
3120
3121 ap_params->beacon_ies.ie_len = params->beacon_ies->used;
3122 }
3123
3124 if (params->proberesp_ies)
3125 {
3126 memcpy(ap_params->proberesp_ies.ie, params->proberesp_ies->buf, params->proberesp_ies->used);
3127
3128 ap_params->proberesp_ies.ie_len = params->proberesp_ies->used;
3129 }
3130
3131 if (params->assocresp_ies)
3132 {
3133 memcpy(ap_params->assocresp_ies.ie, params->assocresp_ies->buf, params->assocresp_ies->used);
3134
3135 ap_params->assocresp_ies.ie_len = params->assocresp_ies->used;
3136 }
3137
3138 ap_params->ht_opmode = params->ht_opmode;
3139 ap_params->ap_max_inactivity = params->ap_max_inactivity;
3140 ap_params->reenable = params->reenable;
3141 ap_params->twt_responder = params->twt_responder;
3142 ap_params->sae_pwe = params->sae_pwe;
3143
3144 if (params->freq)
3145 {
3146 ap_params->chan.mode = (enum wifi_mode)params->freq->mode;
3147 ap_params->chan.freq = params->freq->freq;
3148 ap_params->chan.channel = params->freq->channel;
3149 ap_params->chan.sec_channel_offset = params->freq->sec_channel_offset;
3150 ap_params->chan.bandwidth = params->freq->bandwidth;
3151 ap_params->chan.ht_enabled = params->freq->ht_enabled;
3152 ap_params->chan.vht_enabled = params->freq->vht_enabled;
3153 ap_params->chan.he_enabled = params->freq->he_enabled;
3154 ap_params->chan.center_freq1 = params->freq->center_freq1;
3155 ap_params->chan.center_freq2 = params->freq->center_freq2;
3156 }
3157
3158 status = wifi_nxp_beacon_config(ap_params);
3159 if (status != WM_SUCCESS)
3160 {
3161 supp_e("%s: wifi nxp beacon config failed", __func__);
3162 goto out;
3163 }
3164
3165 if (!beacon_set)
3166 {
3167 wifi_if_ctx_rtos->uap_started = true;
3168 }
3169
3170 ret = 0;
3171 out:
3172 if (ap_params != NULL)
3173 {
3174 OSA_MemoryFree((void *)ap_params);
3175 }
3176 return ret;
3177 }
3178
wifi_nxp_hostapd_sta_add(void * if_priv,struct hostapd_sta_add_params * params)3179 int wifi_nxp_hostapd_sta_add(void *if_priv, struct hostapd_sta_add_params *params)
3180 {
3181 int status = -WM_FAIL;
3182 nxp_wifi_sta_info_t *sta_params = NULL;
3183
3184 if ((!if_priv) || (!params))
3185 {
3186 supp_e("%s: Invalid params", __func__);
3187 goto out;
3188 }
3189
3190 sta_params = (nxp_wifi_sta_info_t *)OSA_MemoryAllocate(sizeof(nxp_wifi_sta_info_t));
3191
3192 if (!sta_params)
3193 {
3194 supp_e("%s: sta params calloc failed", __func__);
3195 goto out;
3196 }
3197
3198 sta_params->set = params->set;
3199
3200 memcpy(sta_params->addr, params->addr, WIFI_ETH_ADDR_LEN);
3201
3202 sta_params->aid = params->aid;
3203
3204 sta_params->capability = params->capability;
3205
3206 if (params->supp_rates_len)
3207 {
3208 sta_params->supp_rates_len = params->supp_rates_len;
3209 memcpy((void *)sta_params->supp_rates, (const void *)params->supp_rates, (size_t)sta_params->supp_rates_len);
3210 }
3211
3212 sta_params->listen_interval = params->listen_interval;
3213
3214 if (params->ext_capab)
3215 {
3216 memcpy(sta_params->ext_capab, params->ext_capab, params->ext_capab_len);
3217 sta_params->ext_capab_len = params->ext_capab_len;
3218 }
3219
3220 sta_params->qosinfo = params->qosinfo;
3221
3222 if (params->flags & WPA_STA_AUTHORIZED)
3223 sta_params->flags |= STA_FLAG_AUTHORIZED;
3224
3225 if (params->flags & WPA_STA_WMM)
3226 sta_params->flags |= STA_FLAG_WME;
3227
3228 if (params->flags & WPA_STA_SHORT_PREAMBLE)
3229 sta_params->flags |= STA_FLAG_SHORT_PREAMBLE;
3230
3231 if (params->flags & WPA_STA_MFP)
3232 sta_params->flags |= STA_FLAG_MFP;
3233
3234 if (params->flags & WPA_STA_AUTHENTICATED)
3235 sta_params->flags |= STA_FLAG_AUTHENTICATED;
3236
3237 if (params->flags & WPA_STA_ASSOCIATED)
3238 sta_params->flags |= STA_FLAG_ASSOCIATED;
3239
3240 if (params->ht_capabilities)
3241 {
3242 memcpy(&sta_params->ht_capab, params->ht_capabilities, sizeof(struct ieee80211_ht_capabilities));
3243 sta_params->ht_capab_len = sizeof(struct ieee80211_ht_capabilities);
3244 }
3245
3246 if (params->vht_capabilities)
3247 {
3248 memcpy(&sta_params->vht_capab, params->vht_capabilities, sizeof(struct ieee80211_vht_capabilities));
3249 sta_params->vht_capab_len = sizeof(struct ieee80211_vht_capabilities);
3250 }
3251
3252 if (params->he_capab)
3253 {
3254 memcpy(&sta_params->he_capab, params->he_capab, sizeof(struct ieee80211_he_capabilities));
3255 sta_params->he_capab_len = params->he_capab_len;
3256 }
3257
3258 status = wifi_nxp_sta_add(sta_params);
3259 if (status != WM_SUCCESS)
3260 {
3261 supp_e("%s: wifi nxp sta add failed", __func__);
3262 }
3263
3264 wifi_uap_client_assoc(sta_params->addr, params->ht_capabilities ? 1 : 0);
3265 out:
3266 if (sta_params != NULL)
3267 {
3268 OSA_MemoryFree((void *)sta_params);
3269 }
3270 return status;
3271 }
3272
wifi_nxp_hostapd_sta_remove(void * if_priv,const u8 * addr)3273 int wifi_nxp_hostapd_sta_remove(void *if_priv, const u8 *addr)
3274 {
3275 int status = -WM_FAIL;
3276
3277 if ((!if_priv) || (!addr))
3278 {
3279 supp_e("%s: Invalid params", __func__);
3280 goto out;
3281 }
3282
3283 status = wifi_nxp_sta_remove(addr);
3284 if (status != WM_SUCCESS)
3285 {
3286 supp_e("%s: wifi nxp sta remove failed", __func__);
3287 }
3288
3289 wifi_uap_client_deauth((t_u8 *)addr);
3290 out:
3291 return status;
3292 }
3293
wifi_nxp_hostapd_send_eapol(void * if_priv,const u8 * data,size_t data_len)3294 int wifi_nxp_hostapd_send_eapol(void *if_priv, const u8 *data, size_t data_len)
3295 {
3296 int ret = -1;
3297 if ((!if_priv) || (!data))
3298 {
3299 supp_e("%s: Invalid params\n", __func__);
3300 goto out;
3301 }
3302
3303 ret = wifi_supp_inject_frame(WLAN_BSS_TYPE_UAP, data, data_len);
3304
3305 out:
3306 return ret;
3307 }
3308
wifi_nxp_hostapd_set_freq(void * if_priv,struct hostapd_freq_params * freq)3309 int wifi_nxp_hostapd_set_freq(void *if_priv, struct hostapd_freq_params *freq)
3310 {
3311 int ret = -1;
3312 nxp_wifi_chan_info_t chan;
3313
3314 if ((!if_priv) || (!freq))
3315 {
3316 supp_e("%s: Invalid params\n", __func__);
3317 goto out;
3318 }
3319
3320 memset(&chan, 0x00, sizeof(nxp_wifi_chan_info_t));
3321
3322 #if 0
3323 PRINTF("freq->freq: %d\r\n", freq->freq);
3324 PRINTF("freq->channel: %d\r\n", freq->channel);
3325 PRINTF("freq->ht_enabled: %d\r\n", freq->ht_enabled);
3326 PRINTF("freq->sec_channel_offset: %d\r\n", freq->sec_channel_offset);
3327 PRINTF("freq->vht_enabled: %d\r\n", freq->vht_enabled);
3328 PRINTF("freq->he_enabled: %d\r\n", freq->he_enabled);
3329 PRINTF("freq->bandwidth: %d\r\n", freq->bandwidth);
3330 #endif
3331 ret = 0;
3332
3333 chan.mode = (enum wifi_mode)freq->mode;
3334 chan.freq = freq->freq;
3335 chan.channel = freq->channel;
3336 chan.sec_channel_offset = freq->sec_channel_offset;
3337 chan.bandwidth = freq->bandwidth;
3338 chan.ht_enabled = freq->ht_enabled;
3339 chan.vht_enabled = freq->vht_enabled;
3340 chan.he_enabled = freq->he_enabled;
3341 chan.center_freq1 = freq->center_freq1;
3342 chan.center_freq2 = freq->center_freq2;
3343
3344 ret = 0; // wifi_nxp_set_chan(chan);
3345
3346 out:
3347 return ret;
3348 }
3349
wifi_nxp_hostapd_set_rts(void * if_priv,int rts_threshold)3350 int wifi_nxp_hostapd_set_rts(void *if_priv, int rts_threshold)
3351 {
3352 int ret = -1;
3353 if (!if_priv)
3354 {
3355 supp_e("%s: Invalid params\n", __func__);
3356 goto out;
3357 }
3358
3359 // ret = wifi_nxp_set_rts(rts_threshold);
3360 ret = wifi_set_uap_rts(rts_threshold);
3361
3362 out:
3363 return ret;
3364 }
3365
wifi_nxp_hostapd_set_frag(void * if_priv,int frag_threshold)3366 int wifi_nxp_hostapd_set_frag(void *if_priv, int frag_threshold)
3367 {
3368 int ret = -1;
3369 if (!if_priv)
3370 {
3371 supp_e("%s: Invalid params\n", __func__);
3372 goto out;
3373 }
3374
3375 ret = wifi_set_uap_frag(frag_threshold);
3376
3377 out:
3378 return ret;
3379 }
3380
wifi_nxp_hostapd_stop_ap(void * if_priv)3381 int wifi_nxp_hostapd_stop_ap(void *if_priv)
3382 {
3383 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
3384 int ret = -1;
3385 if (!if_priv)
3386 {
3387 supp_e("%s: Invalid params", __func__);
3388 goto out;
3389 }
3390
3391 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
3392
3393 ret = wifi_nxp_stop_ap();
3394 if (ret != 0)
3395 {
3396 supp_e("%s: Stop AP failed", __func__);
3397 goto out;
3398 }
3399 wifi_if_ctx_rtos->uap_started = false;
3400 out:
3401 return ret;
3402 }
3403
wifi_nxp_hostapd_set_acl(void * if_priv,struct hostapd_acl_params * params)3404 int wifi_nxp_hostapd_set_acl(void *if_priv, struct hostapd_acl_params *params)
3405 {
3406 // struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
3407 int ret = -1;
3408 nxp_wifi_acl_info_t *acl_params = NULL;
3409 size_t acl_sz = 0;
3410 unsigned int i;
3411
3412 if ((!if_priv) || (!params))
3413 {
3414 supp_e("%s: Invalid params", __func__);
3415 goto out;
3416 }
3417
3418 // wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
3419
3420 acl_sz = WIFI_ETH_ADDR_LEN * params->num_mac_acl;
3421
3422 acl_params = (nxp_wifi_acl_info_t *)OSA_MemoryAllocate(sizeof(nxp_wifi_acl_info_t) + acl_sz);
3423 if (!acl_params)
3424 {
3425 supp_e("%s: acl params calloc failed", __func__);
3426 goto out;
3427 }
3428
3429 acl_params->acl_policy = params->acl_policy;
3430 acl_params->num_mac_acl = params->num_mac_acl;
3431
3432 for (i = 0; i < params->num_mac_acl; i++)
3433 {
3434 memcpy(acl_params->mac_acl[i].addr, params->mac_acl[i].addr, WIFI_ETH_ADDR_LEN);
3435 }
3436
3437 ret = wifi_nxp_set_acl(acl_params);
3438 if (ret != 0)
3439 {
3440 supp_e("%s: Set ACL failed", __func__);
3441 }
3442
3443 out:
3444 if (acl_params)
3445 OSA_MemoryFree((void *)acl_params);
3446 return ret;
3447 }
3448 #endif
3449
wifi_nxp_wpa_dpp_listen(void * if_priv,bool enable)3450 int wifi_nxp_wpa_dpp_listen(void *if_priv, bool enable)
3451 {
3452 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
3453
3454 if (!if_priv)
3455 {
3456 supp_e("%s: Invalid params", __func__);
3457 goto out;
3458 }
3459
3460 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
3461
3462 return wlan_supp_dpp_listen(wifi_if_ctx_rtos->bss_type, enable);
3463 out:
3464 return -1;
3465 }
3466
wifi_nxp_wpa_get_modes(void * if_priv)3467 bool wifi_nxp_wpa_get_modes(void *if_priv)
3468 {
3469 return (!ISSUPP_NO5G(mlan_adap->fw_cap_ext));
3470 }
3471
wifi_nxp_wpa_supp_cancel_action_wait(void * if_priv)3472 void wifi_nxp_wpa_supp_cancel_action_wait(void *if_priv)
3473 {
3474 struct wifi_nxp_ctx_rtos *wifi_if_ctx_rtos = NULL;
3475
3476 if (!if_priv)
3477 {
3478 supp_e("%s: Invalid params", __func__);
3479 goto out;
3480 }
3481
3482 wifi_if_ctx_rtos = (struct wifi_nxp_ctx_rtos *)if_priv;
3483 if (wifi_if_ctx_rtos->bss_type == BSS_TYPE_STA)
3484 {
3485 (void)wifi_remain_on_channel(false, 0, 0);
3486 }
3487
3488 out:
3489 return;
3490 }
3491 #endif
3492