1 /*
2 * Driver interaction with Zephyr WLAN device drivers.
3 * Copyright (c) 2023, Nordic Semiconductor
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8 #include <zephyr/kernel.h>
9
10 #include "includes.h"
11 #include "utils/common.h"
12 #include "eloop.h"
13 #include "driver_zephyr.h"
14 #include "supp_main.h"
15 #include "common/ieee802_11_common.h"
16
17 #ifdef CONFIG_AP
18 #include "l2_packet/l2_packet.h"
19 #endif /* CONFIG_AP */
20
21 /* Zephyr drivers have a timeout of 30s wait for them to handle the cleanup */
22 /* TODO: The timeout should be retrieved from the driver to keep it generic */
23 #define SCAN_TIMEOUT 35
24 #define GET_WIPHY_TIMEOUT 10
25
26 int wpa_drv_zep_send_mlme(void *priv, const u8 *data, size_t data_len, int noack,
27 unsigned int freq, const u16 *csa_offs, size_t csa_offs_len, int no_encrypt,
28 unsigned int wait, int link_id);
29
get_dev_ops(const struct device * dev)30 const struct zep_wpa_supp_dev_ops *get_dev_ops(const struct device *dev)
31 {
32 struct net_wifi_mgmt_offload *api;
33
34 api = (struct net_wifi_mgmt_offload *)dev->api;
35
36 return api->wifi_drv_ops;
37 }
38
39 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
hostapd_event_wrapper(void * ctx,enum wpa_event_type event,union wpa_event_data * data)40 void hostapd_event_wrapper(void *ctx, enum wpa_event_type event, union wpa_event_data *data)
41 {
42 struct wpa_supplicant_event_msg msg = { 0 };
43
44 msg.hostapd = 1;
45 msg.ctx = ctx;
46 msg.event = event;
47 if (data) {
48 msg.data = os_zalloc(sizeof(*data));
49 if (!msg.data) {
50 wpa_printf(MSG_ERROR, "Failed to allocate data for event: %d", event);
51 return;
52 }
53 os_memcpy(msg.data, data, sizeof(*data));
54 if (event == EVENT_TX_STATUS) {
55 union wpa_event_data *data_tmp = msg.data;
56 const struct ieee80211_hdr *hdr;
57
58 if (data->tx_status.data) {
59 char *frame = os_zalloc(data->tx_status.data_len);
60
61 if (!frame) {
62 wpa_printf(MSG_ERROR, "%s:%d Failed to alloc %d bytes\n", __func__,
63 __LINE__, data->tx_status.data_len);
64 os_free(msg.data);
65 return;
66 }
67
68 os_memcpy(frame, data->tx_status.data, data->tx_status.data_len);
69 data_tmp->tx_status.data = frame;
70 hdr = (const struct ieee80211_hdr *) frame;
71 data_tmp->tx_status.dst = hdr->addr1;
72 }
73 } else if (event == EVENT_RX_MGMT) {
74 union wpa_event_data *data_tmp = msg.data;
75
76 if (data->rx_mgmt.frame) {
77 char *frame = os_zalloc(data->rx_mgmt.frame_len);
78
79 if (!frame) {
80 wpa_printf(MSG_ERROR, "%s:%d Failed to alloc %d bytes\n",
81 __func__, __LINE__, data->rx_mgmt.frame_len);
82 os_free(msg.data);
83 return;
84 }
85
86 os_memcpy(frame, data->rx_mgmt.frame, data->rx_mgmt.frame_len);
87 data_tmp->rx_mgmt.frame = frame;
88 }
89 }
90 }
91 zephyr_wifi_send_event(&msg);
92 }
93 #endif
94
wpa_supplicant_event_wrapper(void * ctx,enum wpa_event_type event,union wpa_event_data * data)95 void wpa_supplicant_event_wrapper(void *ctx,
96 enum wpa_event_type event,
97 union wpa_event_data *data)
98 {
99 struct wpa_supplicant_event_msg msg = { 0 };
100
101 msg.ctx = ctx;
102 msg.event = event;
103 if (data) {
104 msg.data = os_zalloc(sizeof(*data));
105 if (!msg.data) {
106 wpa_printf(MSG_ERROR, "Failed to allocated for event: %d", event);
107 return;
108 }
109 os_memcpy(msg.data, data, sizeof(*data));
110 /* Handle deep copy for some event data */
111 if (event == EVENT_AUTH) {
112 union wpa_event_data *data_tmp = msg.data;
113
114 if (data->auth.ies) {
115 char *ies = os_zalloc(data->auth.ies_len);
116
117 if (!ies) {
118 wpa_printf(MSG_ERROR,
119 "%s:%d event %u Failed to alloc ies %d bytes\n",
120 __func__, __LINE__, event, data->auth.ies_len);
121 os_free(msg.data);
122 return;
123 }
124
125 os_memcpy(ies, data->auth.ies, data->auth.ies_len);
126 data_tmp->auth.ies = ies;
127 }
128 } else if (event == EVENT_RX_MGMT) {
129 union wpa_event_data *data_tmp = msg.data;
130
131 if (data->rx_mgmt.frame) {
132 char *frame = os_zalloc(data->rx_mgmt.frame_len);
133
134 if (!frame) {
135 wpa_printf(MSG_ERROR,
136 "%s:%d event %u Failed to alloc frame %d bytes\n",
137 __func__, __LINE__, event, data->rx_mgmt.frame_len);
138 os_free(msg.data);
139 return;
140 }
141
142 os_memcpy(frame, data->rx_mgmt.frame, data->rx_mgmt.frame_len);
143 data_tmp->rx_mgmt.frame = frame;
144 }
145 } else if (event == EVENT_TX_STATUS) {
146 union wpa_event_data *data_tmp = msg.data;
147 const struct ieee80211_hdr *hdr;
148
149 if (data->tx_status.data) {
150 char *frame = os_zalloc(data->tx_status.data_len);
151
152 if (!frame) {
153 wpa_printf(MSG_ERROR,
154 "%s:%d event %u Failed to alloc frame %d bytes\n",
155 __func__, __LINE__, event, data->tx_status.data_len);
156 os_free(msg.data);
157 return;
158 }
159
160 os_memcpy(frame, data->tx_status.data, data->tx_status.data_len);
161 data_tmp->tx_status.data = frame;
162 hdr = (const struct ieee80211_hdr *) frame;
163 data_tmp->tx_status.dst = hdr->addr1;
164 }
165 } else if (event == EVENT_ASSOC) {
166 union wpa_event_data *data_tmp = msg.data;
167 char *addr = os_zalloc(ETH_ALEN);
168
169 if (!addr) {
170 wpa_printf(MSG_ERROR,
171 "%s:%d event %u Failed to alloc addr %d bytes\n",
172 __func__, __LINE__, event, ETH_ALEN);
173 os_free(msg.data);
174 return;
175 }
176
177 os_memcpy(addr, data->assoc_info.addr, ETH_ALEN);
178 data_tmp->assoc_info.addr = addr;
179
180 if (data->assoc_info.req_ies) {
181 char *req_ies = os_zalloc(data->assoc_info.req_ies_len);
182
183 if (!req_ies) {
184 wpa_printf(MSG_ERROR,
185 "%s:%d event %u Failed to alloc req_ies %d bytes\n",
186 __func__, __LINE__, event, data->assoc_info.req_ies_len);
187 os_free(msg.data);
188 os_free(addr);
189 return;
190 }
191
192 os_memcpy(req_ies, data->assoc_info.req_ies,
193 data->assoc_info.req_ies_len);
194 data_tmp->assoc_info.req_ies = req_ies;
195 }
196 if (data->assoc_info.resp_ies) {
197 char *resp_ies = os_zalloc(data->assoc_info.resp_ies_len);
198
199 if (!resp_ies) {
200 wpa_printf(MSG_ERROR,
201 "%s:%d event %u Failed to alloc resp_ies %d bytes\n",
202 __func__, __LINE__, event, data->assoc_info.resp_ies_len);
203 os_free(msg.data);
204 os_free(addr);
205 if (data_tmp->assoc_info.req_ies)
206 os_free((void *)(data_tmp->assoc_info.req_ies));
207 return;
208 }
209
210 os_memcpy(resp_ies, data->assoc_info.resp_ies,
211 data->assoc_info.resp_ies_len);
212 data_tmp->assoc_info.resp_ies = resp_ies;
213 }
214 if (data->assoc_info.resp_frame) {
215 char *resp_frame = os_zalloc(data->assoc_info.resp_frame_len);
216
217 if (!resp_frame) {
218 wpa_printf(MSG_ERROR,
219 "%s:%d event %u Failed to alloc resp_frame %d bytes\n",
220 __func__, __LINE__, event, data->assoc_info.resp_frame_len);
221 os_free(msg.data);
222 os_free(addr);
223 if (data_tmp->assoc_info.req_ies)
224 os_free((void *)(data_tmp->assoc_info.req_ies));
225 if (data_tmp->assoc_info.resp_ies)
226 os_free((void *)(data_tmp->assoc_info.resp_ies));
227 return;
228 }
229
230 os_memcpy(resp_frame, data->assoc_info.resp_frame,
231 data->assoc_info.resp_frame_len);
232 data_tmp->assoc_info.resp_frame = resp_frame;
233 }
234 } else if (event == EVENT_ASSOC_REJECT) {
235 union wpa_event_data *data_tmp = msg.data;
236 char *bssid = os_zalloc(ETH_ALEN);
237
238 if (!bssid) {
239 wpa_printf(MSG_ERROR,
240 "%s:%d event %u Failed to alloc bssid %d bytes\n",
241 __func__, __LINE__, event, ETH_ALEN);
242 os_free(msg.data);
243 return;
244 }
245
246 os_memcpy(bssid, data->assoc_reject.bssid, ETH_ALEN);
247 data_tmp->assoc_reject.bssid = bssid;
248
249 if (data->assoc_reject.resp_ies) {
250 char *resp_ies = os_zalloc(data->assoc_reject.resp_ies_len);
251
252 if (!resp_ies) {
253 wpa_printf(MSG_ERROR,
254 "%s:%d event %u Failed to alloc resp_ies %d bytes\n",
255 __func__, __LINE__, event, data->assoc_reject.resp_ies_len);
256 os_free(msg.data);
257 os_free(bssid);
258 return;
259 }
260
261 os_memcpy(resp_ies, data->assoc_reject.resp_ies,
262 data->assoc_reject.resp_ies_len);
263 data_tmp->assoc_reject.resp_ies = resp_ies;
264 }
265 } else if (event == EVENT_DEAUTH) {
266 union wpa_event_data *data_tmp = msg.data;
267 char *sa = os_zalloc(ETH_ALEN);
268
269 if (!sa) {
270 wpa_printf(MSG_ERROR,
271 "%s:%d event %u Failed to alloc sa %d bytes\n",
272 __func__, __LINE__, event, ETH_ALEN);
273 os_free(msg.data);
274 return;
275 }
276
277 os_memcpy(sa, data->deauth_info.addr, ETH_ALEN);
278 data_tmp->deauth_info.addr = sa;
279 if (data->deauth_info.ie) {
280 char *ie = os_zalloc(data->deauth_info.ie_len);
281
282 if (!ie) {
283 wpa_printf(MSG_ERROR,
284 "%s:%d event %u Failed to alloc ie %d bytes\n",
285 __func__, __LINE__, event, data->deauth_info.ie_len);
286 os_free(msg.data);
287 os_free(sa);
288 return;
289 }
290
291 os_memcpy(ie, data->deauth_info.ie, data->deauth_info.ie_len);
292 data_tmp->deauth_info.ie = ie;
293 }
294 } else if (event == EVENT_DISASSOC) {
295 union wpa_event_data *data_tmp = msg.data;
296 char *sa = os_zalloc(ETH_ALEN);
297
298 if (!sa) {
299 wpa_printf(MSG_ERROR,
300 "%s:%d event %u Failed to alloc sa %d bytes\n",
301 __func__, __LINE__, event, ETH_ALEN);
302 os_free(msg.data);
303 return;
304 }
305
306 os_memcpy(sa, data->disassoc_info.addr, ETH_ALEN);
307 data_tmp->disassoc_info.addr = sa;
308 if (data->disassoc_info.ie) {
309 char *ie = os_zalloc(data->disassoc_info.ie_len);
310
311 if (!ie) {
312 wpa_printf(MSG_ERROR,
313 "%s:%d event %u Failed to alloc ie %d bytes\n",
314 __func__, __LINE__, event, data->disassoc_info.ie_len);
315 os_free(msg.data);
316 os_free(sa);
317 return;
318 }
319
320 os_memcpy(ie, data->disassoc_info.ie, data->disassoc_info.ie_len);
321 data_tmp->disassoc_info.ie = ie;
322 }
323 } else if (event == EVENT_UNPROT_DEAUTH) {
324 union wpa_event_data *data_tmp = msg.data;
325 char *sa = os_zalloc(ETH_ALEN);
326 char *da = os_zalloc(ETH_ALEN);
327
328 if (!sa) {
329 wpa_printf(MSG_ERROR,
330 "%s:%d event %u Failed to alloc sa %d bytes\n",
331 __func__, __LINE__, event, ETH_ALEN);
332 os_free(msg.data);
333 if (da)
334 os_free(da);
335 return;
336 }
337
338 if (!da) {
339 wpa_printf(MSG_ERROR,
340 "%s:%d event %u Failed to alloc da %d bytes\n",
341 __func__, __LINE__, event, ETH_ALEN);
342 os_free(msg.data);
343 if (sa)
344 os_free(sa);
345 return;
346 }
347 os_memcpy(sa, data->unprot_deauth.sa, ETH_ALEN);
348 data_tmp->unprot_deauth.sa = sa;
349 os_memcpy(da, data->unprot_deauth.da, ETH_ALEN);
350 data_tmp->unprot_deauth.da = da;
351 } else if (event == EVENT_UNPROT_DISASSOC) {
352 union wpa_event_data *data_tmp = msg.data;
353 char *sa = os_zalloc(ETH_ALEN);
354 char *da = os_zalloc(ETH_ALEN);
355
356 if (!sa) {
357 wpa_printf(MSG_ERROR,
358 "%s:%d event %u Failed to alloc sa %d bytes\n",
359 __func__, __LINE__, event, ETH_ALEN);
360 os_free(msg.data);
361 if (da)
362 os_free(da);
363 return;
364 }
365
366 if (!da) {
367 wpa_printf(MSG_ERROR,
368 "%s:%d event %u Failed to alloc da %d bytes\n",
369 __func__, __LINE__, event, ETH_ALEN);
370 os_free(msg.data);
371 if (sa)
372 os_free(sa);
373 return;
374 }
375 os_memcpy(sa, data->unprot_disassoc.sa, ETH_ALEN);
376 data_tmp->unprot_disassoc.sa = sa;
377 os_memcpy(da, data->unprot_disassoc.da, ETH_ALEN);
378 data_tmp->unprot_disassoc.da = da;
379 }
380 }
381
382 zephyr_wifi_send_event(&msg);
383 }
384
wpa_drv_zep_event_chan_list_changed(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)385 void wpa_drv_zep_event_chan_list_changed(struct zep_drv_if_ctx *if_ctx, union wpa_event_data *event)
386 {
387 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
388 if (if_ctx->hapd)
389 hostapd_event_wrapper(if_ctx->hapd, EVENT_CHANNEL_LIST_CHANGED, event);
390 else
391 #endif
392 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
393 EVENT_CHANNEL_LIST_CHANGED,
394 event);
395 }
396
wpa_drv_zep_event_mac_changed(struct zep_drv_if_ctx * if_ctx)397 void wpa_drv_zep_event_mac_changed(struct zep_drv_if_ctx *if_ctx)
398 {
399 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
400 const struct net_linkaddr *link_addr = NULL;
401
402 if (if_ctx->hapd) {
403 link_addr = net_if_get_link_addr(net_if_get_wifi_sap());
404 os_memcpy(if_ctx->hapd->own_addr, link_addr->addr, link_addr->len);
405 }
406 else
407 #endif
408 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
409 EVENT_INTERFACE_MAC_CHANGED,
410 NULL);
411 }
412
wpa_drv_zep_abort_scan(void * priv,u64 scan_cookie)413 static int wpa_drv_zep_abort_scan(void *priv,
414 u64 scan_cookie)
415 {
416 struct zep_drv_if_ctx *if_ctx = NULL;
417 const struct zep_wpa_supp_dev_ops *dev_ops;
418 int ret = -1;
419
420 if_ctx = priv;
421
422 dev_ops = get_dev_ops(if_ctx->dev_ctx);
423 if (!dev_ops->scan_abort) {
424 wpa_printf(MSG_ERROR,
425 "%s: No op registered for scan_abort",
426 __func__);
427 goto out;
428 }
429
430 ret = dev_ops->scan_abort(if_ctx->dev_priv);
431 out:
432 return ret;
433 }
434
435
436 /**
437 * wpa_drv_zep_scan_timeout - Scan timeout to report scan completion
438 * @eloop_ctx: Driver private data
439 * @timeout_ctx: ctx argument given to wpa_drv_zep_init()
440 *
441 * This function can be used as registered timeout when starting a scan to
442 * generate a scan completed event if the driver does not report this.
443 */
wpa_drv_zep_scan_timeout(void * eloop_ctx,void * timeout_ctx)444 void wpa_drv_zep_scan_timeout(void *eloop_ctx, void *timeout_ctx)
445 {
446 struct zep_drv_if_ctx *if_ctx = NULL;
447
448 if_ctx = eloop_ctx;
449
450 wpa_printf(MSG_ERROR,
451 "%s: Scan timeout - try to abort it",
452 __func__);
453
454 if (wpa_drv_zep_abort_scan(if_ctx, 0) == 0) {
455 return;
456 }
457 }
458
459
wpa_drv_zep_event_proc_scan_start(struct zep_drv_if_ctx * if_ctx)460 void wpa_drv_zep_event_proc_scan_start(struct zep_drv_if_ctx *if_ctx)
461 {
462 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
463 EVENT_SCAN_STARTED,
464 NULL);
465 }
466
467
wpa_drv_zep_event_proc_scan_done(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)468 void wpa_drv_zep_event_proc_scan_done(struct zep_drv_if_ctx *if_ctx,
469 union wpa_event_data *event)
470 {
471 eloop_cancel_timeout(wpa_drv_zep_scan_timeout,
472 if_ctx,
473 if_ctx->supp_if_ctx);
474
475 if_ctx->scan_res2_get_in_prog = false;
476 k_sem_give(&if_ctx->drv_resp_sem);
477
478 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
479 EVENT_SCAN_RESULTS,
480 event);
481 }
482
483
wpa_drv_zep_event_proc_scan_res(struct zep_drv_if_ctx * if_ctx,struct wpa_scan_res * r,bool more_res)484 void wpa_drv_zep_event_proc_scan_res(struct zep_drv_if_ctx *if_ctx,
485 struct wpa_scan_res *r,
486 bool more_res)
487 {
488 struct wpa_scan_res **tmp = NULL;
489 size_t scan_res_len = sizeof(struct wpa_scan_res) + r->ie_len + r->beacon_ie_len;
490
491 if (!if_ctx->scan_res2)
492 return;
493
494 tmp = os_realloc_array(if_ctx->scan_res2->res,
495 if_ctx->scan_res2->num + 1,
496 sizeof(struct wpa_scan_res *));
497
498 if (!tmp) {
499 wpa_printf(MSG_ERROR, "%s: Failed to realloc scan result array", __func__);
500 goto err;
501 }
502
503 struct wpa_scan_res *sr = os_zalloc(scan_res_len);
504 if (!sr) {
505 wpa_printf(MSG_ERROR, "%s: Failed to alloc scan results(%d bytes)", __func__, scan_res_len);
506 if_ctx->scan_res2->res = tmp;
507 goto err;
508 }
509
510 os_memcpy(sr, r, scan_res_len);
511
512 tmp[if_ctx->scan_res2->num++] = sr;
513
514 if_ctx->scan_res2->res = tmp;
515
516 err:
517 if (!more_res) {
518 if_ctx->scan_res2_get_in_prog = false;
519 k_sem_give(&if_ctx->drv_resp_sem);
520 }
521 }
522
523
wpa_drv_zep_event_proc_auth_resp(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)524 void wpa_drv_zep_event_proc_auth_resp(struct zep_drv_if_ctx *if_ctx,
525 union wpa_event_data *event)
526 {
527 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
528 EVENT_AUTH,
529 event);
530 }
531
532
wpa_drv_zep_event_proc_assoc_resp(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event,unsigned int status)533 void wpa_drv_zep_event_proc_assoc_resp(struct zep_drv_if_ctx *if_ctx,
534 union wpa_event_data *event,
535 unsigned int status)
536 {
537 if (status != WLAN_STATUS_SUCCESS) {
538 if (if_ctx->ft_roaming) {
539 if_ctx->ft_roaming = false;
540 }
541 if (if_ctx->roaming) {
542 if_ctx->roaming = false;
543 }
544 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
545 EVENT_ASSOC_REJECT,
546 event);
547 } else {
548 if_ctx->associated = true;
549
550 os_memcpy(if_ctx->bssid,
551 event->assoc_info.addr,
552 ETH_ALEN);
553
554 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
555 EVENT_ASSOC,
556 event);
557 }
558 }
559
560
wpa_drv_zep_event_proc_deauth(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event,const struct ieee80211_mgmt * mgmt)561 void wpa_drv_zep_event_proc_deauth(struct zep_drv_if_ctx *if_ctx,
562 union wpa_event_data *event, const struct ieee80211_mgmt *mgmt)
563 {
564 const u8 *bssid = NULL;
565
566 bssid = mgmt->bssid;
567
568 if ((if_ctx->capa.flags & WPA_DRIVER_FLAGS_SME) &&
569 !if_ctx->associated &&
570 os_memcmp(bssid, if_ctx->auth_bssid, ETH_ALEN) != 0 &&
571 os_memcmp(bssid, if_ctx->auth_attempt_bssid, ETH_ALEN) != 0 &&
572 os_memcmp(bssid, if_ctx->prev_bssid, ETH_ALEN) == 0)
573 {
574 /*
575 * Avoid issues with some roaming cases where
576 * disconnection event for the old AP may show up after
577 * we have started connection with the new AP.
578 * In case of locally generated event clear
579 * ignore_next_local_deauth as well, to avoid next local
580 * deauth event be wrongly ignored.
581 */
582 wpa_printf(MSG_DEBUG,
583 "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
584 MAC2STR(bssid),
585 MAC2STR(if_ctx->auth_attempt_bssid));
586 return;
587 }
588 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
589 EVENT_DEAUTH,
590 event);
591 }
592
593
wpa_drv_zep_event_proc_disassoc(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)594 void wpa_drv_zep_event_proc_disassoc(struct zep_drv_if_ctx *if_ctx,
595 union wpa_event_data *event)
596 {
597 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
598 EVENT_DISASSOC,
599 event);
600 }
601
wpa_drv_zep_event_mgmt_tx_status(struct zep_drv_if_ctx * if_ctx,const u8 * frame,size_t len,bool ack)602 static void wpa_drv_zep_event_mgmt_tx_status(struct zep_drv_if_ctx *if_ctx,
603 const u8 *frame, size_t len, bool ack)
604 {
605 union wpa_event_data event;
606 const struct ieee80211_hdr *hdr;
607 u16 fc;
608
609 wpa_printf(MSG_DEBUG, "wpa_supp: Frame TX status event");
610
611 hdr = (const struct ieee80211_hdr *) frame;
612 fc = le_to_host16(hdr->frame_control);
613
614 os_memset(&event, 0, sizeof(event));
615 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
616 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
617 event.tx_status.dst = hdr->addr1;
618 event.tx_status.data = frame;
619 event.tx_status.data_len = len;
620 event.tx_status.ack = ack;
621
622 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
623 if (if_ctx->hapd)
624 hostapd_event_wrapper(if_ctx->hapd, EVENT_TX_STATUS, &event);
625 else
626 #endif
627 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
628 EVENT_TX_STATUS,
629 &event);
630 }
631
wpa_drv_zep_event_proc_unprot_deauth(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)632 static void wpa_drv_zep_event_proc_unprot_deauth(struct zep_drv_if_ctx *if_ctx,
633 union wpa_event_data *event)
634 {
635 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
636 EVENT_UNPROT_DEAUTH,
637 event);
638 }
639
wpa_drv_zep_event_proc_unprot_disassoc(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)640 static void wpa_drv_zep_event_proc_unprot_disassoc(struct zep_drv_if_ctx *if_ctx,
641 union wpa_event_data *event)
642 {
643 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
644 EVENT_UNPROT_DISASSOC,
645 event);
646 }
647
648 struct phy_info_arg {
649 u16 *num_modes;
650 struct hostapd_hw_modes *modes;
651 int last_mode, last_chan_idx;
652 int failed;
653 u8 dfs_domain;
654 };
655
phy_info_freq_cfg(struct hostapd_hw_modes * mode,struct hostapd_channel_data * chan,struct wpa_supp_event_channel * chnl_info)656 static void phy_info_freq_cfg(struct hostapd_hw_modes *mode,
657 struct hostapd_channel_data *chan,
658 struct wpa_supp_event_channel *chnl_info)
659 {
660 u8 channel = 0;
661
662 chan->freq = chnl_info->center_frequency;
663 chan->flag = 0;
664 chan->allowed_bw = ~0;
665 chan->dfs_cac_ms = 0;
666 chan->max_tx_power = chnl_info->wpa_supp_max_power;
667
668 if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES) {
669 chan->chan = channel;
670 }
671
672 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_DISABLED)
673 chan->flag |= HOSTAPD_CHAN_DISABLED;
674 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_IR)
675 chan->flag |= HOSTAPD_CHAN_NO_IR;
676 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_RADAR)
677 chan->flag |= HOSTAPD_CHAN_RADAR;
678 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_INDOOR_ONLY)
679 chan->flag |= HOSTAPD_CHAN_INDOOR_ONLY;
680 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_GO_CONCURRENT)
681 chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT;
682 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_10MHZ)
683 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_10;
684 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_20MHZ)
685 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_20;
686 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_HT40_PLUS)
687 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40P;
688 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_HT40_MINUS)
689 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40M;
690 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_80MHZ)
691 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_80;
692 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_160MHZ)
693 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160;
694
695 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_DFS_CAC_TIME_VALID) {
696 chan->dfs_cac_ms = (chnl_info->wpa_supp_time);
697 }
698
699 /* Other elements are not present */
700 chan->wmm_rules_valid = 0;
701 chan->wmm_rules_valid = 0;
702 }
703
704
phy_info_freqs_cfg(struct phy_info_arg * phy_info,struct hostapd_hw_modes * mode,struct wpa_supp_event_supported_band * band_info)705 static int phy_info_freqs_cfg(struct phy_info_arg *phy_info,
706 struct hostapd_hw_modes *mode,
707 struct wpa_supp_event_supported_band *band_info)
708 {
709 int new_channels = 0;
710 struct hostapd_channel_data *channel = NULL;
711 int idx;
712
713 if (!phy_info || !mode || !band_info)
714 return -1;
715
716 new_channels = band_info->wpa_supp_n_channels;
717 if (!new_channels)
718 return 0;
719
720 channel = os_realloc_array(mode->channels,
721 mode->num_channels + new_channels,
722 sizeof(struct hostapd_channel_data));
723 if (!channel)
724 return -1;
725
726 os_memset(channel, 0, (mode->num_channels + new_channels) * sizeof(*channel));
727
728 mode->channels = channel;
729 mode->num_channels += new_channels;
730
731 idx = phy_info->last_chan_idx;
732
733 for (int i = 0; i < new_channels; i++) {
734 phy_info_freq_cfg(mode, &mode->channels[idx], &band_info->channels[i]);
735 idx++;
736 }
737
738 phy_info->last_chan_idx = idx;
739
740 return 0;
741 }
742
phy_info_rates_cfg(struct hostapd_hw_modes * mode,struct wpa_supp_event_supported_band * band_info)743 static int phy_info_rates_cfg(struct hostapd_hw_modes *mode,
744 struct wpa_supp_event_supported_band *band_info)
745 {
746 int idx;
747
748 if (!mode || !band_info)
749 return -1;
750
751 mode->num_rates = band_info->wpa_supp_n_bitrates;
752 if (!mode->num_rates)
753 return 0;
754
755 mode->rates = os_calloc(mode->num_rates, sizeof(int));
756 if (!mode->rates)
757 return -1;
758
759 idx = 0;
760
761 for (int i = 0; i < mode->num_rates; i++) {
762 if (!band_info->bitrates[i].wpa_supp_bitrate)
763 continue;
764 mode->rates[idx] = band_info->bitrates[i].wpa_supp_bitrate;
765 idx++;
766 }
767
768 return 0;
769 }
770
771
772
phy_info_ht_capa_cfg(struct hostapd_hw_modes * mode,u16 capa,u8 ampdu_factor,u8 ampdu_density,struct wpa_supp_event_mcs_info * mcs_set)773 static void phy_info_ht_capa_cfg(struct hostapd_hw_modes *mode, u16 capa,
774 u8 ampdu_factor,
775 u8 ampdu_density,
776 struct wpa_supp_event_mcs_info *mcs_set)
777 {
778 if (capa)
779 mode->ht_capab = (capa);
780
781 if (ampdu_factor)
782 mode->a_mpdu_params |= (ampdu_factor) & WPA_SUPP_AMPDU_FACTOR_MASK;
783
784 if (ampdu_density)
785 mode->a_mpdu_params |= (ampdu_density) << WPA_SUPP_AMPDU_DENSITY_SHIFT;
786
787 if (mcs_set) {
788 os_memcpy(mode->mcs_set, mcs_set, sizeof(*mcs_set));
789 }
790
791 }
792
phy_info_vht_capa_cfg(struct hostapd_hw_modes * mode,unsigned int capa,struct wpa_supp_event_vht_mcs_info * vht_mcs_set)793 static void phy_info_vht_capa_cfg(struct hostapd_hw_modes *mode,
794 unsigned int capa,
795 struct wpa_supp_event_vht_mcs_info *vht_mcs_set)
796 {
797 if (capa)
798 mode->vht_capab = (capa);
799
800 if (vht_mcs_set) {
801 os_memcpy(mode->vht_mcs_set, vht_mcs_set, 8);
802 }
803 }
804
phy_info_he_capa_cfg(struct hostapd_hw_modes * mode,struct wpa_supp_event_sta_he_cap * he)805 static void phy_info_he_capa_cfg(struct hostapd_hw_modes *mode,
806 struct wpa_supp_event_sta_he_cap *he)
807 {
808 mode->he_capab[IEEE80211_MODE_AP].he_supported = he->wpa_supp_he_supported;
809 memcpy(mode->he_capab[IEEE80211_MODE_AP].phy_cap, he->phy_cap, HE_MAX_PHY_CAPAB_SIZE);
810 memcpy(mode->he_capab[IEEE80211_MODE_AP].mac_cap, he->mac_cap, HE_MAX_MAC_CAPAB_SIZE);
811 memcpy(mode->he_capab[IEEE80211_MODE_AP].mcs, he->mcs, HE_MAX_MCS_CAPAB_SIZE);
812 memcpy(mode->he_capab[IEEE80211_MODE_AP].ppet, he->ppet, HE_MAX_PPET_CAPAB_SIZE);
813 mode->he_capab[IEEE80211_MODE_AP].he_6ghz_capa = he->he_6ghz_capa;
814 }
815
phy_info_band_cfg(struct phy_info_arg * phy_info,struct wpa_supp_event_supported_band * band_info)816 static int phy_info_band_cfg(struct phy_info_arg *phy_info,
817 struct wpa_supp_event_supported_band *band_info)
818 {
819 struct hostapd_hw_modes *mode;
820 int ret;
821
822 if (phy_info->last_mode != band_info->band) {
823 mode = os_realloc_array(phy_info->modes,
824 *phy_info->num_modes + 1,
825 sizeof(*mode));
826 if (!mode) {
827 phy_info->failed = 1;
828 return -1;
829 }
830
831 phy_info->modes = mode;
832
833 mode = &phy_info->modes[*(phy_info->num_modes)];
834
835 os_memset(mode, 0, sizeof(*mode));
836
837 mode->mode = NUM_HOSTAPD_MODES;
838 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
839 HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
840
841 /*
842 * Unsupported VHT MCS stream is defined as value 3, so the VHT
843 * MCS RX/TX map must be initialized with 0xffff to mark all 8
844 * possible streams as unsupported. This will be overridden if
845 * driver advertises VHT support.
846 */
847 mode->vht_mcs_set[0] = 0xff;
848 mode->vht_mcs_set[1] = 0xff;
849 mode->vht_mcs_set[4] = 0xff;
850 mode->vht_mcs_set[5] = 0xff;
851
852 *(phy_info->num_modes) += 1;
853
854 phy_info->last_mode = band_info->band;
855 phy_info->last_chan_idx = 0;
856 }
857 else
858 mode = &phy_info->modes[*(phy_info->num_modes) - 1];
859
860 phy_info_ht_capa_cfg(mode, band_info->ht_cap.wpa_supp_cap,
861 band_info->ht_cap.wpa_supp_ampdu_factor,
862 band_info->ht_cap.wpa_supp_ampdu_density,
863 &band_info->ht_cap.mcs);
864
865 phy_info_vht_capa_cfg(mode, band_info->vht_cap.wpa_supp_cap,
866 &band_info->vht_cap.vht_mcs);
867
868 phy_info_he_capa_cfg(mode, &band_info->he_cap);
869
870 ret = phy_info_freqs_cfg(phy_info, mode, band_info);
871
872 if (ret == 0)
873 ret = phy_info_rates_cfg(mode, band_info);
874
875 if (ret != 0) {
876 phy_info->failed = 1;
877 return ret;
878 }
879
880 return 0;
881 }
882
wpa_drv_zep_event_get_wiphy(struct zep_drv_if_ctx * if_ctx,void * band_info)883 static void wpa_drv_zep_event_get_wiphy(struct zep_drv_if_ctx *if_ctx, void *band_info)
884 {
885 if (!band_info) {
886 /* Done with all bands */
887 k_sem_give(&if_ctx->drv_resp_sem);
888 return;
889 }
890
891 phy_info_band_cfg(if_ctx->phy_info_arg, band_info);
892 }
893
wpa_drv_register_frame(struct zep_drv_if_ctx * if_ctx,u16 type,const u8 * match,size_t match_len,bool multicast)894 static int wpa_drv_register_frame(struct zep_drv_if_ctx *if_ctx,
895 u16 type, const u8 *match, size_t match_len,
896 bool multicast)
897 {
898 const struct zep_wpa_supp_dev_ops *dev_ops;
899
900 dev_ops = get_dev_ops(if_ctx->dev_ctx);
901 if (!dev_ops->register_frame)
902 return -1;
903
904 return dev_ops->register_frame(if_ctx->dev_priv, type, match, match_len, false);
905 }
906
wpa_drv_register_action_frame(struct zep_drv_if_ctx * if_ctx,const u8 * match,size_t match_len)907 static int wpa_drv_register_action_frame(struct zep_drv_if_ctx *if_ctx,
908 const u8 *match, size_t match_len)
909 {
910 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
911
912 return wpa_drv_register_frame(if_ctx, type, match, match_len, false);
913 }
914
wpa_drv_mgmt_subscribe_non_ap(struct zep_drv_if_ctx * if_ctx)915 static int wpa_drv_mgmt_subscribe_non_ap(struct zep_drv_if_ctx *if_ctx)
916 {
917 int ret = 0;
918
919 /* WNM - BSS Transition Management Request */
920 if (wpa_drv_register_action_frame(if_ctx, (u8 *)"\x0a\x07", 2) < 0)
921 ret = -1;
922
923 /* Radio Measurement - Neighbor Report Response */
924 if (wpa_drv_register_action_frame(if_ctx, (u8 *)"\x05\x05", 2) < 0)
925 ret = -1;
926
927 /* Radio Measurement - Radio Measurement Request */
928 if (wpa_drv_register_action_frame(if_ctx, (u8 *)"\x05\x00", 2) < 0)
929 ret = -1;
930
931 return ret;
932 }
933
wpa_drv_zep_event_mgmt_rx(struct zep_drv_if_ctx * if_ctx,char * frame,int frame_len,int frequency,int rx_signal_dbm)934 static void wpa_drv_zep_event_mgmt_rx(struct zep_drv_if_ctx *if_ctx,
935 char *frame, int frame_len,
936 int frequency, int rx_signal_dbm)
937 {
938 const struct ieee80211_mgmt *mgmt;
939
940 union wpa_event_data event;
941 u16 fc, stype;
942 int rx_freq = 0;
943
944 wpa_printf(MSG_MSGDUMP, "wpa_supp: Frame event");
945 mgmt = (const struct ieee80211_mgmt *)frame;
946
947 if (frame_len < 24) {
948 wpa_printf(MSG_DEBUG, "wpa_supp: Too short management frame");
949 return;
950 }
951
952 fc = le_to_host16(mgmt->frame_control);
953 stype = WLAN_FC_GET_STYPE(fc);
954
955 os_memset(&event, 0, sizeof(event));
956
957 if (frequency) {
958 event.rx_mgmt.freq = frequency;
959 rx_freq = event.rx_mgmt.freq;
960 }
961
962 event.rx_mgmt.frame = frame;
963 event.rx_mgmt.frame_len = frame_len;
964 event.rx_mgmt.ssi_signal = rx_signal_dbm;
965
966 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
967 if (if_ctx->hapd)
968 hostapd_event_wrapper(if_ctx->hapd, EVENT_RX_MGMT, &event);
969 else
970 #endif
971 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx, EVENT_RX_MGMT, &event);
972 }
973
wpa_drv_zep_event_ecsa_complete(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)974 static void wpa_drv_zep_event_ecsa_complete(struct zep_drv_if_ctx *if_ctx, union wpa_event_data *event)
975 {
976 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
977 if (if_ctx->hapd)
978 hostapd_event_wrapper(if_ctx->hapd, EVENT_CH_SWITCH, event);
979 else
980 #endif
981 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx, EVENT_CH_SWITCH, event);
982 }
983
984 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
wpa_drv_zep_event_dfs_cac_started(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)985 static void wpa_drv_zep_event_dfs_cac_started(struct zep_drv_if_ctx *if_ctx, union wpa_event_data *event)
986 {
987 if (if_ctx->hapd)
988 hostapd_event_wrapper(if_ctx->hapd, EVENT_DFS_CAC_STARTED, event);
989 else
990 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx, EVENT_DFS_CAC_STARTED, event);
991 }
992
wpa_drv_zep_event_dfs_cac_finished(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)993 static void wpa_drv_zep_event_dfs_cac_finished(struct zep_drv_if_ctx *if_ctx, union wpa_event_data *event)
994 {
995 if (if_ctx->hapd)
996 hostapd_event_wrapper(if_ctx->hapd, EVENT_DFS_CAC_FINISHED, event);
997 else
998 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx, EVENT_DFS_CAC_FINISHED, event);
999 }
1000 #endif
1001
wpa_drv_zep_event_signal_change(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)1002 static void wpa_drv_zep_event_signal_change(struct zep_drv_if_ctx *if_ctx,
1003 union wpa_event_data *event)
1004 {
1005 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx, EVENT_SIGNAL_CHANGE, event);
1006 }
1007
1008 static struct hostapd_hw_modes *
wpa_driver_wpa_supp_postprocess_modes(struct hostapd_hw_modes * modes,u16 * num_modes)1009 wpa_driver_wpa_supp_postprocess_modes(struct hostapd_hw_modes *modes,
1010 u16 *num_modes)
1011 {
1012 u16 m;
1013 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
1014 int i, mode11g_idx = -1;
1015
1016 /* heuristic to set up modes */
1017 for (m = 0; m < *num_modes; m++) {
1018 if (!modes[m].num_channels)
1019 continue;
1020 if (modes[m].channels[0].freq < 4000) {
1021 modes[m].mode = HOSTAPD_MODE_IEEE80211B;
1022 for (i = 0; i < modes[m].num_rates; i++) {
1023 if (modes[m].rates[i] > 200) {
1024 modes[m].mode = HOSTAPD_MODE_IEEE80211G;
1025 break;
1026 }
1027 }
1028 } else if (modes[m].channels[0].freq > 50000)
1029 modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
1030 else
1031 modes[m].mode = HOSTAPD_MODE_IEEE80211A;
1032 }
1033
1034 /* If only 802.11g mode is included, use it to construct matching
1035 * 802.11b mode data. */
1036
1037 for (m = 0; m < *num_modes; m++) {
1038 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
1039 return modes; /* 802.11b already included */
1040 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
1041 mode11g_idx = m;
1042 }
1043
1044 if (mode11g_idx < 0)
1045 return modes; /* 2.4 GHz band not supported at all */
1046
1047 nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
1048 if (nmodes == NULL)
1049 return modes; /* Could not add 802.11b mode */
1050
1051 mode = &nmodes[*num_modes];
1052 os_memset(mode, 0, sizeof(*mode));
1053 (*num_modes)++;
1054 modes = nmodes;
1055
1056 mode->mode = HOSTAPD_MODE_IEEE80211B;
1057 mode11g = &modes[mode11g_idx];
1058 mode->num_channels = mode11g->num_channels;
1059 mode->channels = os_memdup(mode11g->channels,
1060 mode11g->num_channels *
1061 sizeof(struct hostapd_channel_data));
1062 if (mode->channels == NULL) {
1063 (*num_modes)--;
1064 return modes; /* Could not add 802.11b mode */
1065 }
1066
1067 mode->num_rates = 0;
1068 mode->rates = os_malloc(4 * sizeof(int));
1069 if (mode->rates == NULL) {
1070 os_free(mode->channels);
1071 (*num_modes)--;
1072 return modes; /* Could not add 802.11b mode */
1073 }
1074
1075 for (i = 0; i < mode11g->num_rates; i++) {
1076 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
1077 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
1078 continue;
1079 mode->rates[mode->num_rates] = mode11g->rates[i];
1080 mode->num_rates++;
1081 if (mode->num_rates == 4)
1082 break;
1083 }
1084
1085 if (mode->num_rates == 0) {
1086 os_free(mode->channels);
1087 os_free(mode->rates);
1088 (*num_modes)--;
1089 return modes; /* No 802.11b rates */
1090 }
1091
1092 wpa_printf(MSG_DEBUG, "wpa_supp: Added 802.11b mode based on 802.11g "
1093 "information");
1094
1095 return modes;
1096 }
1097
wpa_drv_zep_get_hw_feature_data(void * priv,u16 * num_modes,u16 * flags,u8 * dfs_domain)1098 struct hostapd_hw_modes *wpa_drv_zep_get_hw_feature_data(void *priv,
1099 u16 *num_modes,
1100 u16 *flags, u8 *dfs_domain)
1101 {
1102 struct zep_drv_if_ctx *if_ctx = NULL;
1103 const struct zep_wpa_supp_dev_ops *dev_ops;
1104 struct hostapd_hw_modes *modes = NULL;
1105 int ret = -1;
1106
1107 if_ctx = priv;
1108
1109 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1110 if (!dev_ops) {
1111 wpa_printf(MSG_ERROR, "%s:Failed to get dev_ops handle", __func__);
1112 goto out;
1113 }
1114
1115 if (!dev_ops->get_wiphy) {
1116 wpa_printf(MSG_ERROR, "%s: No op registered for get_wiphy", __func__);
1117 goto out;
1118 }
1119
1120 struct phy_info_arg result = {
1121 .num_modes = num_modes,
1122 .modes = NULL,
1123 .last_mode = -1,
1124 .failed = 0,
1125 .dfs_domain = 0,
1126 };
1127
1128 *num_modes = 0;
1129 *flags = 0;
1130 *dfs_domain = 0;
1131
1132 if_ctx->phy_info_arg = &result;
1133
1134 k_sem_reset(&if_ctx->drv_resp_sem);
1135
1136 ret = dev_ops->get_wiphy(if_ctx->dev_priv);
1137 if (ret < 0) {
1138 return NULL;
1139 }
1140
1141 k_sem_take(&if_ctx->drv_resp_sem, K_SECONDS(GET_WIPHY_TIMEOUT));
1142
1143 if (!result.modes) {
1144 return NULL;
1145 }
1146
1147 *dfs_domain = result.dfs_domain;
1148
1149 modes = wpa_driver_wpa_supp_postprocess_modes(result.modes,
1150 num_modes);
1151
1152 out:
1153 return modes;
1154 }
1155
wpa_drv_zep_global_init(void * ctx)1156 static void *wpa_drv_zep_global_init(void *ctx)
1157 {
1158 struct zep_drv_ctx *drv_ctx = NULL;
1159
1160 drv_ctx = os_zalloc(sizeof(*drv_ctx));
1161 if (!drv_ctx) {
1162 return NULL;
1163 }
1164
1165 drv_ctx->supp_ctx = ctx;
1166
1167 return drv_ctx;
1168 }
1169
1170
wpa_drv_zep_global_deinit(void * priv)1171 static void wpa_drv_zep_global_deinit(void *priv)
1172 {
1173 struct zep_drv_ctx *drv_ctx = priv;
1174
1175 if (!drv_ctx) {
1176 return;
1177 }
1178
1179 os_free(drv_ctx);
1180 }
1181
1182
1183 /**
1184 * wpa_driver_zep_init - Initialize Zephyr driver interface
1185 * @ctx: Context to be used when calling wpa_supplicant functions,
1186 * e.g., wpa_supplicant_event_wrapper()
1187 * @ifname: Interface name, e.g., wlan0
1188 * @global_priv: private driver global data from global_init()
1189 *
1190 * Returns: Pointer to private data, %NULL on failure
1191 */
wpa_drv_zep_init(void * ctx,const char * ifname,void * global_priv)1192 static void *wpa_drv_zep_init(void *ctx,
1193 const char *ifname,
1194 void *global_priv)
1195 {
1196 struct zep_drv_if_ctx *if_ctx = NULL;
1197 const struct zep_wpa_supp_dev_ops *dev_ops;
1198 struct zep_wpa_supp_dev_callbk_fns callbk_fns;
1199 const struct device *device;
1200 struct net_if *iface;
1201
1202 iface = net_if_get_by_index(net_if_get_by_name(ifname));
1203
1204 device = net_if_get_device(iface);
1205 if (!device) {
1206 wpa_printf(MSG_ERROR, "%s: Interface %s not found", __func__, ifname);
1207 goto out;
1208 }
1209
1210 if_ctx = os_zalloc(sizeof(*if_ctx));
1211 if (if_ctx == NULL) {
1212 goto out;
1213 }
1214
1215 if_ctx->supp_if_ctx = ctx;
1216 if_ctx->iface = iface;
1217 if_ctx->dev_ctx = device;
1218 if_ctx->drv_ctx = global_priv;
1219
1220 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1221 if ((!dev_ops) || (!dev_ops->init)) {
1222 wpa_printf(MSG_ERROR,
1223 "%s: No op registered for init",
1224 __func__);
1225 os_free(if_ctx);
1226 if_ctx = NULL;
1227 goto out;
1228 }
1229
1230 os_memset(&callbk_fns, 0, sizeof(callbk_fns));
1231
1232 callbk_fns.scan_start = wpa_drv_zep_event_proc_scan_start;
1233 callbk_fns.scan_done = wpa_drv_zep_event_proc_scan_done;
1234 callbk_fns.scan_res = wpa_drv_zep_event_proc_scan_res;
1235 callbk_fns.auth_resp = wpa_drv_zep_event_proc_auth_resp;
1236 callbk_fns.assoc_resp = wpa_drv_zep_event_proc_assoc_resp;
1237 callbk_fns.deauth = wpa_drv_zep_event_proc_deauth;
1238 callbk_fns.disassoc = wpa_drv_zep_event_proc_disassoc;
1239 callbk_fns.mgmt_tx_status = wpa_drv_zep_event_mgmt_tx_status;
1240 callbk_fns.unprot_deauth = wpa_drv_zep_event_proc_unprot_deauth;
1241 callbk_fns.unprot_disassoc = wpa_drv_zep_event_proc_unprot_disassoc;
1242 callbk_fns.get_wiphy_res = wpa_drv_zep_event_get_wiphy;
1243 callbk_fns.mgmt_rx = wpa_drv_zep_event_mgmt_rx;
1244 callbk_fns.chan_list_changed = wpa_drv_zep_event_chan_list_changed;
1245 callbk_fns.mac_changed = wpa_drv_zep_event_mac_changed;
1246 callbk_fns.ecsa_complete = wpa_drv_zep_event_ecsa_complete;
1247 callbk_fns.signal_change = wpa_drv_zep_event_signal_change;
1248
1249 if_ctx->dev_priv = dev_ops->init(if_ctx,
1250 ifname,
1251 &callbk_fns);
1252 if (!if_ctx->dev_priv) {
1253 wpa_printf(MSG_ERROR,
1254 "%s: Failed to initialize the interface",
1255 __func__);
1256 os_free(if_ctx);
1257 if_ctx = NULL;
1258 goto out;
1259 }
1260
1261 k_sem_init(&if_ctx->drv_resp_sem, 0, 1);
1262
1263 wpa_drv_mgmt_subscribe_non_ap(if_ctx);
1264
1265 out:
1266 return if_ctx;
1267 }
1268
1269
wpa_drv_zep_deinit(void * priv)1270 static void wpa_drv_zep_deinit(void *priv)
1271 {
1272 struct zep_drv_if_ctx *if_ctx = NULL;
1273 const struct zep_wpa_supp_dev_ops *dev_ops;
1274
1275 if_ctx = priv;
1276
1277 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1278 if (!dev_ops->deinit) {
1279 wpa_printf(MSG_ERROR, "%s: No op registered for deinit", __func__);
1280 return;
1281 }
1282
1283 dev_ops->deinit(if_ctx->dev_priv);
1284
1285 os_free(if_ctx);
1286 }
1287
1288 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
wpa_drv_zep_event_acs_channel_selected(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)1289 static void wpa_drv_zep_event_acs_channel_selected(struct zep_drv_if_ctx *if_ctx, union wpa_event_data *event)
1290 {
1291 if (if_ctx->hapd)
1292 hostapd_event_wrapper(if_ctx->hapd, EVENT_ACS_CHANNEL_SELECTED, event);
1293 else
1294 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx, EVENT_ACS_CHANNEL_SELECTED, event);
1295 }
1296
wpa_drv_zep_hapd_init(struct hostapd_data * hapd,struct wpa_init_params * params)1297 static void *wpa_drv_zep_hapd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
1298 {
1299 struct zep_drv_if_ctx *if_ctx = NULL;
1300 struct net_if *iface = NULL;
1301 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1302 const struct device *device = NULL;
1303 const struct net_linkaddr *link_addr = NULL;
1304 struct zep_hostapd_dev_callbk_fns callbk_fns;
1305
1306 iface = net_if_get_by_index(net_if_get_by_name(params->ifname));
1307 if(iface != net_if_get_wifi_sap()) {
1308 wpa_printf(MSG_ERROR, "%s: Interface %s not found", __func__, params->ifname);
1309 goto out;
1310 }
1311
1312 device = net_if_get_device(iface);
1313 if (!device) {
1314 wpa_printf(MSG_ERROR, "%s: Device not found for %s", __func__, params->ifname);
1315 goto out;
1316 }
1317
1318 if_ctx = os_zalloc(sizeof(*if_ctx));
1319 if (if_ctx == NULL) {
1320 goto out;
1321 }
1322
1323 if_ctx->hapd = hapd;
1324 if_ctx->is_ap = 1;
1325
1326 if_ctx->dev_ctx = device;
1327 if_ctx->drv_ctx = params->global_priv;
1328 link_addr = net_if_get_link_addr(net_if_get_wifi_sap());
1329 os_memcpy(params->own_addr, link_addr->addr, link_addr->len);
1330
1331 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1332 if (!dev_ops->hapd_init) {
1333 wpa_printf(MSG_ERROR, "%s: No op registered for hapd init", __func__);
1334 os_free(if_ctx);
1335 if_ctx = NULL;
1336 goto out;
1337 }
1338
1339 os_memset(&callbk_fns, 0, sizeof(callbk_fns));
1340
1341 callbk_fns.get_wiphy_res = wpa_drv_zep_event_get_wiphy;
1342 callbk_fns.acs_channel_sel = wpa_drv_zep_event_acs_channel_selected;
1343 callbk_fns.mgmt_rx = wpa_drv_zep_event_mgmt_rx;
1344 callbk_fns.mgmt_tx_status = wpa_drv_zep_event_mgmt_tx_status;
1345 callbk_fns.mac_changed = wpa_drv_zep_event_mac_changed;
1346 callbk_fns.chan_list_changed = wpa_drv_zep_event_chan_list_changed;
1347 callbk_fns.ecsa_complete = wpa_drv_zep_event_ecsa_complete;
1348 callbk_fns.dfs_cac_started = wpa_drv_zep_event_dfs_cac_started;
1349 callbk_fns.dfs_cac_finished = wpa_drv_zep_event_dfs_cac_finished;
1350
1351 if_ctx->dev_priv = dev_ops->hapd_init(if_ctx, params->ifname, &callbk_fns);
1352 if (!if_ctx->dev_priv) {
1353 wpa_printf(MSG_ERROR, "%s: Failed to initialize the interface", __func__);
1354 os_free(if_ctx);
1355 if_ctx = NULL;
1356 goto out;
1357 }
1358
1359 k_sem_init(&if_ctx->drv_resp_sem, 0, 1);
1360 out:
1361 return if_ctx;
1362 }
1363
wpa_drv_zep_hapd_deinit(void * priv)1364 static void wpa_drv_zep_hapd_deinit(void *priv)
1365 {
1366 struct zep_drv_if_ctx *if_ctx = NULL;
1367 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1368
1369 if_ctx = priv;
1370
1371 dev_ops = (struct zep_wpa_supp_dev_ops *)if_ctx->dev_ops;
1372 if (!dev_ops->hapd_deinit) {
1373 wpa_printf(MSG_ERROR, "%s: No op registered for hapd deinit", __func__);
1374 return;
1375 }
1376
1377 dev_ops->hapd_deinit(if_ctx->dev_priv);
1378
1379 os_free(if_ctx);
1380 }
1381
wpa_drv_zep_do_acs(void * priv,struct drv_acs_params * params)1382 int wpa_drv_zep_do_acs(void *priv, struct drv_acs_params *params)
1383 {
1384 struct zep_drv_if_ctx *if_ctx = NULL;
1385 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1386 int ret = -1;
1387
1388 if ((!priv) || (!params)) {
1389 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1390 goto out;
1391 }
1392
1393 if_ctx = priv;
1394
1395 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1396 if (!dev_ops->do_acs) {
1397 wpa_printf(MSG_ERROR, "%s: No op registered for do_acs", __func__);
1398 goto out;
1399 }
1400
1401 ret = dev_ops->do_acs(if_ctx->dev_priv, params);
1402 if (ret) {
1403 wpa_printf(MSG_ERROR, "%s: do_acs op failed", __func__);
1404 goto out;
1405 }
1406
1407 ret = 0;
1408
1409 out:
1410 return ret;
1411 }
1412 #endif
1413
wpa_drv_zep_scan2(void * priv,struct wpa_driver_scan_params * params)1414 static int wpa_drv_zep_scan2(void *priv, struct wpa_driver_scan_params *params)
1415 {
1416 struct zep_drv_if_ctx *if_ctx = NULL;
1417 const struct zep_wpa_supp_dev_ops *dev_ops;
1418 int timeout = 0;
1419 int ret = -1;
1420
1421 if (!priv || !params) {
1422 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1423 goto out;
1424 }
1425
1426 if_ctx = priv;
1427 if (if_ctx->scan_res2_get_in_prog) {
1428 wpa_printf(MSG_ERROR, "%s: Scan is already in progress", __func__);
1429 goto out;
1430 }
1431
1432 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1433 if (!dev_ops->scan2) {
1434 wpa_printf(MSG_ERROR, "%s: No op registered for scan2", __func__);
1435 goto out;
1436 }
1437
1438 ret = dev_ops->scan2(if_ctx->dev_priv, params);
1439 if (ret) {
1440 wpa_printf(MSG_ERROR, "%s: scan2 op failed", __func__);
1441 goto out;
1442 }
1443
1444 /* The driver delivers events to notify when scan is
1445 * complete, so use longer timeout to avoid race conditions
1446 * with scanning and following association request.
1447 */
1448 timeout = SCAN_TIMEOUT;
1449
1450 wpa_printf(MSG_DEBUG,
1451 "%s: Scan requested - scan timeout %d seconds",
1452 __func__,
1453 timeout);
1454
1455 eloop_cancel_timeout(wpa_drv_zep_scan_timeout,
1456 if_ctx,
1457 if_ctx->supp_if_ctx);
1458
1459 eloop_register_timeout(timeout,
1460 0,
1461 wpa_drv_zep_scan_timeout,
1462 if_ctx,
1463 if_ctx->supp_if_ctx);
1464
1465 ret = 0;
1466
1467 out:
1468 return ret;
1469 }
1470
1471
1472 /**
1473 * wpa_drv_zep_get_scan_results2 - Fetch the latest scan results
1474 * @priv: Pointer to private data from wpa_drv_zep_init()
1475 * Returns: Scan results on success, -1 on failure
1476 */
wpa_drv_zep_get_scan_results2(void * priv)1477 struct wpa_scan_results *wpa_drv_zep_get_scan_results2(void *priv)
1478 {
1479 struct zep_drv_if_ctx *if_ctx = NULL;
1480 const struct zep_wpa_supp_dev_ops *dev_ops;
1481 int ret = -1;
1482
1483 if (!priv) {
1484 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1485 goto out;
1486 }
1487
1488 if_ctx = priv;
1489
1490 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1491 if (!dev_ops->get_scan_results2) {
1492 wpa_printf(MSG_ERROR,
1493 "%s: No op registered for scan2",
1494 __func__);
1495 goto out;
1496 }
1497
1498 if_ctx->scan_res2 = os_zalloc(sizeof(*if_ctx->scan_res2));
1499 if (!if_ctx->scan_res2) {
1500 wpa_printf(MSG_ERROR, "%s: Failed to alloc memory for scan results", __func__);
1501 goto out;
1502 }
1503
1504 if_ctx->scan_res2_get_in_prog = true;
1505 k_sem_reset(&if_ctx->drv_resp_sem);
1506
1507 ret = dev_ops->get_scan_results2(if_ctx->dev_priv);
1508 if (ret) {
1509 wpa_printf(MSG_ERROR, "%s: get_scan_results2 op failed", __func__);
1510 if_ctx->scan_res2_get_in_prog = false;
1511 goto out;
1512 }
1513
1514 k_sem_take(&if_ctx->drv_resp_sem, K_SECONDS(SCAN_TIMEOUT));
1515
1516 if (if_ctx->scan_res2_get_in_prog) {
1517 wpa_printf(MSG_ERROR, "%s: Timed out waiting for scan results", __func__);
1518 /* If this is a temporary issue, then we can allow subsequent scans */
1519 if_ctx->scan_res2_get_in_prog = false;
1520 ret = -1;
1521 goto out;
1522 }
1523
1524 ret = 0;
1525 out:
1526 if (ret == -1) {
1527 if (if_ctx->scan_res2) {
1528 wpa_scan_results_free(if_ctx->scan_res2);
1529 if_ctx->scan_res2 = NULL;
1530 }
1531 }
1532
1533 return if_ctx->scan_res2;
1534 }
1535
1536
wpa_drv_zep_deauthenticate(void * priv,const u8 * addr,u16 reason_code)1537 static int wpa_drv_zep_deauthenticate(void *priv, const u8 *addr,
1538 u16 reason_code)
1539 {
1540 struct zep_drv_if_ctx *if_ctx = NULL;
1541 const struct zep_wpa_supp_dev_ops *dev_ops;
1542 int ret = -1;
1543
1544 if ((!priv) || (!addr)) {
1545 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1546 goto out;
1547 }
1548
1549 if_ctx = priv;
1550
1551 if (if_ctx->ft_roaming) {
1552 if_ctx->ft_roaming = false;
1553 }
1554
1555 if (if_ctx->roaming) {
1556 if_ctx->roaming = false;
1557 }
1558
1559 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1560 ret = dev_ops->deauthenticate(if_ctx->dev_priv, addr, reason_code);
1561 if (ret) {
1562 wpa_printf(MSG_ERROR, "%s: deauthenticate op failed", __func__);
1563 goto out;
1564 }
1565
1566 ret = 0;
1567 out:
1568 return ret;
1569 }
1570
1571
wpa_drv_zep_authenticate(void * priv,struct wpa_driver_auth_params * params)1572 static int wpa_drv_zep_authenticate(void *priv,
1573 struct wpa_driver_auth_params *params)
1574 {
1575 struct zep_drv_if_ctx *if_ctx = NULL;
1576 const struct zep_wpa_supp_dev_ops *dev_ops;
1577 struct wpa_bss *curr_bss;
1578 int ret = -1;
1579 struct wpa_supplicant *wpa_s = NULL;
1580
1581 if ((!priv) || (!params)) {
1582 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1583 goto out;
1584 }
1585
1586 if_ctx = priv;
1587 wpa_s = if_ctx->supp_if_ctx;
1588 if_ctx->ft_roaming = false;
1589 if_ctx->roaming = false;
1590
1591 if (params->auth_alg == WPA_AUTH_ALG_FT) {
1592 if_ctx->ft_roaming = true;
1593 }
1594
1595 if (wpa_s->assoc_freq) {
1596 if_ctx->roaming = true;
1597 }
1598
1599 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1600
1601 os_memcpy(if_ctx->ssid, params->ssid, params->ssid_len);
1602
1603 if_ctx->ssid_len = params->ssid_len;
1604
1605 curr_bss = wpa_bss_get(if_ctx->supp_if_ctx, params->bssid, params->ssid, params->ssid_len);
1606 if (!curr_bss) {
1607 wpa_printf(MSG_ERROR, "%s: Failed to get BSS", __func__);
1608 ret = -1;
1609 goto out;
1610 }
1611
1612 if (params->bssid)
1613 os_memcpy(if_ctx->auth_attempt_bssid, params->bssid, ETH_ALEN);
1614
1615 if (if_ctx->associated)
1616 os_memcpy(if_ctx->prev_bssid, if_ctx->bssid, ETH_ALEN);
1617
1618 os_memset(if_ctx->auth_bssid, 0, ETH_ALEN);
1619
1620 if_ctx->associated = false;
1621
1622 ret = dev_ops->authenticate(if_ctx->dev_priv, params, curr_bss);
1623 if (ret) {
1624 wpa_printf(MSG_ERROR, "%s: authenticate op failed", __func__);
1625 goto out;
1626 }
1627
1628 ret = 0;
1629 out:
1630 return ret;
1631 }
1632
1633
wpa_drv_zep_associate(void * priv,struct wpa_driver_associate_params * params)1634 static int wpa_drv_zep_associate(void *priv,
1635 struct wpa_driver_associate_params *params)
1636 {
1637 struct zep_drv_if_ctx *if_ctx = NULL;
1638 const struct zep_wpa_supp_dev_ops *dev_ops;
1639 int ret = -1;
1640
1641 if ((!priv) || (!params)) {
1642 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1643 goto out;
1644 }
1645
1646 if_ctx = priv;
1647
1648 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1649
1650 if (IS_ENABLED(CONFIG_AP) && params->mode == IEEE80211_MODE_AP) {
1651 ret = dev_ops->init_ap(if_ctx->dev_priv,
1652 params);
1653 } else if (params->mode == IEEE80211_MODE_INFRA) {
1654 ret = dev_ops->associate(if_ctx->dev_priv,
1655 params);
1656 } else {
1657 wpa_printf(MSG_ERROR, "%s: Unsupported mode", __func__);
1658 goto out;
1659 }
1660
1661 if (ret) {
1662 wpa_printf(MSG_ERROR, "%s: associate op failed", __func__);
1663 goto out;
1664 }
1665
1666 ret = 0;
1667 out:
1668 return ret;
1669 }
1670
1671
_wpa_drv_zep_set_key(void * priv,const char * ifname,enum wpa_alg alg,const u8 * addr,int key_idx,int set_tx,const u8 * seq,size_t seq_len,const u8 * key,size_t key_len,enum key_flag key_flag)1672 static int _wpa_drv_zep_set_key(void *priv,
1673 const char *ifname,
1674 enum wpa_alg alg,
1675 const u8 *addr,
1676 int key_idx,
1677 int set_tx,
1678 const u8 *seq,
1679 size_t seq_len,
1680 const u8 *key,
1681 size_t key_len,
1682 enum key_flag key_flag)
1683 {
1684 struct zep_drv_if_ctx *if_ctx = NULL;
1685 const struct zep_wpa_supp_dev_ops *dev_ops;
1686 struct net_if *iface;
1687 int ret = -1;
1688
1689 if (!priv) {
1690 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1691 goto out;
1692 }
1693 if ((alg != WPA_ALG_NONE) && !key) {
1694 wpa_printf(MSG_ERROR,
1695 "%s: Missing mandatory params",
1696 __func__);
1697 goto out;
1698 }
1699
1700 if_ctx = priv;
1701 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1702
1703 iface = net_if_lookup_by_dev(if_ctx->dev_ctx);
1704 if (!iface) {
1705 wpa_printf(MSG_ERROR, "%s: Failed to get iface", __func__);
1706 goto out;
1707 }
1708
1709 if (!net_if_is_admin_up(iface)) {
1710 goto out;
1711 }
1712
1713 wpa_printf(MSG_DEBUG, "%s: priv:%p alg %d addr %p key_idx %d set_tx %d seq %p "
1714 "seq_len %d key %p key_len %d key_flag %x",
1715 __func__,
1716 if_ctx->dev_priv,
1717 alg, addr,
1718 key_idx,
1719 set_tx,
1720 seq,
1721 seq_len,
1722 key,
1723 key_len,
1724 key_flag);
1725
1726 ret = dev_ops->set_key(if_ctx->dev_priv,
1727 ifname,
1728 alg,
1729 addr,
1730 key_idx,
1731 set_tx,
1732 seq,
1733 seq_len,
1734 key,
1735 key_len,
1736 key_flag);
1737 if (ret) {
1738 wpa_printf(MSG_ERROR, "%s: set_key op failed", __func__);
1739 goto out;
1740 }
1741 out:
1742 return ret;
1743 }
1744
1745
wpa_drv_zep_set_key(void * priv,struct wpa_driver_set_key_params * params)1746 static int wpa_drv_zep_set_key(void* priv,
1747 struct wpa_driver_set_key_params *params)
1748 {
1749 return _wpa_drv_zep_set_key(priv,
1750 params->ifname,
1751 params->alg,
1752 params->addr,
1753 params->key_idx,
1754 params->set_tx,
1755 params->seq,
1756 params->seq_len,
1757 params->key,
1758 params->key_len,
1759 params->key_flag);
1760 }
1761
1762
wpa_drv_zep_get_capa(void * priv,struct wpa_driver_capa * capa)1763 static int wpa_drv_zep_get_capa(void *priv, struct wpa_driver_capa *capa)
1764 {
1765 struct zep_drv_if_ctx *if_ctx = NULL;
1766 const struct zep_wpa_supp_dev_ops *dev_ops;
1767 int ret = -1;
1768
1769 if ((!priv) || (!capa)) {
1770 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1771 goto out;
1772 }
1773
1774 if_ctx = priv;
1775 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1776
1777 if (!dev_ops->get_capa) {
1778 wpa_printf(MSG_ERROR, "%s: get_capa op not supported", __func__);
1779 goto out;
1780 }
1781
1782 ret = dev_ops->get_capa(if_ctx->dev_priv, capa);
1783 if (ret) {
1784 wpa_printf(MSG_ERROR, "%s: get_capa op failed", __func__);
1785 goto out;
1786 }
1787
1788 ret = 0;
1789
1790 if_ctx->capa = *capa;
1791
1792 out:
1793 return ret;
1794 }
1795
1796
wpa_drv_zep_get_bssid(void * priv,u8 * bssid)1797 static int wpa_drv_zep_get_bssid(void *priv, u8 *bssid)
1798 {
1799 struct zep_drv_if_ctx *if_ctx = NULL;
1800
1801 if_ctx = priv;
1802
1803 os_memcpy(bssid, if_ctx->bssid, ETH_ALEN);
1804
1805 return 0;
1806 }
1807
1808
wpa_drv_zep_get_ssid(void * priv,u8 * ssid)1809 static int wpa_drv_zep_get_ssid(void *priv,
1810 u8 *ssid)
1811 {
1812 struct zep_drv_if_ctx *if_ctx = NULL;
1813
1814 if_ctx = priv;
1815
1816 wpa_printf(MSG_DEBUG,
1817 "%s: SSID size: %d",
1818 __func__,
1819 if_ctx->ssid_len);
1820
1821 os_memcpy(ssid, if_ctx->ssid, if_ctx->ssid_len);
1822
1823 return if_ctx->ssid_len;
1824 }
1825
1826
wpa_drv_zep_set_supp_port(void * priv,int authorized)1827 static int wpa_drv_zep_set_supp_port(void *priv,
1828 int authorized)
1829 {
1830 struct zep_drv_if_ctx *if_ctx = NULL;
1831 const struct zep_wpa_supp_dev_ops *dev_ops;
1832 struct net_if *iface = NULL;
1833
1834 int ret;
1835
1836 if_ctx = priv;
1837
1838 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1839
1840 iface = net_if_lookup_by_dev(if_ctx->dev_ctx);
1841
1842 ret = dev_ops->set_supp_port(if_ctx->dev_priv,
1843 authorized,
1844 if_ctx->bssid);
1845
1846 #ifdef CONFIG_NET_DHCPV4
1847 if (authorized) {
1848 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_SKIP_DHCP_ON_ROAMING
1849 if (if_ctx->ft_roaming == true || if_ctx->roaming == true) {
1850 if_ctx->roaming = false;
1851 if_ctx->ft_roaming = false;
1852 } else {
1853 net_dhcpv4_restart(iface);
1854 }
1855 #else
1856 net_dhcpv4_restart(iface);
1857 #endif
1858 }
1859
1860 #endif
1861
1862 return ret;
1863 }
1864
1865
wpa_drv_zep_signal_poll(void * priv,struct wpa_signal_info * si)1866 static int wpa_drv_zep_signal_poll(void *priv, struct wpa_signal_info *si)
1867 {
1868 struct zep_drv_if_ctx *if_ctx = NULL;
1869 const struct zep_wpa_supp_dev_ops *dev_ops;
1870 int ret = -1;
1871
1872 if (!priv) {
1873 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1874 goto out;
1875 }
1876
1877 if (!si) {
1878 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1879 goto out;
1880 }
1881
1882 if_ctx = priv;
1883 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1884
1885 os_memset(si, 0, sizeof(*si));
1886
1887 if (dev_ops && dev_ops->signal_poll) {
1888 ret = dev_ops->signal_poll(if_ctx->dev_priv, si, if_ctx->bssid);
1889 if (ret) {
1890 wpa_printf(MSG_ERROR, "%s: Signal polling failed: %d", __func__, ret);
1891 goto out;
1892 }
1893 } else {
1894 wpa_printf(MSG_ERROR, "%s: Signal polling not supported", __func__);
1895 goto out;
1896 }
1897
1898 out:
1899 return ret;
1900 }
1901
wpa_drv_zep_send_action(void * priv,unsigned int freq,unsigned int wait_time,const u8 * dst,const u8 * src,const u8 * bssid,const u8 * data,size_t data_len,int no_cck)1902 static int wpa_drv_zep_send_action(void *priv, unsigned int freq,
1903 unsigned int wait_time,
1904 const u8 *dst, const u8 *src,
1905 const u8 *bssid,
1906 const u8 *data, size_t data_len,
1907 int no_cck)
1908 {
1909 struct zep_drv_if_ctx *if_ctx = NULL;
1910 const struct zep_wpa_supp_dev_ops *dev_ops;
1911 int ret = -1;
1912 u8 *buf;
1913 struct ieee80211_hdr *hdr;
1914
1915 if_ctx = priv;
1916 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1917
1918 wpa_printf(MSG_DEBUG, "wpa_supp: Send Action frame ("
1919 "freq=%u MHz wait=%d ms no_cck=%d)",
1920 freq, wait_time, no_cck);
1921
1922 buf = os_zalloc(24 + data_len);
1923 if (buf == NULL)
1924 return ret;
1925
1926 os_memcpy(buf + 24, data, data_len);
1927
1928 hdr = (struct ieee80211_hdr *)buf;
1929 hdr->frame_control =
1930 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
1931 os_memcpy(hdr->addr1, dst, ETH_ALEN);
1932 os_memcpy(hdr->addr2, src, ETH_ALEN);
1933 os_memcpy(hdr->addr3, bssid, ETH_ALEN);
1934
1935 ret = dev_ops->send_mlme(if_ctx->dev_priv, buf, 24 + data_len,
1936 0, freq, no_cck, 1,
1937 wait_time, 0);
1938 if (ret) {
1939 wpa_printf(MSG_ERROR, "wpa_supp: Failed to send Action frame: %d", ret);
1940 }
1941
1942 os_free(buf);
1943
1944 return ret;
1945 }
1946
wpa_drv_zep_get_ext_capab(void * priv,enum wpa_driver_if_type type,const u8 ** ext_capa,const u8 ** ext_capa_mask,unsigned int * ext_capa_len)1947 static int wpa_drv_zep_get_ext_capab(void *priv, enum wpa_driver_if_type type,
1948 const u8 **ext_capa, const u8 **ext_capa_mask,
1949 unsigned int *ext_capa_len)
1950 {
1951 struct wpa_driver_capa capa;
1952
1953 wpa_drv_zep_get_capa(priv, &capa);
1954
1955 /* By default, use the per-radio values */
1956 *ext_capa = capa.extended_capa;
1957 *ext_capa_mask = capa.extended_capa_mask;
1958 *ext_capa_len = capa.extended_capa_len;
1959
1960 return 0;
1961 }
1962
wpa_drv_zep_get_conn_info(void * priv,struct wpa_conn_info * ci)1963 static int wpa_drv_zep_get_conn_info(void *priv, struct wpa_conn_info *ci)
1964 {
1965 struct zep_drv_if_ctx *if_ctx = NULL;
1966 const struct zep_wpa_supp_dev_ops *dev_ops;
1967 int ret = -1;
1968
1969 if (!priv) {
1970 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1971 goto out;
1972 }
1973
1974 if (!ci) {
1975 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1976 goto out;
1977 }
1978
1979 if_ctx = priv;
1980 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1981
1982 if (!dev_ops) {
1983 wpa_printf(MSG_ERROR, "%s:Failed to get dev_ops handle", __func__);
1984 goto out;
1985 }
1986
1987 if (dev_ops->get_conn_info) {
1988 ret = dev_ops->get_conn_info(if_ctx->dev_priv, ci);
1989 if (ret) {
1990 wpa_printf(MSG_ERROR, "%s: Failed to get connection info: %d", __func__, ret);
1991 goto out;
1992 }
1993 } else {
1994 wpa_printf(MSG_ERROR, "%s: Getting connection info is not supported", __func__);
1995 goto out;
1996 }
1997
1998 out:
1999 return ret;
2000 }
2001
wpa_drv_zep_set_country(void * priv,const char * alpha2_arg)2002 static int wpa_drv_zep_set_country(void *priv, const char *alpha2_arg)
2003 {
2004 struct zep_drv_if_ctx *if_ctx = NULL;
2005 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
2006 char alpha2[3];
2007 int ret = -1;
2008
2009 if_ctx = priv;
2010
2011 alpha2[0] = alpha2_arg[0];
2012 alpha2[1] = alpha2_arg[1];
2013 alpha2[2] = '\0';
2014
2015 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2016 if (!dev_ops->set_country) {
2017 wpa_printf(MSG_ERROR, "%s: No op registered for set_country", __func__);
2018 return ret;
2019 }
2020
2021 ret = dev_ops->set_country(if_ctx->dev_priv, alpha2);
2022 if (ret) {
2023 wpa_printf(MSG_ERROR, "%s: set_country op failed", __func__);
2024 return ret;
2025 }
2026
2027 return ret;
2028 }
2029
wpa_drv_zep_get_country(void * priv,char * alpha2)2030 static int wpa_drv_zep_get_country(void *priv, char *alpha2)
2031 {
2032 struct zep_drv_if_ctx *if_ctx = NULL;
2033 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
2034 int ret = -1;
2035
2036 if_ctx = priv;
2037
2038 alpha2[0] = '\0';
2039
2040 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2041 if (!dev_ops->get_country) {
2042 wpa_printf(MSG_ERROR, "%s: No op registered for get_country", __func__);
2043 return ret;
2044 }
2045
2046 ret = dev_ops->get_country(if_ctx->dev_priv, alpha2);
2047 if (ret) {
2048 wpa_printf(MSG_ERROR, "%s: get_country op failed", __func__);
2049 return ret;
2050 }
2051
2052 alpha2[2] = '\0';
2053
2054 return ret;
2055 }
2056
2057 #ifdef CONFIG_AP
2058 #ifndef CONFIG_WIFI_NM_HOSTAPD_AP
register_mgmt_frames_ap(struct zep_drv_if_ctx * if_ctx)2059 static int register_mgmt_frames_ap(struct zep_drv_if_ctx *if_ctx)
2060 {
2061 const struct zep_wpa_supp_dev_ops *dev_ops;
2062 static const int stypes[] = {
2063 WLAN_FC_STYPE_AUTH,
2064 WLAN_FC_STYPE_ASSOC_REQ,
2065 WLAN_FC_STYPE_REASSOC_REQ,
2066 WLAN_FC_STYPE_DISASSOC,
2067 WLAN_FC_STYPE_DEAUTH,
2068 WLAN_FC_STYPE_PROBE_REQ,
2069 };
2070 int i, ret = -1;
2071
2072 if (!if_ctx) {
2073 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
2074 goto out;
2075 }
2076
2077 dev_ops = if_ctx->dev_ctx->config;
2078
2079 if (!dev_ops->register_mgmt_frame) {
2080 wpa_printf(MSG_ERROR, "%s: register_mgmt_frame op not supported", __func__);
2081 goto out;
2082 }
2083
2084 for (i = 0; i < ARRAY_SIZE(stypes); i++) {
2085 ret = dev_ops->register_mgmt_frame(if_ctx->dev_priv,
2086 stypes[i] << 4,
2087 0,
2088 NULL);
2089 if (ret) {
2090 wpa_printf(MSG_ERROR, "%s: register_mgmt_frame op failed", __func__);
2091 goto out;
2092 }
2093 }
2094
2095 out:
2096 return ret;
2097 }
2098 #endif
2099
wpa_drv_zep_set_ap(void * priv,struct wpa_driver_ap_params * params)2100 static int wpa_drv_zep_set_ap(void *priv,
2101 struct wpa_driver_ap_params *params)
2102 {
2103 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
2104 struct zep_drv_if_ctx *if_ctx = NULL;
2105 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
2106 int ret = -1;
2107
2108 if ((!priv) || (!params)) {
2109 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
2110 goto out;
2111 }
2112
2113 if_ctx = priv;
2114
2115 if_ctx->beacon_set = params->reenable ? 0 : if_ctx->beacon_set;
2116
2117 wpa_printf(MSG_EXCESSIVE, "beacon set : %d", if_ctx->beacon_set);
2118 wpa_hexdump(MSG_EXCESSIVE, "Beacon head", params->head, params->head_len);
2119 wpa_hexdump(MSG_EXCESSIVE, "Beacon tail", params->tail, params->tail_len);
2120 wpa_printf(MSG_EXCESSIVE, "beacon_int=%d", params->beacon_int);
2121 wpa_printf(MSG_EXCESSIVE, "beacon_rate=%u", params->beacon_rate);
2122 wpa_printf(MSG_EXCESSIVE, "rate_type=%d", params->rate_type);
2123 wpa_printf(MSG_EXCESSIVE, "dtim_period=%d", params->dtim_period);
2124 wpa_printf(MSG_EXCESSIVE, "ssid=%s", wpa_ssid_txt(params->ssid, params->ssid_len));
2125 wpa_printf(MSG_EXCESSIVE, "ht_opmode=%d", params->ht_opmode);
2126 if (params->freq) {
2127 wpa_printf(MSG_EXCESSIVE, "params->freq->freq: %d", params->freq->freq);
2128 wpa_printf(MSG_EXCESSIVE, "params->freq->channel: %d", params->freq->channel);
2129 wpa_printf(MSG_EXCESSIVE, "params->freq->ht_enabled: %d", params->freq->ht_enabled);
2130 wpa_printf(MSG_EXCESSIVE, "params->freq->sec_channel_offset: %d", params->freq->sec_channel_offset);
2131 wpa_printf(MSG_EXCESSIVE, "params->freq->vht_enabled: %d", params->freq->vht_enabled);
2132 wpa_printf(MSG_EXCESSIVE, "params->freq->he_enabled: %d", params->freq->he_enabled);
2133 wpa_printf(MSG_EXCESSIVE, "params->freq->bandwidth: %d", params->freq->bandwidth);
2134 }
2135
2136 if (params->proberesp && params->proberesp_len) {
2137 wpa_hexdump(MSG_EXCESSIVE, "proberesp (offload)", params->proberesp, params->proberesp_len);
2138 }
2139 switch (params->hide_ssid)
2140 {
2141 case NO_SSID_HIDING:
2142 wpa_printf(MSG_EXCESSIVE, "hidden SSID not in use");
2143 break;
2144 case HIDDEN_SSID_ZERO_LEN:
2145 wpa_printf(MSG_EXCESSIVE, "hidden SSID zero len");
2146 break;
2147 case HIDDEN_SSID_ZERO_CONTENTS:
2148 wpa_printf(MSG_EXCESSIVE, "hidden SSID zero contents");
2149 break;
2150 }
2151 wpa_printf(MSG_EXCESSIVE, "privacy=%d", params->privacy);
2152 wpa_printf(MSG_EXCESSIVE, "auth_algs=0x%x", params->auth_algs);
2153 wpa_printf(MSG_EXCESSIVE, "wpa_version=0x%x", params->wpa_version);
2154 wpa_printf(MSG_EXCESSIVE, "key_mgmt_suites=0x%x", params->key_mgmt_suites);
2155 wpa_printf(MSG_EXCESSIVE, "pairwise_ciphers=0x%x", params->pairwise_ciphers);
2156 wpa_printf(MSG_EXCESSIVE, "group_cipher=0x%x", params->group_cipher);
2157
2158 if (params->beacon_ies)
2159 wpa_hexdump_buf(MSG_EXCESSIVE, "beacon_ies", params->beacon_ies);
2160 if (params->proberesp_ies)
2161 wpa_hexdump_buf(MSG_EXCESSIVE, "proberesp_ies", params->proberesp_ies);
2162 if (params->assocresp_ies)
2163 wpa_hexdump_buf(MSG_EXCESSIVE, "assocresp_ies", params->assocresp_ies);
2164
2165 #ifdef CONFIG_IEEE80211AX
2166 if (params->he_spr_ctrl)
2167 wpa_printf(MSG_EXCESSIVE, "he_spr_ctrl=0x%x", params->he_spr_ctrl);
2168 #endif
2169
2170 if (params->twt_responder)
2171 wpa_printf(MSG_EXCESSIVE, "twt_responder=%d", params->twt_responder);
2172
2173 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2174 if (!dev_ops->set_ap) {
2175 wpa_printf(MSG_ERROR, "%s: No op registered for set_ap", __func__);
2176 goto out;
2177 }
2178
2179 ret = dev_ops->set_ap(if_ctx->dev_priv, if_ctx->beacon_set, params);
2180 if (ret) {
2181 wpa_printf(MSG_ERROR, "%s: set_ap op failed", __func__);
2182 goto out;
2183 }
2184
2185 if_ctx->beacon_set = 1;
2186
2187 ret = 0;
2188
2189 #else
2190 struct zep_drv_if_ctx *if_ctx = NULL;
2191 const struct zep_wpa_supp_dev_ops *dev_ops;
2192 int ret = -1;
2193
2194 if ((!priv) || (!params)) {
2195 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
2196 goto out;
2197 }
2198
2199 if_ctx = priv;
2200
2201 dev_ops = if_ctx->dev_ctx->config;
2202
2203 if (!if_ctx->beacon_set && !dev_ops->start_ap) {
2204 wpa_printf(MSG_ERROR, "%s: start_ap op not supported", __func__);
2205 goto out;
2206 } else if (if_ctx->beacon_set && !dev_ops->change_beacon) {
2207 wpa_printf(MSG_ERROR, "%s: change_beacon op not supported", __func__);
2208 goto out;
2209 }
2210
2211 if (!if_ctx->beacon_set) {
2212 ret = register_mgmt_frames_ap(if_ctx);
2213 if (ret) {
2214 wpa_printf(MSG_ERROR, "%s: register_mgmt_frames_ap failed", __func__);
2215 goto out;
2216 }
2217 ret = dev_ops->start_ap(if_ctx->dev_priv,
2218 params);
2219 if (ret) {
2220 wpa_printf(MSG_ERROR, "%s: start_ap op failed: %d", __func__, ret);
2221 goto out;
2222 }
2223 } else {
2224 ret = dev_ops->change_beacon(if_ctx->dev_priv,
2225 params);
2226 if (ret) {
2227 wpa_printf(MSG_ERROR, "%s: change_beacon op failed: %d", __func__, ret);
2228 goto out;
2229 }
2230 }
2231
2232 if (!if_ctx->beacon_set) {
2233 if_ctx->beacon_set = true;
2234 }
2235
2236 if_ctx->freq = params->freq->freq;
2237 #endif
2238 out:
2239 return ret;
2240 }
2241
wpa_drv_zep_stop_ap(void * priv,int link_id)2242 int wpa_drv_zep_stop_ap(void *priv, int link_id)
2243 {
2244 struct zep_drv_if_ctx *if_ctx = NULL;
2245 const struct zep_wpa_supp_dev_ops *dev_ops;
2246 int ret = -1;
2247
2248 /* Unused till Wi-Fi7 MLO is supported in Zephyr */
2249 (void)link_id;
2250
2251 if (!priv) {
2252 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
2253 goto out;
2254 }
2255
2256 if_ctx = priv;
2257
2258 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
2259 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2260 #else
2261 dev_ops = if_ctx->dev_ctx->config;
2262 #endif
2263
2264 if (!dev_ops->stop_ap) {
2265 wpa_printf(MSG_ERROR, "%s: stop_ap op not supported", __func__);
2266 goto out;
2267 }
2268
2269 ret = dev_ops->stop_ap(if_ctx->dev_priv);
2270
2271 if (ret) {
2272 wpa_printf(MSG_ERROR, "%s: stop_ap op failed: %d", __func__, ret);
2273 goto out;
2274 }
2275
2276 if_ctx->freq = 0;
2277 out:
2278 if (if_ctx) {
2279 if_ctx->beacon_set = false;
2280 }
2281 return ret;
2282 }
2283
wpa_drv_zep_deinit_ap(void * priv)2284 int wpa_drv_zep_deinit_ap(void *priv)
2285 {
2286 struct zep_drv_if_ctx *if_ctx = NULL;
2287 const struct zep_wpa_supp_dev_ops *dev_ops;
2288 int ret = -1;
2289
2290 if (!priv) {
2291 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
2292 goto out;
2293 }
2294
2295 if_ctx = priv;
2296
2297 dev_ops = if_ctx->dev_ctx->config;
2298
2299 if (!dev_ops->deinit_ap) {
2300 wpa_printf(MSG_ERROR, "%s: deinit_ap op not supported", __func__);
2301 goto out;
2302 }
2303
2304 ret = dev_ops->deinit_ap(if_ctx->dev_priv);
2305
2306 if (ret) {
2307 wpa_printf(MSG_ERROR, "%s: deinit_ap op failed: %d", __func__, ret);
2308 goto out;
2309 }
2310
2311 out:
2312 if (if_ctx) {
2313 if_ctx->beacon_set = false;
2314 }
2315 return ret;
2316 }
2317
wpa_drv_zep_sta_add(void * priv,struct hostapd_sta_add_params * params)2318 int wpa_drv_zep_sta_add(void *priv, struct hostapd_sta_add_params *params)
2319 {
2320 struct zep_drv_if_ctx *if_ctx = priv;
2321 const struct zep_wpa_supp_dev_ops *dev_ops;
2322 int ret = -1;
2323
2324 if ((!priv) || (!params)) {
2325 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
2326 goto out;
2327 }
2328
2329 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
2330 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2331 #else
2332 dev_ops = if_ctx->dev_ctx->config;
2333 #endif
2334 if (!dev_ops->sta_add) {
2335 wpa_printf(MSG_ERROR, "%s: sta_add op not supported", __func__);
2336 goto out;
2337 }
2338
2339 ret = dev_ops->sta_add(if_ctx->dev_priv, params);
2340 if (ret) {
2341 wpa_printf(MSG_ERROR, "%s: sta_add op failed: %d", __func__, ret);
2342 goto out;
2343 }
2344
2345 out:
2346 return ret;
2347 }
2348
wpa_drv_zep_sta_set_flags(void * priv,const u8 * addr,u32 total_flags,u32 flags_or,u32 flags_and)2349 int wpa_drv_zep_sta_set_flags(void *priv, const u8 *addr, u32 total_flags,
2350 u32 flags_or, u32 flags_and)
2351 {
2352 struct zep_drv_if_ctx *if_ctx = priv;
2353 const struct zep_wpa_supp_dev_ops *dev_ops;
2354 int ret = -1;
2355
2356 if ((!priv) || (!addr)) {
2357 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
2358 goto out;
2359 }
2360
2361 dev_ops = if_ctx->dev_ctx->config;
2362 if (!dev_ops->sta_set_flags) {
2363 wpa_printf(MSG_ERROR, "%s: sta_set_flags op not supported",
2364 __func__);
2365 goto out;
2366 }
2367
2368 ret = dev_ops->sta_set_flags(if_ctx->dev_priv, addr, total_flags, flags_or, flags_and);
2369 if (ret) {
2370 wpa_printf(MSG_ERROR, "%s: sta_set_flags op failed: %d", __func__, ret);
2371 goto out;
2372 }
2373
2374 out:
2375 return ret;
2376 }
2377
wpa_drv_zep_sta_deauth(void * priv,const u8 * own_addr,const u8 * addr,u16 reason_code,int link_id)2378 int wpa_drv_zep_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, u16 reason_code,
2379 int link_id)
2380 {
2381 struct zep_drv_if_ctx *if_ctx = priv;
2382 const struct zep_wpa_supp_dev_ops *dev_ops;
2383 int ret = -1;
2384 struct ieee80211_mgmt mgmt;
2385
2386 /* Unused till Wi-Fi7 MLO is supported in Zephyr */
2387 (void)link_id;
2388
2389 if ((!priv) || (!addr)) {
2390 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
2391 goto out;
2392 }
2393
2394 dev_ops = if_ctx->dev_ctx->config;
2395
2396 wpa_printf(MSG_DEBUG, "%s: addr %p reason_code %d",
2397 __func__, addr, reason_code);
2398
2399 memset(&mgmt, 0, sizeof(mgmt));
2400 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
2401 WLAN_FC_STYPE_DEAUTH);
2402 memcpy(mgmt.da, addr, ETH_ALEN);
2403 memcpy(mgmt.sa, own_addr, ETH_ALEN);
2404 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
2405 mgmt.u.deauth.reason_code = host_to_le16(reason_code);
2406
2407 return wpa_drv_zep_send_mlme(priv, (u8 *) &mgmt,
2408 IEEE80211_HDRLEN +
2409 sizeof(mgmt.u.deauth), 0, if_ctx->freq, 0, 0,
2410 0, 0, -1);
2411 out:
2412 return ret;
2413 }
2414
wpa_drv_zep_sta_disassoc(void * priv,const u8 * own_addr,const u8 * addr,u16 reason_code)2415 int wpa_drv_zep_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, u16 reason_code)
2416 {
2417 struct zep_drv_if_ctx *if_ctx = priv;
2418 const struct zep_wpa_supp_dev_ops *dev_ops;
2419 int ret = -1;
2420 struct ieee80211_mgmt mgmt;
2421
2422 if ((!priv) || (!addr)) {
2423 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
2424 goto out;
2425 }
2426
2427 dev_ops = if_ctx->dev_ctx->config;
2428
2429 wpa_printf(MSG_DEBUG, "%s: addr %p reason_code %d",
2430 __func__, addr, reason_code);
2431
2432 memset(&mgmt, 0, sizeof(mgmt));
2433 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
2434 WLAN_FC_STYPE_DISASSOC);
2435 memcpy(mgmt.da, addr, ETH_ALEN);
2436 memcpy(mgmt.sa, own_addr, ETH_ALEN);
2437 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
2438 mgmt.u.disassoc.reason_code = host_to_le16(reason_code);
2439
2440 return wpa_drv_zep_send_mlme(priv, (u8 *) &mgmt,
2441 IEEE80211_HDRLEN +
2442 sizeof(mgmt.u.disassoc), 0, if_ctx->freq, 0, 0,
2443 0, 0, -1);
2444 out:
2445 return ret;
2446 }
2447
wpa_drv_zep_sta_remove(void * priv,const u8 * addr)2448 int wpa_drv_zep_sta_remove(void *priv, const u8 *addr)
2449 {
2450 struct zep_drv_if_ctx *if_ctx = priv;
2451 const struct zep_wpa_supp_dev_ops *dev_ops;
2452 int ret = -1;
2453
2454 if ((!priv) || (!addr)) {
2455 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
2456 goto out;
2457 }
2458
2459 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
2460 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2461 #else
2462 dev_ops = if_ctx->dev_ctx->config;
2463 #endif
2464 if (!dev_ops->sta_remove) {
2465 wpa_printf(MSG_ERROR, "%s: sta_remove op not supported",
2466 __func__);
2467 goto out;
2468 }
2469
2470 ret = dev_ops->sta_remove(if_ctx->dev_priv, addr);
2471 if (ret) {
2472 wpa_printf(MSG_ERROR, "%s: sta_remove op failed: %d", __func__, ret);
2473 goto out;
2474 }
2475
2476 out:
2477 return ret;
2478 }
2479
wpa_drv_zep_send_mlme(void * priv,const u8 * data,size_t data_len,int noack,unsigned int freq,const u16 * csa_offs,size_t csa_offs_len,int no_encrypt,unsigned int wait,int link_id)2480 int wpa_drv_zep_send_mlme(void *priv, const u8 *data, size_t data_len, int noack,
2481 unsigned int freq, const u16 *csa_offs, size_t csa_offs_len, int no_encrypt,
2482 unsigned int wait, int link_id)
2483 {
2484 struct zep_drv_if_ctx *if_ctx = priv;
2485 const struct zep_wpa_supp_dev_ops *dev_ops;
2486 int ret = -1;
2487
2488 /* Unused till Wi-Fi7 MLO is supported in Zephyr */
2489 (void)link_id;
2490
2491 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
2492 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2493 #else
2494 dev_ops = if_ctx->dev_ctx->config;
2495 #endif
2496 if (!dev_ops->send_mlme) {
2497 wpa_printf(MSG_ERROR, "%s: send_mlme op not supported",
2498 __func__);
2499 goto out;
2500 }
2501
2502 if (freq == 0) {
2503 freq = if_ctx->freq;
2504 }
2505
2506 ret = dev_ops->send_mlme(if_ctx->dev_priv, data, data_len, noack, freq, 0, 0, wait, 0);
2507 if (ret) {
2508 wpa_printf(MSG_ERROR, "%s: send_mlme op failed: %d", __func__, ret);
2509 goto out;
2510 }
2511 ret = 0;
2512 out:
2513 return ret;
2514 }
2515
wpa_drv_hapd_send_eapol(void * priv,const u8 * addr,const u8 * data,size_t data_len,int encrypt,const u8 * own_addr,u32 flags,int link_id)2516 int wpa_drv_hapd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
2517 int encrypt, const u8 *own_addr, u32 flags, int link_id)
2518 {
2519 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
2520 struct zep_drv_if_ctx *if_ctx = priv;
2521 struct hostapd_data *hapd = NULL;
2522 int ret = -1;
2523
2524 /* TODO: Unused for now, but might need for rekeying */
2525 (void)own_addr;
2526 (void)flags;
2527 (void)encrypt;
2528 /* Unused till Wi-Fi7 MLO is supported in Zephyr */
2529 (void)link_id;
2530
2531 hapd = if_ctx->hapd;
2532
2533 wpa_printf(MSG_DEBUG, "hostapd: Send EAPOL frame (encrypt=%d)", encrypt);
2534
2535 ret = l2_packet_send(hapd->l2, addr, ETH_P_EAPOL, data, data_len);
2536 if (ret < 0) {
2537 wpa_printf(MSG_ERROR, "%s: l2_packet_send failed: %d", __func__, ret);
2538 goto out;
2539 }
2540 #else
2541 struct zep_drv_if_ctx *if_ctx = priv;
2542 const struct zep_wpa_supp_dev_ops *dev_ops;
2543 int ret = -1;
2544 struct wpa_supplicant *wpa_s = NULL;
2545
2546 /* TODO: Unused for now, but might need for rekeying */
2547 (void)own_addr;
2548 (void)flags;
2549 (void)encrypt;
2550
2551 wpa_s = if_ctx->supp_if_ctx;
2552 dev_ops = if_ctx->dev_ctx->config;
2553
2554 wpa_printf(MSG_DEBUG, "wpa_supp: Send EAPOL frame (encrypt=%d)", encrypt);
2555
2556 ret = l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data, data_len);
2557 if (ret < 0) {
2558 wpa_printf(MSG_ERROR, "%s: l2_packet_send failed: %d", __func__, ret);
2559 goto out;
2560 }
2561 #endif
2562
2563 ret = 0;
2564 out:
2565 return ret;
2566 }
2567
2568
wpa_drv_zep_get_inact_sec(void * priv,const u8 * addr)2569 int wpa_drv_zep_get_inact_sec(void *priv, const u8 *addr)
2570 {
2571 struct zep_drv_if_ctx *if_ctx = priv;
2572 const struct zep_wpa_supp_dev_ops *dev_ops;
2573 int ret = -1;
2574
2575 dev_ops = if_ctx->dev_ctx->config;
2576 if (!dev_ops->get_inact_sec) {
2577 wpa_printf(MSG_ERROR, "%s: get_inact_sec op not supported\n",
2578 __func__);
2579 goto out;
2580 }
2581
2582 ret = dev_ops->get_inact_sec(if_ctx->dev_priv, addr);
2583 if (ret < 0) {
2584 wpa_printf(MSG_ERROR, "%s: get_inact_sec op failed: %d\n", __func__, ret);
2585 goto out;
2586 }
2587
2588 out:
2589 return ret;
2590 }
2591 #endif /* CONFIG_AP */
2592
wpa_drv_zep_dpp_listen(void * priv,bool enable)2593 int wpa_drv_zep_dpp_listen(void *priv, bool enable)
2594 {
2595 struct zep_drv_if_ctx *if_ctx = NULL;
2596 const struct zep_wpa_supp_dev_ops *dev_ops;
2597 int ret = -1;
2598
2599 if ((!priv)) {
2600 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
2601 goto out;
2602 }
2603
2604 if_ctx = priv;
2605 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2606
2607 if (!dev_ops || !dev_ops->dpp_listen) {
2608 wpa_printf(MSG_ERROR, "%s: dpp_listen op not supported", __func__);
2609 goto out;
2610 }
2611
2612 ret = dev_ops->dpp_listen(if_ctx->dev_priv, enable);
2613 if (ret) {
2614 wpa_printf(MSG_ERROR, "%s: dpp_listen op failed", __func__);
2615 goto out;
2616 }
2617
2618 out:
2619 return ret;
2620
2621 }
2622
wpa_drv_zep_remain_on_channel(void * priv,unsigned int freq,unsigned int duration)2623 int wpa_drv_zep_remain_on_channel(void *priv, unsigned int freq,
2624 unsigned int duration)
2625 {
2626 struct zep_drv_if_ctx *if_ctx = NULL;
2627 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
2628 int ret = -1;
2629
2630 if (!priv) {
2631 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
2632 goto out;
2633 }
2634
2635 if_ctx = priv;
2636 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2637
2638 if (!dev_ops || !dev_ops->remain_on_channel) {
2639 wpa_printf(MSG_ERROR, "%s: remain_on_channel op not supported", __func__);
2640 goto out;
2641 }
2642
2643 ret = dev_ops->remain_on_channel(if_ctx->dev_priv, freq, duration);
2644 if (ret) {
2645 wpa_printf(MSG_ERROR, "%s: dpp_listen op failed", __func__);
2646 goto out;
2647 }
2648
2649 out:
2650 return ret;
2651 }
2652
wpa_drv_zep_cancel_remain_on_channel(void * priv)2653 int wpa_drv_zep_cancel_remain_on_channel(void *priv)
2654 {
2655 struct zep_drv_if_ctx *if_ctx = NULL;
2656 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
2657 int ret = -1;
2658
2659 if (!priv) {
2660 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
2661 goto out;
2662 }
2663
2664 if_ctx = priv;
2665 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2666
2667 if (!dev_ops || !dev_ops->cancel_remain_on_channel) {
2668 wpa_printf(MSG_ERROR, "%s: cancel_remain_on_channel op not supported", __func__);
2669 goto out;
2670 }
2671
2672 ret = dev_ops->cancel_remain_on_channel(if_ctx->dev_priv);
2673 if (ret) {
2674 wpa_printf(MSG_ERROR, "%s: dpp_listen op failed", __func__);
2675 goto out;
2676 }
2677
2678 out:
2679 return ret;
2680 }
2681
wpa_drv_zep_send_action_cancel_wait(void * priv)2682 void wpa_drv_zep_send_action_cancel_wait(void *priv)
2683 {
2684 struct zep_drv_if_ctx *if_ctx = NULL;
2685 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
2686
2687 if (!priv) {
2688 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
2689 goto out;
2690 }
2691
2692 if_ctx = priv;
2693 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2694
2695 if (!dev_ops || !dev_ops->send_action_cancel_wait) {
2696 wpa_printf(MSG_DEBUG, "%s: send_action_cancel_wait op not supported", __func__);
2697 goto out;
2698 }
2699
2700 dev_ops->send_action_cancel_wait(if_ctx->dev_priv);
2701
2702 out:
2703 return;
2704 }
2705
2706 const struct wpa_driver_ops wpa_driver_zep_ops = {
2707 .name = "zephyr",
2708 .desc = "Zephyr wpa_supplicant driver",
2709 .global_init = wpa_drv_zep_global_init,
2710 .global_deinit = wpa_drv_zep_global_deinit,
2711 .init2 = wpa_drv_zep_init,
2712 .deinit = wpa_drv_zep_deinit,
2713 .scan2 = wpa_drv_zep_scan2,
2714 .abort_scan = wpa_drv_zep_abort_scan,
2715 .get_scan_results2 = wpa_drv_zep_get_scan_results2,
2716 .authenticate = wpa_drv_zep_authenticate,
2717 .associate = wpa_drv_zep_associate,
2718 .get_capa = wpa_drv_zep_get_capa,
2719 .get_bssid = wpa_drv_zep_get_bssid,
2720 .get_ssid = wpa_drv_zep_get_ssid,
2721 .set_supp_port = wpa_drv_zep_set_supp_port,
2722 .deauthenticate = wpa_drv_zep_deauthenticate,
2723 .set_key = wpa_drv_zep_set_key,
2724 .signal_poll = wpa_drv_zep_signal_poll,
2725 .send_action = wpa_drv_zep_send_action,
2726 .get_hw_feature_data = wpa_drv_zep_get_hw_feature_data,
2727 .get_ext_capab = wpa_drv_zep_get_ext_capab,
2728 .get_conn_info = wpa_drv_zep_get_conn_info,
2729 .set_country = wpa_drv_zep_set_country,
2730 .get_country = wpa_drv_zep_get_country,
2731 #ifdef CONFIG_AP
2732 #ifdef CONFIG_WIFI_NM_HOSTAPD_AP
2733 .hapd_init = wpa_drv_zep_hapd_init,
2734 .hapd_deinit = wpa_drv_zep_hapd_deinit,
2735 .do_acs = wpa_drv_zep_do_acs,
2736 #endif
2737 .hapd_send_eapol = wpa_drv_hapd_send_eapol,
2738 .send_mlme = wpa_drv_zep_send_mlme,
2739 .set_ap = wpa_drv_zep_set_ap,
2740 .stop_ap = wpa_drv_zep_stop_ap,
2741 .deinit_ap = wpa_drv_zep_deinit_ap,
2742 .sta_add = wpa_drv_zep_sta_add,
2743 #ifndef CONFIG_WIFI_NM_HOSTAPD_AP
2744 .sta_set_flags = wpa_drv_zep_sta_set_flags,
2745 #endif
2746 .sta_deauth = wpa_drv_zep_sta_deauth,
2747 .sta_disassoc = wpa_drv_zep_sta_disassoc,
2748 .sta_remove = wpa_drv_zep_sta_remove,
2749 .get_inact_sec = wpa_drv_zep_get_inact_sec,
2750 #endif /* CONFIG_AP */
2751 .dpp_listen = wpa_drv_zep_dpp_listen,
2752 .remain_on_channel = wpa_drv_zep_remain_on_channel,
2753 .cancel_remain_on_channel = wpa_drv_zep_cancel_remain_on_channel,
2754 .send_action_cancel_wait = wpa_drv_zep_send_action_cancel_wait,
2755 };
2756