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);
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
wpa_supplicant_event_wrapper(void * ctx,enum wpa_event_type event,union wpa_event_data * data)39 void wpa_supplicant_event_wrapper(void *ctx,
40 enum wpa_event_type event,
41 union wpa_event_data *data)
42 {
43 struct wpa_supplicant_event_msg msg = { 0 };
44
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 allocated for event: %d", event);
51 return;
52 }
53 os_memcpy(msg.data, data, sizeof(*data));
54 /* Handle deep copy for some event data */
55 if (event == EVENT_AUTH) {
56 union wpa_event_data *data_tmp = msg.data;
57
58 if (data->auth.ies) {
59 char *ies = os_zalloc(data->auth.ies_len);
60
61 if (!ies) {
62 wpa_printf(MSG_ERROR,
63 "%s:%d Failed to alloc %d bytes\n",
64 __func__, __LINE__, data->auth.ies_len);
65 return;
66 }
67
68 os_memcpy(ies, data->auth.ies, data->auth.ies_len);
69 data_tmp->auth.ies = ies;
70 }
71 } else if (event == EVENT_RX_MGMT) {
72 union wpa_event_data *data_tmp = msg.data;
73
74 if (data->rx_mgmt.frame) {
75 char *frame = os_zalloc(data->rx_mgmt.frame_len);
76
77 if (!frame) {
78 wpa_printf(MSG_ERROR,
79 "%s:%d Failed to alloc %d bytes\n",
80 __func__, __LINE__, data->rx_mgmt.frame_len);
81 return;
82 }
83
84 os_memcpy(frame, data->rx_mgmt.frame, data->rx_mgmt.frame_len);
85 data_tmp->rx_mgmt.frame = frame;
86 }
87 } else if (event == EVENT_TX_STATUS) {
88 union wpa_event_data *data_tmp = msg.data;
89 const struct ieee80211_hdr *hdr;
90
91 if (data->tx_status.data) {
92 char *frame = os_zalloc(data->tx_status.data_len);
93
94 if (!frame) {
95 wpa_printf(MSG_ERROR,
96 "%s:%d Failed to alloc %d bytes\n",
97 __func__, __LINE__, data->tx_status.data_len);
98 return;
99 }
100
101 os_memcpy(frame, data->tx_status.data, data->tx_status.data_len);
102 data_tmp->tx_status.data = frame;
103 hdr = (const struct ieee80211_hdr *) frame;
104 data_tmp->tx_status.dst = hdr->addr1;
105 }
106 } else if (event == EVENT_ASSOC) {
107 union wpa_event_data *data_tmp = msg.data;
108 char *addr = os_zalloc(ETH_ALEN);
109
110 if (!addr) {
111 wpa_printf(MSG_ERROR,
112 "%s:%d Failed to alloc %d bytes\n",
113 __func__, __LINE__, ETH_ALEN);
114 return;
115 }
116
117 os_memcpy(addr, data->assoc_info.addr, ETH_ALEN);
118 data_tmp->assoc_info.addr = addr;
119
120 if (data->assoc_info.req_ies) {
121 char *req_ies = os_zalloc(data->assoc_info.req_ies_len);
122
123 if (!req_ies) {
124 wpa_printf(MSG_ERROR,
125 "%s:%d Failed to alloc %d bytes\n",
126 __func__, __LINE__, data->assoc_info.req_ies_len);
127 return;
128 }
129
130 os_memcpy(req_ies, data->assoc_info.req_ies,
131 data->assoc_info.req_ies_len);
132 data_tmp->assoc_info.req_ies = req_ies;
133 }
134 if (data->assoc_info.resp_ies) {
135 char *resp_ies = os_zalloc(data->assoc_info.resp_ies_len);
136
137 if (!resp_ies) {
138 wpa_printf(MSG_ERROR,
139 "%s:%d Failed to alloc %d bytes\n",
140 __func__, __LINE__, data->assoc_info.resp_ies_len);
141 return;
142 }
143
144 os_memcpy(resp_ies, data->assoc_info.resp_ies,
145 data->assoc_info.resp_ies_len);
146 data_tmp->assoc_info.resp_ies = resp_ies;
147 }
148 if (data->assoc_info.resp_frame) {
149 char *resp_frame = os_zalloc(data->assoc_info.resp_frame_len);
150
151 if (!resp_frame) {
152 wpa_printf(MSG_ERROR,
153 "%s:%d Failed to alloc %d bytes\n",
154 __func__, __LINE__, data->assoc_info.resp_frame_len);
155 return;
156 }
157
158 os_memcpy(resp_frame, data->assoc_info.resp_frame,
159 data->assoc_info.resp_frame_len);
160 data_tmp->assoc_info.resp_frame = resp_frame;
161 }
162 } else if (event == EVENT_ASSOC_REJECT) {
163 union wpa_event_data *data_tmp = msg.data;
164 char *bssid = os_zalloc(ETH_ALEN);
165
166 if (!bssid) {
167 wpa_printf(MSG_ERROR,
168 "%s:%d Failed to alloc %d bytes\n",
169 __func__, __LINE__, ETH_ALEN);
170 return;
171 }
172
173 os_memcpy(bssid, data->assoc_reject.bssid, ETH_ALEN);
174 data_tmp->assoc_reject.bssid = bssid;
175
176 if (data->assoc_reject.resp_ies) {
177 char *resp_ies = os_zalloc(data->assoc_reject.resp_ies_len);
178
179 if (!resp_ies) {
180 wpa_printf(MSG_ERROR,
181 "%s:%d Failed to alloc %d bytes\n",
182 __func__, __LINE__, data->assoc_reject.resp_ies_len);
183 return;
184 }
185
186 os_memcpy(resp_ies, data->assoc_reject.resp_ies,
187 data->assoc_reject.resp_ies_len);
188 data_tmp->assoc_reject.resp_ies = resp_ies;
189 }
190 } else if (event == EVENT_DEAUTH) {
191 union wpa_event_data *data_tmp = msg.data;
192 char *sa = os_zalloc(ETH_ALEN);
193
194 if (!sa) {
195 wpa_printf(MSG_ERROR,
196 "%s:%d Failed to alloc %d bytes\n",
197 __func__, __LINE__, ETH_ALEN);
198 return;
199 }
200
201 os_memcpy(sa, data->deauth_info.addr, ETH_ALEN);
202 data_tmp->deauth_info.addr = sa;
203 if (data->deauth_info.ie) {
204 char *ie = os_zalloc(data->deauth_info.ie_len);
205
206 if (!ie) {
207 wpa_printf(MSG_ERROR,
208 "%s:%d Failed to alloc %d bytes\n",
209 __func__, __LINE__, data->deauth_info.ie_len);
210 return;
211 }
212
213 os_memcpy(ie, data->deauth_info.ie, data->deauth_info.ie_len);
214 data_tmp->deauth_info.ie = ie;
215 }
216 } else if (event == EVENT_DISASSOC) {
217 union wpa_event_data *data_tmp = msg.data;
218 char *sa = os_zalloc(ETH_ALEN);
219
220 if (!sa) {
221 wpa_printf(MSG_ERROR,
222 "%s:%d Failed to alloc %d bytes\n",
223 __func__, __LINE__, ETH_ALEN);
224 return;
225 }
226
227 os_memcpy(sa, data->disassoc_info.addr, ETH_ALEN);
228 data_tmp->disassoc_info.addr = sa;
229 if (data->disassoc_info.ie) {
230 char *ie = os_zalloc(data->disassoc_info.ie_len);
231
232 if (!ie) {
233 wpa_printf(MSG_ERROR,
234 "%s:%d Failed to alloc %d bytes\n",
235 __func__, __LINE__, data->disassoc_info.ie_len);
236 return;
237 }
238
239 os_memcpy(ie, data->disassoc_info.ie, data->disassoc_info.ie_len);
240 data_tmp->disassoc_info.ie = ie;
241 }
242 } else if (event == EVENT_UNPROT_DEAUTH) {
243 union wpa_event_data *data_tmp = msg.data;
244 char *sa = os_zalloc(ETH_ALEN);
245 char *da = os_zalloc(ETH_ALEN);
246
247 if (!sa) {
248 wpa_printf(MSG_ERROR,
249 "%s:%d Failed to alloc %d bytes\n",
250 __func__, __LINE__, ETH_ALEN);
251 return;
252 }
253
254 if (!da) {
255 wpa_printf(MSG_ERROR,
256 "%s:%d Failed to alloc %d bytes\n",
257 __func__, __LINE__, ETH_ALEN);
258 return;
259 }
260 os_memcpy(sa, data->unprot_deauth.sa, ETH_ALEN);
261 data_tmp->unprot_deauth.sa = sa;
262 os_memcpy(da, data->unprot_deauth.da, ETH_ALEN);
263 data_tmp->unprot_deauth.da = da;
264 } else if (event == EVENT_UNPROT_DISASSOC) {
265 union wpa_event_data *data_tmp = msg.data;
266 char *sa = os_zalloc(ETH_ALEN);
267 char *da = os_zalloc(ETH_ALEN);
268
269 if (!sa) {
270 wpa_printf(MSG_ERROR,
271 "%s:%d Failed to alloc %d bytes\n",
272 __func__, __LINE__, ETH_ALEN);
273 return;
274 }
275
276 if (!da) {
277 wpa_printf(MSG_ERROR,
278 "%s:%d Failed to alloc %d bytes\n",
279 __func__, __LINE__, ETH_ALEN);
280 return;
281 }
282 os_memcpy(sa, data->unprot_disassoc.sa, ETH_ALEN);
283 data_tmp->unprot_disassoc.sa = sa;
284 os_memcpy(da, data->unprot_disassoc.da, ETH_ALEN);
285 data_tmp->unprot_disassoc.da = da;
286 }
287 }
288
289 zephyr_wifi_send_event(&msg);
290 }
291
wpa_drv_zep_event_mac_changed(struct zep_drv_if_ctx * if_ctx)292 void wpa_drv_zep_event_mac_changed(struct zep_drv_if_ctx *if_ctx)
293 {
294 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
295 EVENT_INTERFACE_MAC_CHANGED,
296 NULL);
297 }
298
wpa_drv_zep_abort_scan(void * priv,u64 scan_cookie)299 static int wpa_drv_zep_abort_scan(void *priv,
300 u64 scan_cookie)
301 {
302 struct zep_drv_if_ctx *if_ctx = NULL;
303 const struct zep_wpa_supp_dev_ops *dev_ops;
304 int ret = -1;
305
306 if_ctx = priv;
307
308 dev_ops = get_dev_ops(if_ctx->dev_ctx);
309 if (!dev_ops->scan_abort) {
310 wpa_printf(MSG_ERROR,
311 "%s: No op registered for scan_abort",
312 __func__);
313 goto out;
314 }
315
316 ret = dev_ops->scan_abort(if_ctx->dev_priv);
317 out:
318 return ret;
319 }
320
321
322 /**
323 * wpa_drv_zep_scan_timeout - Scan timeout to report scan completion
324 * @eloop_ctx: Driver private data
325 * @timeout_ctx: ctx argument given to wpa_drv_zep_init()
326 *
327 * This function can be used as registered timeout when starting a scan to
328 * generate a scan completed event if the driver does not report this.
329 */
wpa_drv_zep_scan_timeout(void * eloop_ctx,void * timeout_ctx)330 void wpa_drv_zep_scan_timeout(void *eloop_ctx, void *timeout_ctx)
331 {
332 struct zep_drv_if_ctx *if_ctx = NULL;
333
334 if_ctx = eloop_ctx;
335
336 wpa_printf(MSG_ERROR,
337 "%s: Scan timeout - try to abort it",
338 __func__);
339
340 if (wpa_drv_zep_abort_scan(if_ctx, 0) == 0) {
341 return;
342 }
343 }
344
345
wpa_drv_zep_event_proc_scan_start(struct zep_drv_if_ctx * if_ctx)346 void wpa_drv_zep_event_proc_scan_start(struct zep_drv_if_ctx *if_ctx)
347 {
348 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
349 EVENT_SCAN_STARTED,
350 NULL);
351 }
352
353
wpa_drv_zep_event_proc_scan_done(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)354 void wpa_drv_zep_event_proc_scan_done(struct zep_drv_if_ctx *if_ctx,
355 union wpa_event_data *event)
356 {
357 eloop_cancel_timeout(wpa_drv_zep_scan_timeout,
358 if_ctx,
359 if_ctx->supp_if_ctx);
360
361 if_ctx->scan_res2_get_in_prog = false;
362 k_sem_give(&if_ctx->drv_resp_sem);
363
364 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
365 EVENT_SCAN_RESULTS,
366 event);
367 }
368
369
wpa_drv_zep_event_proc_scan_res(struct zep_drv_if_ctx * if_ctx,struct wpa_scan_res * r,bool more_res)370 void wpa_drv_zep_event_proc_scan_res(struct zep_drv_if_ctx *if_ctx,
371 struct wpa_scan_res *r,
372 bool more_res)
373 {
374 struct wpa_scan_res **tmp = NULL;
375 size_t scan_res_len = sizeof(struct wpa_scan_res) + r->ie_len + r->beacon_ie_len;
376
377 if (!if_ctx->scan_res2)
378 return;
379
380 tmp = os_realloc_array(if_ctx->scan_res2->res,
381 if_ctx->scan_res2->num + 1,
382 sizeof(struct wpa_scan_res *));
383
384 if (!tmp) {
385 wpa_printf(MSG_ERROR, "%s: Failed to realloc scan result array", __func__);
386 goto err;
387 }
388
389 struct wpa_scan_res *sr = os_zalloc(scan_res_len);
390 if (!sr) {
391 wpa_printf(MSG_ERROR, "%s: Failed to alloc scan results(%d bytes)", __func__, scan_res_len);
392 if_ctx->scan_res2->res = tmp;
393 goto err;
394 }
395
396 os_memcpy(sr, r, scan_res_len);
397
398 tmp[if_ctx->scan_res2->num++] = sr;
399
400 if_ctx->scan_res2->res = tmp;
401
402 err:
403 if (!more_res) {
404 if_ctx->scan_res2_get_in_prog = false;
405 k_sem_give(&if_ctx->drv_resp_sem);
406 }
407 }
408
409
wpa_drv_zep_event_proc_auth_resp(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)410 void wpa_drv_zep_event_proc_auth_resp(struct zep_drv_if_ctx *if_ctx,
411 union wpa_event_data *event)
412 {
413 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
414 EVENT_AUTH,
415 event);
416 }
417
418
wpa_drv_zep_event_proc_assoc_resp(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event,unsigned int status)419 void wpa_drv_zep_event_proc_assoc_resp(struct zep_drv_if_ctx *if_ctx,
420 union wpa_event_data *event,
421 unsigned int status)
422 {
423 if (status != WLAN_STATUS_SUCCESS) {
424 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
425 EVENT_ASSOC_REJECT,
426 event);
427 } else {
428 if_ctx->associated = true;
429
430 os_memcpy(if_ctx->bssid,
431 event->assoc_info.addr,
432 ETH_ALEN);
433
434 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
435 EVENT_ASSOC,
436 event);
437 }
438 }
439
440
wpa_drv_zep_event_proc_deauth(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event,const struct ieee80211_mgmt * mgmt)441 void wpa_drv_zep_event_proc_deauth(struct zep_drv_if_ctx *if_ctx,
442 union wpa_event_data *event, const struct ieee80211_mgmt *mgmt)
443 {
444 const u8 *bssid = NULL;
445
446 bssid = mgmt->bssid;
447
448 if ((if_ctx->capa.flags & WPA_DRIVER_FLAGS_SME) &&
449 !if_ctx->associated &&
450 os_memcmp(bssid, if_ctx->auth_bssid, ETH_ALEN) != 0 &&
451 os_memcmp(bssid, if_ctx->auth_attempt_bssid, ETH_ALEN) != 0 &&
452 os_memcmp(bssid, if_ctx->prev_bssid, ETH_ALEN) == 0)
453 {
454 /*
455 * Avoid issues with some roaming cases where
456 * disconnection event for the old AP may show up after
457 * we have started connection with the new AP.
458 * In case of locally generated event clear
459 * ignore_next_local_deauth as well, to avoid next local
460 * deauth event be wrongly ignored.
461 */
462 wpa_printf(MSG_DEBUG,
463 "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
464 MAC2STR(bssid),
465 MAC2STR(if_ctx->auth_attempt_bssid));
466 return;
467 }
468 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
469 EVENT_DEAUTH,
470 event);
471 }
472
473
wpa_drv_zep_event_proc_disassoc(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)474 void wpa_drv_zep_event_proc_disassoc(struct zep_drv_if_ctx *if_ctx,
475 union wpa_event_data *event)
476 {
477 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
478 EVENT_DISASSOC,
479 event);
480 }
481
wpa_drv_zep_event_mgmt_tx_status(struct zep_drv_if_ctx * if_ctx,const u8 * frame,size_t len,bool ack)482 static void wpa_drv_zep_event_mgmt_tx_status(struct zep_drv_if_ctx *if_ctx,
483 const u8 *frame, size_t len, bool ack)
484 {
485 union wpa_event_data event;
486 const struct ieee80211_hdr *hdr;
487 u16 fc;
488
489 wpa_printf(MSG_DEBUG, "wpa_supp: Frame TX status event");
490
491 hdr = (const struct ieee80211_hdr *) frame;
492 fc = le_to_host16(hdr->frame_control);
493
494 os_memset(&event, 0, sizeof(event));
495 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
496 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
497 event.tx_status.dst = hdr->addr1;
498 event.tx_status.data = frame;
499 event.tx_status.data_len = len;
500 event.tx_status.ack = ack;
501
502 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
503 EVENT_TX_STATUS,
504 &event);
505 }
506
wpa_drv_zep_event_proc_unprot_deauth(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)507 static void wpa_drv_zep_event_proc_unprot_deauth(struct zep_drv_if_ctx *if_ctx,
508 union wpa_event_data *event)
509 {
510 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
511 EVENT_UNPROT_DEAUTH,
512 event);
513 }
514
wpa_drv_zep_event_proc_unprot_disassoc(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)515 static void wpa_drv_zep_event_proc_unprot_disassoc(struct zep_drv_if_ctx *if_ctx,
516 union wpa_event_data *event)
517 {
518 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
519 EVENT_UNPROT_DISASSOC,
520 event);
521 }
522
523 struct phy_info_arg {
524 u16 *num_modes;
525 struct hostapd_hw_modes *modes;
526 int last_mode, last_chan_idx;
527 int failed;
528 u8 dfs_domain;
529 };
530
phy_info_freq_cfg(struct hostapd_hw_modes * mode,struct hostapd_channel_data * chan,struct wpa_supp_event_channel * chnl_info)531 static void phy_info_freq_cfg(struct hostapd_hw_modes *mode,
532 struct hostapd_channel_data *chan,
533 struct wpa_supp_event_channel *chnl_info)
534 {
535 u8 channel = 0;
536
537 chan->freq = chnl_info->center_frequency;
538 chan->flag = 0;
539 chan->allowed_bw = ~0;
540 chan->dfs_cac_ms = 0;
541
542 if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES) {
543 chan->chan = channel;
544 }
545
546 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_DISABLED)
547 chan->flag |= HOSTAPD_CHAN_DISABLED;
548 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_IR)
549 chan->flag |= HOSTAPD_CHAN_NO_IR;
550 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_RADAR)
551 chan->flag |= HOSTAPD_CHAN_RADAR;
552 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_INDOOR_ONLY)
553 chan->flag |= HOSTAPD_CHAN_INDOOR_ONLY;
554 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_GO_CONCURRENT)
555 chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT;
556 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_10MHZ)
557 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_10;
558 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_20MHZ)
559 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_20;
560 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_HT40_PLUS)
561 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40P;
562 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_HT40_MINUS)
563 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40M;
564 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_80MHZ)
565 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_80;
566 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_160MHZ)
567 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160;
568
569 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_DFS_CAC_TIME_VALID) {
570 chan->dfs_cac_ms = (chnl_info->wpa_supp_time);
571 }
572
573 /* Other elements are not present */
574 chan->wmm_rules_valid = 0;
575 chan->wmm_rules_valid = 0;
576 }
577
578
phy_info_freqs_cfg(struct phy_info_arg * phy_info,struct hostapd_hw_modes * mode,struct wpa_supp_event_supported_band * band_info)579 static int phy_info_freqs_cfg(struct phy_info_arg *phy_info,
580 struct hostapd_hw_modes *mode,
581 struct wpa_supp_event_supported_band *band_info)
582 {
583 int new_channels = 0;
584 struct hostapd_channel_data *channel = NULL;
585 int idx;
586
587 if (!phy_info || !mode || !band_info)
588 return -1;
589
590 new_channels = band_info->wpa_supp_n_channels;
591 if (!new_channels)
592 return 0;
593
594 channel = os_realloc_array(mode->channels,
595 mode->num_channels + new_channels,
596 sizeof(struct hostapd_channel_data));
597 if (!channel)
598 return -1;
599
600 mode->channels = channel;
601 mode->num_channels += new_channels;
602
603 idx = phy_info->last_chan_idx;
604
605 for (int i = 0; i < new_channels; i++) {
606 phy_info_freq_cfg(mode, &mode->channels[idx], &band_info->channels[i]);
607 idx++;
608 }
609
610 phy_info->last_chan_idx = idx;
611
612 return 0;
613 }
614
phy_info_rates_cfg(struct hostapd_hw_modes * mode,struct wpa_supp_event_supported_band * band_info)615 static int phy_info_rates_cfg(struct hostapd_hw_modes *mode,
616 struct wpa_supp_event_supported_band *band_info)
617 {
618 int idx;
619
620 if (!mode || !band_info)
621 return -1;
622
623 mode->num_rates = band_info->wpa_supp_n_bitrates;
624 if (!mode->num_rates)
625 return 0;
626
627 mode->rates = os_calloc(mode->num_rates, sizeof(int));
628 if (!mode->rates)
629 return -1;
630
631 idx = 0;
632
633 for (int i = 0; i < mode->num_rates; i++) {
634 if (!band_info->bitrates[i].wpa_supp_bitrate)
635 continue;
636 mode->rates[idx] = band_info->bitrates[i].wpa_supp_bitrate;
637 idx++;
638 }
639
640 return 0;
641 }
642
643
644
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)645 static void phy_info_ht_capa_cfg(struct hostapd_hw_modes *mode, u16 capa,
646 u8 ampdu_factor,
647 u8 ampdu_density,
648 struct wpa_supp_event_mcs_info *mcs_set)
649 {
650 if (capa)
651 mode->ht_capab = (capa);
652
653 if (ampdu_factor)
654 mode->a_mpdu_params |= (ampdu_factor) & WPA_SUPP_AMPDU_FACTOR_MASK;
655
656 if (ampdu_density)
657 mode->a_mpdu_params |= (ampdu_density) << WPA_SUPP_AMPDU_DENSITY_SHIFT;
658
659 if (mcs_set) {
660 os_memcpy(mode->mcs_set, mcs_set, sizeof(*mcs_set));
661 }
662
663 }
664
phy_info_vht_capa_cfg(struct hostapd_hw_modes * mode,unsigned int capa,struct wpa_supp_event_vht_mcs_info * vht_mcs_set)665 static void phy_info_vht_capa_cfg(struct hostapd_hw_modes *mode,
666 unsigned int capa,
667 struct wpa_supp_event_vht_mcs_info *vht_mcs_set)
668 {
669 if (capa)
670 mode->vht_capab = (capa);
671
672 if (vht_mcs_set) {
673 os_memcpy(mode->vht_mcs_set, vht_mcs_set, 8);
674 }
675 }
676
phy_info_band_cfg(struct phy_info_arg * phy_info,struct wpa_supp_event_supported_band * band_info)677 static int phy_info_band_cfg(struct phy_info_arg *phy_info,
678 struct wpa_supp_event_supported_band *band_info)
679 {
680 struct hostapd_hw_modes *mode;
681 int ret;
682
683 if (phy_info->last_mode != band_info->band) {
684 mode = os_realloc_array(phy_info->modes,
685 *phy_info->num_modes + 1,
686 sizeof(*mode));
687 if (!mode) {
688 phy_info->failed = 1;
689 return -1;
690 }
691
692 phy_info->modes = mode;
693
694 mode = &phy_info->modes[*(phy_info->num_modes)];
695
696 os_memset(mode, 0, sizeof(*mode));
697
698 mode->mode = NUM_HOSTAPD_MODES;
699 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
700 HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
701
702 /*
703 * Unsupported VHT MCS stream is defined as value 3, so the VHT
704 * MCS RX/TX map must be initialized with 0xffff to mark all 8
705 * possible streams as unsupported. This will be overridden if
706 * driver advertises VHT support.
707 */
708 mode->vht_mcs_set[0] = 0xff;
709 mode->vht_mcs_set[1] = 0xff;
710 mode->vht_mcs_set[4] = 0xff;
711 mode->vht_mcs_set[5] = 0xff;
712
713 *(phy_info->num_modes) += 1;
714
715 phy_info->last_mode = band_info->band;
716 phy_info->last_chan_idx = 0;
717 }
718 else
719 mode = &phy_info->modes[*(phy_info->num_modes) - 1];
720
721 phy_info_ht_capa_cfg(mode, band_info->ht_cap.wpa_supp_cap,
722 band_info->ht_cap.wpa_supp_ampdu_factor,
723 band_info->ht_cap.wpa_supp_ampdu_density,
724 &band_info->ht_cap.mcs);
725
726 phy_info_vht_capa_cfg(mode, band_info->vht_cap.wpa_supp_cap,
727 &band_info->vht_cap.vht_mcs);
728
729 ret = phy_info_freqs_cfg(phy_info, mode, band_info);
730
731 if (ret == 0)
732 ret = phy_info_rates_cfg(mode, band_info);
733
734 if (ret != 0) {
735 phy_info->failed = 1;
736 return ret;
737 }
738
739 return 0;
740 }
741
wpa_drv_zep_event_get_wiphy(struct zep_drv_if_ctx * if_ctx,void * band_info)742 static void wpa_drv_zep_event_get_wiphy(struct zep_drv_if_ctx *if_ctx, void *band_info)
743 {
744 if (!band_info) {
745 /* Done with all bands */
746 k_sem_give(&if_ctx->drv_resp_sem);
747 return;
748 }
749
750 phy_info_band_cfg(if_ctx->phy_info_arg, band_info);
751 }
752
wpa_drv_register_frame(struct zep_drv_if_ctx * if_ctx,u16 type,const u8 * match,size_t match_len,bool multicast)753 static int wpa_drv_register_frame(struct zep_drv_if_ctx *if_ctx,
754 u16 type, const u8 *match, size_t match_len,
755 bool multicast)
756 {
757 const struct zep_wpa_supp_dev_ops *dev_ops;
758
759 dev_ops = get_dev_ops(if_ctx->dev_ctx);
760 if (!dev_ops->register_frame)
761 return -1;
762
763 return dev_ops->register_frame(if_ctx->dev_priv, type, match, match_len, false);
764 }
765
wpa_drv_register_action_frame(struct zep_drv_if_ctx * if_ctx,const u8 * match,size_t match_len)766 static int wpa_drv_register_action_frame(struct zep_drv_if_ctx *if_ctx,
767 const u8 *match, size_t match_len)
768 {
769 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
770
771 return wpa_drv_register_frame(if_ctx, type, match, match_len, false);
772 }
773
wpa_drv_mgmt_subscribe_non_ap(struct zep_drv_if_ctx * if_ctx)774 static int wpa_drv_mgmt_subscribe_non_ap(struct zep_drv_if_ctx *if_ctx)
775 {
776 int ret = 0;
777
778 /* WNM - BSS Transition Management Request */
779 if (wpa_drv_register_action_frame(if_ctx, (u8 *)"\x0a\x07", 2) < 0)
780 ret = -1;
781
782 /* Radio Measurement - Neighbor Report Response */
783 if (wpa_drv_register_action_frame(if_ctx, (u8 *)"\x05\x05", 2) < 0)
784 ret = -1;
785
786 /* Radio Measurement - Radio Measurement Request */
787 if (wpa_drv_register_action_frame(if_ctx, (u8 *)"\x05\x00", 2) < 0)
788 ret = -1;
789
790 return ret;
791 }
792
wpa_drv_zep_event_mgmt_rx(struct zep_drv_if_ctx * if_ctx,char * frame,int frame_len,int frequency,int rx_signal_dbm)793 static void wpa_drv_zep_event_mgmt_rx(struct zep_drv_if_ctx *if_ctx,
794 char *frame, int frame_len,
795 int frequency, int rx_signal_dbm)
796 {
797 const struct ieee80211_mgmt *mgmt;
798
799 union wpa_event_data event;
800 u16 fc, stype;
801 int rx_freq = 0;
802
803 wpa_printf(MSG_MSGDUMP, "wpa_supp: Frame event");
804 mgmt = (const struct ieee80211_mgmt *)frame;
805
806 if (frame_len < 24) {
807 wpa_printf(MSG_DEBUG, "wpa_supp: Too short management frame");
808 return;
809 }
810
811 fc = le_to_host16(mgmt->frame_control);
812 stype = WLAN_FC_GET_STYPE(fc);
813
814 os_memset(&event, 0, sizeof(event));
815
816 if (frequency) {
817 event.rx_mgmt.freq = frequency;
818 rx_freq = event.rx_mgmt.freq;
819 }
820
821 event.rx_mgmt.frame = frame;
822 event.rx_mgmt.frame_len = frame_len;
823 event.rx_mgmt.ssi_signal = rx_signal_dbm;
824
825 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx, EVENT_RX_MGMT, &event);
826 }
827
828 static struct hostapd_hw_modes *
wpa_driver_wpa_supp_postprocess_modes(struct hostapd_hw_modes * modes,u16 * num_modes)829 wpa_driver_wpa_supp_postprocess_modes(struct hostapd_hw_modes *modes,
830 u16 *num_modes)
831 {
832 u16 m;
833 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
834 int i, mode11g_idx = -1;
835
836 /* heuristic to set up modes */
837 for (m = 0; m < *num_modes; m++) {
838 if (!modes[m].num_channels)
839 continue;
840 if (modes[m].channels[0].freq < 4000) {
841 modes[m].mode = HOSTAPD_MODE_IEEE80211B;
842 for (i = 0; i < modes[m].num_rates; i++) {
843 if (modes[m].rates[i] > 200) {
844 modes[m].mode = HOSTAPD_MODE_IEEE80211G;
845 break;
846 }
847 }
848 } else if (modes[m].channels[0].freq > 50000)
849 modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
850 else
851 modes[m].mode = HOSTAPD_MODE_IEEE80211A;
852 }
853
854 /* If only 802.11g mode is included, use it to construct matching
855 * 802.11b mode data. */
856
857 for (m = 0; m < *num_modes; m++) {
858 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
859 return modes; /* 802.11b already included */
860 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
861 mode11g_idx = m;
862 }
863
864 if (mode11g_idx < 0)
865 return modes; /* 2.4 GHz band not supported at all */
866
867 nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
868 if (nmodes == NULL)
869 return modes; /* Could not add 802.11b mode */
870
871 mode = &nmodes[*num_modes];
872 os_memset(mode, 0, sizeof(*mode));
873 (*num_modes)++;
874 modes = nmodes;
875
876 mode->mode = HOSTAPD_MODE_IEEE80211B;
877 mode11g = &modes[mode11g_idx];
878 mode->num_channels = mode11g->num_channels;
879 mode->channels = os_memdup(mode11g->channels,
880 mode11g->num_channels *
881 sizeof(struct hostapd_channel_data));
882 if (mode->channels == NULL) {
883 (*num_modes)--;
884 return modes; /* Could not add 802.11b mode */
885 }
886
887 mode->num_rates = 0;
888 mode->rates = os_malloc(4 * sizeof(int));
889 if (mode->rates == NULL) {
890 os_free(mode->channels);
891 (*num_modes)--;
892 return modes; /* Could not add 802.11b mode */
893 }
894
895 for (i = 0; i < mode11g->num_rates; i++) {
896 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
897 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
898 continue;
899 mode->rates[mode->num_rates] = mode11g->rates[i];
900 mode->num_rates++;
901 if (mode->num_rates == 4)
902 break;
903 }
904
905 if (mode->num_rates == 0) {
906 os_free(mode->channels);
907 os_free(mode->rates);
908 (*num_modes)--;
909 return modes; /* No 802.11b rates */
910 }
911
912 wpa_printf(MSG_DEBUG, "wpa_supp: Added 802.11b mode based on 802.11g "
913 "information");
914
915 return modes;
916 }
917
wpa_drv_zep_get_hw_feature_data(void * priv,u16 * num_modes,u16 * flags,u8 * dfs_domain)918 struct hostapd_hw_modes *wpa_drv_zep_get_hw_feature_data(void *priv,
919 u16 *num_modes,
920 u16 *flags, u8 *dfs_domain)
921 {
922 struct zep_drv_if_ctx *if_ctx = NULL;
923 const struct zep_wpa_supp_dev_ops *dev_ops;
924 struct hostapd_hw_modes *modes = NULL;
925 int ret = -1;
926
927 if_ctx = priv;
928
929 dev_ops = get_dev_ops(if_ctx->dev_ctx);
930 if (!dev_ops) {
931 wpa_printf(MSG_ERROR, "%s:Failed to get dev_ops handle", __func__);
932 goto out;
933 }
934
935 if (!dev_ops->get_wiphy) {
936 wpa_printf(MSG_ERROR, "%s: No op registered for get_wiphy", __func__);
937 goto out;
938 }
939
940 struct phy_info_arg result = {
941 .num_modes = num_modes,
942 .modes = NULL,
943 .last_mode = -1,
944 .failed = 0,
945 .dfs_domain = 0,
946 };
947
948 *num_modes = 0;
949 *flags = 0;
950 *dfs_domain = 0;
951
952 if_ctx->phy_info_arg = &result;
953
954 k_sem_reset(&if_ctx->drv_resp_sem);
955
956 ret = dev_ops->get_wiphy(if_ctx->dev_priv);
957 if (ret < 0) {
958 return NULL;
959 }
960
961 k_sem_take(&if_ctx->drv_resp_sem, K_SECONDS(GET_WIPHY_TIMEOUT));
962
963 if (!result.modes) {
964 return NULL;
965 }
966
967 *dfs_domain = result.dfs_domain;
968
969 modes = wpa_driver_wpa_supp_postprocess_modes(result.modes,
970 num_modes);
971
972 out:
973 return modes;
974 }
975
wpa_drv_zep_global_init(void * ctx)976 static void *wpa_drv_zep_global_init(void *ctx)
977 {
978 struct zep_drv_ctx *drv_ctx = NULL;
979
980 drv_ctx = os_zalloc(sizeof(*drv_ctx));
981 if (!drv_ctx) {
982 return NULL;
983 }
984
985 drv_ctx->supp_ctx = ctx;
986
987 return drv_ctx;
988 }
989
990
wpa_drv_zep_global_deinit(void * priv)991 static void wpa_drv_zep_global_deinit(void *priv)
992 {
993 struct zep_drv_ctx *drv_ctx = priv;
994
995 if (!drv_ctx) {
996 return;
997 }
998
999 os_free(drv_ctx);
1000 }
1001
1002
1003 /**
1004 * wpa_driver_zep_init - Initialize Zephyr driver interface
1005 * @ctx: Context to be used when calling wpa_supplicant functions,
1006 * e.g., wpa_supplicant_event_wrapper()
1007 * @ifname: Interface name, e.g., wlan0
1008 * @global_priv: private driver global data from global_init()
1009 *
1010 * Returns: Pointer to private data, %NULL on failure
1011 */
wpa_drv_zep_init(void * ctx,const char * ifname,void * global_priv)1012 static void *wpa_drv_zep_init(void *ctx,
1013 const char *ifname,
1014 void *global_priv)
1015 {
1016 struct zep_drv_if_ctx *if_ctx = NULL;
1017 const struct zep_wpa_supp_dev_ops *dev_ops;
1018 struct zep_wpa_supp_dev_callbk_fns callbk_fns;
1019 const struct device *device;
1020 struct net_if *iface;
1021
1022 iface = net_if_get_by_index(net_if_get_by_name(ifname));
1023
1024 device = net_if_get_device(iface);
1025 if (!device) {
1026 wpa_printf(MSG_ERROR, "%s: Interface %s not found", __func__, ifname);
1027 goto out;
1028 }
1029
1030 if_ctx = os_zalloc(sizeof(*if_ctx));
1031 if (if_ctx == NULL) {
1032 goto out;
1033 }
1034
1035 if_ctx->supp_if_ctx = ctx;
1036 if_ctx->iface = iface;
1037 if_ctx->dev_ctx = device;
1038 if_ctx->drv_ctx = global_priv;
1039
1040 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1041 if (!dev_ops->init) {
1042 wpa_printf(MSG_ERROR,
1043 "%s: No op registered for init",
1044 __func__);
1045 os_free(if_ctx);
1046 if_ctx = NULL;
1047 goto out;
1048 }
1049
1050 os_memset(&callbk_fns, 0, sizeof(callbk_fns));
1051
1052 callbk_fns.scan_start = wpa_drv_zep_event_proc_scan_start;
1053 callbk_fns.scan_done = wpa_drv_zep_event_proc_scan_done;
1054 callbk_fns.scan_res = wpa_drv_zep_event_proc_scan_res;
1055 callbk_fns.auth_resp = wpa_drv_zep_event_proc_auth_resp;
1056 callbk_fns.assoc_resp = wpa_drv_zep_event_proc_assoc_resp;
1057 callbk_fns.deauth = wpa_drv_zep_event_proc_deauth;
1058 callbk_fns.disassoc = wpa_drv_zep_event_proc_disassoc;
1059 callbk_fns.mgmt_tx_status = wpa_drv_zep_event_mgmt_tx_status;
1060 callbk_fns.unprot_deauth = wpa_drv_zep_event_proc_unprot_deauth;
1061 callbk_fns.unprot_disassoc = wpa_drv_zep_event_proc_unprot_disassoc;
1062 callbk_fns.get_wiphy_res = wpa_drv_zep_event_get_wiphy;
1063 callbk_fns.mgmt_rx = wpa_drv_zep_event_mgmt_rx;
1064 callbk_fns.mac_changed = wpa_drv_zep_event_mac_changed;
1065
1066 if_ctx->dev_priv = dev_ops->init(if_ctx,
1067 ifname,
1068 &callbk_fns);
1069 if (!if_ctx->dev_priv) {
1070 wpa_printf(MSG_ERROR,
1071 "%s: Failed to initialize the interface",
1072 __func__);
1073 os_free(if_ctx);
1074 if_ctx = NULL;
1075 goto out;
1076 }
1077
1078 k_sem_init(&if_ctx->drv_resp_sem, 0, 1);
1079
1080 wpa_drv_mgmt_subscribe_non_ap(if_ctx);
1081
1082 out:
1083 return if_ctx;
1084 }
1085
1086
wpa_drv_zep_deinit(void * priv)1087 static void wpa_drv_zep_deinit(void *priv)
1088 {
1089 struct zep_drv_if_ctx *if_ctx = NULL;
1090 const struct zep_wpa_supp_dev_ops *dev_ops;
1091
1092 if_ctx = priv;
1093
1094 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1095 if (!dev_ops->deinit) {
1096 wpa_printf(MSG_ERROR, "%s: No op registered for deinit", __func__);
1097 return;
1098 }
1099
1100 dev_ops->deinit(if_ctx->dev_priv);
1101
1102 os_free(if_ctx);
1103 }
1104
1105
wpa_drv_zep_scan2(void * priv,struct wpa_driver_scan_params * params)1106 static int wpa_drv_zep_scan2(void *priv, struct wpa_driver_scan_params *params)
1107 {
1108 struct zep_drv_if_ctx *if_ctx = NULL;
1109 const struct zep_wpa_supp_dev_ops *dev_ops;
1110 int timeout = 0;
1111 int ret = -1;
1112
1113 if (!priv || !params) {
1114 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1115 goto out;
1116 }
1117
1118 if_ctx = priv;
1119 if (if_ctx->scan_res2_get_in_prog) {
1120 wpa_printf(MSG_ERROR, "%s: Scan is already in progress", __func__);
1121 goto out;
1122 }
1123
1124 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1125 if (!dev_ops->scan2) {
1126 wpa_printf(MSG_ERROR, "%s: No op registered for scan2", __func__);
1127 goto out;
1128 }
1129
1130 ret = dev_ops->scan2(if_ctx->dev_priv, params);
1131 if (ret) {
1132 wpa_printf(MSG_ERROR, "%s: scan2 op failed", __func__);
1133 goto out;
1134 }
1135
1136 /* The driver delivers events to notify when scan is
1137 * complete, so use longer timeout to avoid race conditions
1138 * with scanning and following association request.
1139 */
1140 timeout = SCAN_TIMEOUT;
1141
1142 wpa_printf(MSG_DEBUG,
1143 "%s: Scan requested - scan timeout %d seconds",
1144 __func__,
1145 timeout);
1146
1147 eloop_cancel_timeout(wpa_drv_zep_scan_timeout,
1148 if_ctx,
1149 if_ctx->supp_if_ctx);
1150
1151 eloop_register_timeout(timeout,
1152 0,
1153 wpa_drv_zep_scan_timeout,
1154 if_ctx,
1155 if_ctx->supp_if_ctx);
1156
1157 ret = 0;
1158
1159 out:
1160 return ret;
1161 }
1162
1163
1164 /**
1165 * wpa_drv_zep_get_scan_results2 - Fetch the latest scan results
1166 * @priv: Pointer to private data from wpa_drv_zep_init()
1167 * Returns: Scan results on success, -1 on failure
1168 */
wpa_drv_zep_get_scan_results2(void * priv)1169 struct wpa_scan_results *wpa_drv_zep_get_scan_results2(void *priv)
1170 {
1171 struct zep_drv_if_ctx *if_ctx = NULL;
1172 const struct zep_wpa_supp_dev_ops *dev_ops;
1173 int ret = -1;
1174
1175 if (!priv) {
1176 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1177 goto out;
1178 }
1179
1180 if_ctx = priv;
1181
1182 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1183 if (!dev_ops->get_scan_results2) {
1184 wpa_printf(MSG_ERROR,
1185 "%s: No op registered for scan2",
1186 __func__);
1187 goto out;
1188 }
1189
1190 if_ctx->scan_res2 = os_zalloc(sizeof(*if_ctx->scan_res2));
1191 if (!if_ctx->scan_res2) {
1192 wpa_printf(MSG_ERROR, "%s: Failed to alloc memory for scan results", __func__);
1193 goto out;
1194 }
1195
1196 if_ctx->scan_res2_get_in_prog = true;
1197 k_sem_reset(&if_ctx->drv_resp_sem);
1198
1199 ret = dev_ops->get_scan_results2(if_ctx->dev_priv);
1200 if (ret) {
1201 wpa_printf(MSG_ERROR, "%s: get_scan_results2 op failed", __func__);
1202 if_ctx->scan_res2_get_in_prog = false;
1203 goto out;
1204 }
1205
1206 k_sem_take(&if_ctx->drv_resp_sem, K_SECONDS(SCAN_TIMEOUT));
1207
1208 if (if_ctx->scan_res2_get_in_prog) {
1209 wpa_printf(MSG_ERROR, "%s: Timed out waiting for scan results", __func__);
1210 /* If this is a temporary issue, then we can allow subsequent scans */
1211 if_ctx->scan_res2_get_in_prog = false;
1212 ret = -1;
1213 goto out;
1214 }
1215
1216 ret = 0;
1217 out:
1218 if (ret == -1) {
1219 if (if_ctx->scan_res2) {
1220 wpa_scan_results_free(if_ctx->scan_res2);
1221 if_ctx->scan_res2 = NULL;
1222 }
1223 }
1224
1225 return if_ctx->scan_res2;
1226 }
1227
1228
wpa_drv_zep_deauthenticate(void * priv,const u8 * addr,u16 reason_code)1229 static int wpa_drv_zep_deauthenticate(void *priv, const u8 *addr,
1230 u16 reason_code)
1231 {
1232 struct zep_drv_if_ctx *if_ctx = NULL;
1233 const struct zep_wpa_supp_dev_ops *dev_ops;
1234 int ret = -1;
1235
1236 if ((!priv) || (!addr)) {
1237 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1238 goto out;
1239 }
1240
1241 if_ctx = priv;
1242
1243 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1244 ret = dev_ops->deauthenticate(if_ctx->dev_priv, addr, reason_code);
1245 if (ret) {
1246 wpa_printf(MSG_ERROR, "%s: deauthenticate op failed", __func__);
1247 goto out;
1248 }
1249
1250 ret = 0;
1251 out:
1252 return ret;
1253 }
1254
1255
wpa_drv_zep_authenticate(void * priv,struct wpa_driver_auth_params * params)1256 static int wpa_drv_zep_authenticate(void *priv,
1257 struct wpa_driver_auth_params *params)
1258 {
1259 struct zep_drv_if_ctx *if_ctx = NULL;
1260 const struct zep_wpa_supp_dev_ops *dev_ops;
1261 struct wpa_bss *curr_bss;
1262 int ret = -1;
1263
1264 if ((!priv) || (!params)) {
1265 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1266 goto out;
1267 }
1268
1269 if_ctx = priv;
1270
1271 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1272
1273 os_memcpy(if_ctx->ssid, params->ssid, params->ssid_len);
1274
1275 if_ctx->ssid_len = params->ssid_len;
1276
1277 curr_bss = wpa_bss_get(if_ctx->supp_if_ctx, params->bssid, params->ssid, params->ssid_len);
1278 if (!curr_bss) {
1279 wpa_printf(MSG_ERROR, "%s: Failed to get BSS", __func__);
1280 ret = -1;
1281 goto out;
1282 }
1283
1284 if (params->bssid)
1285 os_memcpy(if_ctx->auth_attempt_bssid, params->bssid, ETH_ALEN);
1286
1287 if (if_ctx->associated)
1288 os_memcpy(if_ctx->prev_bssid, if_ctx->bssid, ETH_ALEN);
1289
1290 os_memset(if_ctx->auth_bssid, 0, ETH_ALEN);
1291
1292 if_ctx->associated = false;
1293
1294 ret = dev_ops->authenticate(if_ctx->dev_priv, params, curr_bss);
1295 if (ret) {
1296 wpa_printf(MSG_ERROR, "%s: authenticate op failed", __func__);
1297 goto out;
1298 }
1299
1300 ret = 0;
1301 out:
1302 return ret;
1303 }
1304
1305
wpa_drv_zep_associate(void * priv,struct wpa_driver_associate_params * params)1306 static int wpa_drv_zep_associate(void *priv,
1307 struct wpa_driver_associate_params *params)
1308 {
1309 struct zep_drv_if_ctx *if_ctx = NULL;
1310 const struct zep_wpa_supp_dev_ops *dev_ops;
1311 int ret = -1;
1312
1313 if ((!priv) || (!params)) {
1314 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1315 goto out;
1316 }
1317
1318 if_ctx = priv;
1319
1320 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1321
1322 if (IS_ENABLED(CONFIG_AP) && params->mode == IEEE80211_MODE_AP) {
1323 ret = dev_ops->init_ap(if_ctx->dev_priv,
1324 params);
1325 } else if (params->mode == IEEE80211_MODE_INFRA) {
1326 ret = dev_ops->associate(if_ctx->dev_priv,
1327 params);
1328 } else {
1329 wpa_printf(MSG_ERROR, "%s: Unsupported mode", __func__);
1330 goto out;
1331 }
1332
1333 if (ret) {
1334 wpa_printf(MSG_ERROR, "%s: associate op failed", __func__);
1335 goto out;
1336 }
1337
1338 ret = 0;
1339 out:
1340 return ret;
1341 }
1342
1343
_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)1344 static int _wpa_drv_zep_set_key(void *priv,
1345 const char *ifname,
1346 enum wpa_alg alg,
1347 const u8 *addr,
1348 int key_idx,
1349 int set_tx,
1350 const u8 *seq,
1351 size_t seq_len,
1352 const u8 *key,
1353 size_t key_len,
1354 enum key_flag key_flag)
1355 {
1356 struct zep_drv_if_ctx *if_ctx = NULL;
1357 const struct zep_wpa_supp_dev_ops *dev_ops;
1358 struct net_if *iface;
1359 int ret = -1;
1360
1361 if (!priv) {
1362 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1363 goto out;
1364 }
1365 if ((alg != WPA_ALG_NONE) && !key) {
1366 wpa_printf(MSG_ERROR,
1367 "%s: Missing mandatory params",
1368 __func__);
1369 goto out;
1370 }
1371
1372 if_ctx = priv;
1373 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1374
1375 iface = net_if_lookup_by_dev(if_ctx->dev_ctx);
1376 if (!iface) {
1377 wpa_printf(MSG_ERROR, "%s: Failed to get iface", __func__);
1378 goto out;
1379 }
1380
1381 if (!net_if_is_up(iface)) {
1382 goto out;
1383 }
1384
1385 wpa_printf(MSG_DEBUG, "%s: priv:%p alg %d addr %p key_idx %d set_tx %d seq %p "
1386 "seq_len %d key %p key_len %d key_flag %x",
1387 __func__,
1388 if_ctx->dev_priv,
1389 alg, addr,
1390 key_idx,
1391 set_tx,
1392 seq,
1393 seq_len,
1394 key,
1395 key_len,
1396 key_flag);
1397
1398 ret = dev_ops->set_key(if_ctx->dev_priv,
1399 ifname,
1400 alg,
1401 addr,
1402 key_idx,
1403 set_tx,
1404 seq,
1405 seq_len,
1406 key,
1407 key_len,
1408 key_flag);
1409 if (ret) {
1410 wpa_printf(MSG_ERROR, "%s: set_key op failed", __func__);
1411 goto out;
1412 }
1413 out:
1414 return ret;
1415 }
1416
1417
wpa_drv_zep_set_key(void * priv,struct wpa_driver_set_key_params * params)1418 static int wpa_drv_zep_set_key(void* priv,
1419 struct wpa_driver_set_key_params *params)
1420 {
1421 return _wpa_drv_zep_set_key(priv,
1422 params->ifname,
1423 params->alg,
1424 params->addr,
1425 params->key_idx,
1426 params->set_tx,
1427 params->seq,
1428 params->seq_len,
1429 params->key,
1430 params->key_len,
1431 params->key_flag);
1432 }
1433
1434
wpa_drv_zep_get_capa(void * priv,struct wpa_driver_capa * capa)1435 static int wpa_drv_zep_get_capa(void *priv, struct wpa_driver_capa *capa)
1436 {
1437 struct zep_drv_if_ctx *if_ctx = NULL;
1438 const struct zep_wpa_supp_dev_ops *dev_ops;
1439 int ret = -1;
1440
1441 if ((!priv) || (!capa)) {
1442 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1443 goto out;
1444 }
1445
1446 if_ctx = priv;
1447 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1448
1449 if (!dev_ops->get_capa) {
1450 wpa_printf(MSG_ERROR, "%s: get_capa op not supported", __func__);
1451 goto out;
1452 }
1453
1454 ret = dev_ops->get_capa(if_ctx->dev_priv, capa);
1455 if (ret) {
1456 wpa_printf(MSG_ERROR, "%s: get_capa op failed", __func__);
1457 goto out;
1458 }
1459
1460 ret = 0;
1461
1462 if_ctx->capa = *capa;
1463
1464 out:
1465 return ret;
1466 }
1467
1468
wpa_drv_zep_get_bssid(void * priv,u8 * bssid)1469 static int wpa_drv_zep_get_bssid(void *priv, u8 *bssid)
1470 {
1471 struct zep_drv_if_ctx *if_ctx = NULL;
1472
1473 if_ctx = priv;
1474
1475 os_memcpy(bssid, if_ctx->bssid, ETH_ALEN);
1476
1477 return 0;
1478 }
1479
1480
wpa_drv_zep_get_ssid(void * priv,u8 * ssid)1481 static int wpa_drv_zep_get_ssid(void *priv,
1482 u8 *ssid)
1483 {
1484 struct zep_drv_if_ctx *if_ctx = NULL;
1485
1486 if_ctx = priv;
1487
1488 wpa_printf(MSG_DEBUG,
1489 "%s: SSID size: %d",
1490 __func__,
1491 if_ctx->ssid_len);
1492
1493 os_memcpy(ssid, if_ctx->ssid, if_ctx->ssid_len);
1494
1495 return if_ctx->ssid_len;
1496 }
1497
1498
wpa_drv_zep_set_supp_port(void * priv,int authorized)1499 static int wpa_drv_zep_set_supp_port(void *priv,
1500 int authorized)
1501 {
1502 struct zep_drv_if_ctx *if_ctx = NULL;
1503 const struct zep_wpa_supp_dev_ops *dev_ops;
1504 struct net_if *iface = NULL;
1505
1506 int ret;
1507
1508 if_ctx = priv;
1509
1510 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1511
1512 iface = net_if_lookup_by_dev(if_ctx->dev_ctx);
1513
1514 ret = dev_ops->set_supp_port(if_ctx->dev_priv,
1515 authorized,
1516 if_ctx->bssid);
1517
1518 #ifdef CONFIG_NET_DHCPV4
1519 if (authorized) {
1520 net_dhcpv4_restart(iface);
1521 }
1522 #endif
1523
1524 return ret;
1525 }
1526
1527
wpa_drv_zep_signal_poll(void * priv,struct wpa_signal_info * si)1528 static int wpa_drv_zep_signal_poll(void *priv, struct wpa_signal_info *si)
1529 {
1530 struct zep_drv_if_ctx *if_ctx = NULL;
1531 const struct zep_wpa_supp_dev_ops *dev_ops;
1532 int ret = -1;
1533
1534 if (!priv) {
1535 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1536 goto out;
1537 }
1538
1539 if (!si) {
1540 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1541 goto out;
1542 }
1543
1544 if_ctx = priv;
1545 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1546
1547 os_memset(si, 0, sizeof(*si));
1548
1549 if (dev_ops && dev_ops->signal_poll) {
1550 ret = dev_ops->signal_poll(if_ctx->dev_priv, si, if_ctx->bssid);
1551 if (ret) {
1552 wpa_printf(MSG_ERROR, "%s: Signal polling failed: %d", __func__, ret);
1553 goto out;
1554 }
1555 } else {
1556 wpa_printf(MSG_ERROR, "%s: Signal polling not supported", __func__);
1557 goto out;
1558 }
1559
1560 out:
1561 return ret;
1562 }
1563
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)1564 static int wpa_drv_zep_send_action(void *priv, unsigned int freq,
1565 unsigned int wait_time,
1566 const u8 *dst, const u8 *src,
1567 const u8 *bssid,
1568 const u8 *data, size_t data_len,
1569 int no_cck)
1570 {
1571 struct zep_drv_if_ctx *if_ctx = NULL;
1572 const struct zep_wpa_supp_dev_ops *dev_ops;
1573 int ret = -1;
1574 u8 *buf;
1575 struct ieee80211_hdr *hdr;
1576
1577 if_ctx = priv;
1578 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1579
1580 wpa_printf(MSG_DEBUG, "wpa_supp: Send Action frame ("
1581 "freq=%u MHz wait=%d ms no_cck=%d)",
1582 freq, wait_time, no_cck);
1583
1584 buf = os_zalloc(24 + data_len);
1585 if (buf == NULL)
1586 return ret;
1587
1588 os_memcpy(buf + 24, data, data_len);
1589
1590 hdr = (struct ieee80211_hdr *)buf;
1591 hdr->frame_control =
1592 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
1593 os_memcpy(hdr->addr1, dst, ETH_ALEN);
1594 os_memcpy(hdr->addr2, src, ETH_ALEN);
1595 os_memcpy(hdr->addr3, bssid, ETH_ALEN);
1596
1597 return dev_ops->send_mlme(if_ctx->dev_priv, buf, 24 + data_len,
1598 0, freq, no_cck, 1,
1599 wait_time, 0);
1600 }
1601
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)1602 static int wpa_drv_zep_get_ext_capab(void *priv, enum wpa_driver_if_type type,
1603 const u8 **ext_capa, const u8 **ext_capa_mask,
1604 unsigned int *ext_capa_len)
1605 {
1606 struct wpa_driver_capa capa;
1607
1608 wpa_drv_zep_get_capa(priv, &capa);
1609
1610 /* By default, use the per-radio values */
1611 *ext_capa = capa.extended_capa;
1612 *ext_capa_mask = capa.extended_capa_mask;
1613 *ext_capa_len = capa.extended_capa_len;
1614
1615 return 0;
1616 }
1617
wpa_drv_zep_get_conn_info(void * priv,struct wpa_conn_info * ci)1618 static int wpa_drv_zep_get_conn_info(void *priv, struct wpa_conn_info *ci)
1619 {
1620 struct zep_drv_if_ctx *if_ctx = NULL;
1621 const struct zep_wpa_supp_dev_ops *dev_ops;
1622 int ret = -1;
1623
1624 if (!priv) {
1625 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1626 goto out;
1627 }
1628
1629 if (!ci) {
1630 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1631 goto out;
1632 }
1633
1634 if_ctx = priv;
1635 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1636
1637 if (!dev_ops) {
1638 wpa_printf(MSG_ERROR, "%s:Failed to get dev_ops handle", __func__);
1639 goto out;
1640 }
1641
1642 if (dev_ops->get_conn_info) {
1643 ret = dev_ops->get_conn_info(if_ctx->dev_priv, ci);
1644 if (ret) {
1645 wpa_printf(MSG_ERROR, "%s: Failed to get connection info: %d", __func__, ret);
1646 goto out;
1647 }
1648 } else {
1649 wpa_printf(MSG_ERROR, "%s: Getting connection info is not supported", __func__);
1650 goto out;
1651 }
1652
1653 out:
1654 return ret;
1655 }
1656
1657 #ifdef CONFIG_AP
register_mgmt_frames_ap(struct zep_drv_if_ctx * if_ctx)1658 static int register_mgmt_frames_ap(struct zep_drv_if_ctx *if_ctx)
1659 {
1660 const struct zep_wpa_supp_dev_ops *dev_ops;
1661 static const int stypes[] = {
1662 WLAN_FC_STYPE_AUTH,
1663 WLAN_FC_STYPE_ASSOC_REQ,
1664 WLAN_FC_STYPE_REASSOC_REQ,
1665 WLAN_FC_STYPE_DISASSOC,
1666 WLAN_FC_STYPE_DEAUTH,
1667 WLAN_FC_STYPE_PROBE_REQ,
1668 };
1669 int i, ret = -1;
1670
1671 if (!if_ctx) {
1672 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1673 goto out;
1674 }
1675
1676 dev_ops = if_ctx->dev_ctx->config;
1677
1678 if (!dev_ops->register_mgmt_frame) {
1679 wpa_printf(MSG_ERROR, "%s: register_mgmt_frame op not supported", __func__);
1680 goto out;
1681 }
1682
1683 for (i = 0; i < ARRAY_SIZE(stypes); i++) {
1684 ret = dev_ops->register_mgmt_frame(if_ctx->dev_priv,
1685 stypes[i] << 4,
1686 0,
1687 NULL);
1688 if (ret) {
1689 wpa_printf(MSG_ERROR, "%s: register_mgmt_frame op failed", __func__);
1690 goto out;
1691 }
1692 }
1693
1694 out:
1695 return ret;
1696 }
1697
wpa_drv_zep_set_ap(void * priv,struct wpa_driver_ap_params * params)1698 static int wpa_drv_zep_set_ap(void *priv,
1699 struct wpa_driver_ap_params *params)
1700 {
1701 struct zep_drv_if_ctx *if_ctx = NULL;
1702 const struct zep_wpa_supp_dev_ops *dev_ops;
1703 int ret = -1;
1704
1705 if ((!priv) || (!params)) {
1706 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1707 goto out;
1708 }
1709
1710 if_ctx = priv;
1711
1712 dev_ops = if_ctx->dev_ctx->config;
1713
1714 if (!if_ctx->beacon_set && !dev_ops->start_ap) {
1715 wpa_printf(MSG_ERROR, "%s: start_ap op not supported", __func__);
1716 goto out;
1717 } else if (if_ctx->beacon_set && !dev_ops->change_beacon) {
1718 wpa_printf(MSG_ERROR, "%s: change_beacon op not supported", __func__);
1719 goto out;
1720 }
1721
1722 if (!if_ctx->beacon_set) {
1723 ret = register_mgmt_frames_ap(if_ctx);
1724 if (ret) {
1725 wpa_printf(MSG_ERROR, "%s: register_mgmt_frames_ap failed", __func__);
1726 goto out;
1727 }
1728 ret = dev_ops->start_ap(if_ctx->dev_priv,
1729 params);
1730 if (ret) {
1731 wpa_printf(MSG_ERROR, "%s: start_ap op failed: %d", __func__, ret);
1732 goto out;
1733 }
1734 } else {
1735 ret = dev_ops->change_beacon(if_ctx->dev_priv,
1736 params);
1737 if (ret) {
1738 wpa_printf(MSG_ERROR, "%s: change_beacon op failed: %d", __func__, ret);
1739 goto out;
1740 }
1741 }
1742
1743 if (!if_ctx->beacon_set) {
1744 if_ctx->beacon_set = true;
1745 }
1746
1747 if_ctx->freq = params->freq->freq;
1748 out:
1749 return ret;
1750 }
1751
wpa_drv_zep_stop_ap(void * priv)1752 int wpa_drv_zep_stop_ap(void *priv)
1753 {
1754 struct zep_drv_if_ctx *if_ctx = NULL;
1755 const struct zep_wpa_supp_dev_ops *dev_ops;
1756 int ret = -1;
1757
1758 if (!priv) {
1759 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1760 goto out;
1761 }
1762
1763 if_ctx = priv;
1764
1765 dev_ops = if_ctx->dev_ctx->config;
1766
1767 if (!dev_ops->stop_ap) {
1768 wpa_printf(MSG_ERROR, "%s: stop_ap op not supported", __func__);
1769 goto out;
1770 }
1771
1772 ret = dev_ops->stop_ap(if_ctx->dev_priv);
1773
1774 if (ret) {
1775 wpa_printf(MSG_ERROR, "%s: stop_ap op failed: %d", __func__, ret);
1776 goto out;
1777 }
1778
1779 if_ctx->freq = 0;
1780 out:
1781 if (if_ctx) {
1782 if_ctx->beacon_set = false;
1783 }
1784 return ret;
1785 }
1786
wpa_drv_zep_deinit_ap(void * priv)1787 int wpa_drv_zep_deinit_ap(void *priv)
1788 {
1789 struct zep_drv_if_ctx *if_ctx = NULL;
1790 const struct zep_wpa_supp_dev_ops *dev_ops;
1791 int ret = -1;
1792
1793 if (!priv) {
1794 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1795 goto out;
1796 }
1797
1798 if_ctx = priv;
1799
1800 dev_ops = if_ctx->dev_ctx->config;
1801
1802 if (!dev_ops->deinit_ap) {
1803 wpa_printf(MSG_ERROR, "%s: deinit_ap op not supported", __func__);
1804 goto out;
1805 }
1806
1807 ret = dev_ops->deinit_ap(if_ctx->dev_priv);
1808
1809 if (ret) {
1810 wpa_printf(MSG_ERROR, "%s: deinit_ap op failed: %d", __func__, ret);
1811 goto out;
1812 }
1813
1814 out:
1815 if (if_ctx) {
1816 if_ctx->beacon_set = false;
1817 }
1818 return ret;
1819 }
1820
wpa_drv_zep_sta_add(void * priv,struct hostapd_sta_add_params * params)1821 int wpa_drv_zep_sta_add(void *priv, struct hostapd_sta_add_params *params)
1822 {
1823 struct zep_drv_if_ctx *if_ctx = priv;
1824 const struct zep_wpa_supp_dev_ops *dev_ops;
1825 int ret = -1;
1826
1827 if ((!priv) || (!params)) {
1828 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1829 goto out;
1830 }
1831
1832 dev_ops = if_ctx->dev_ctx->config;
1833 if (!dev_ops->sta_add) {
1834 wpa_printf(MSG_ERROR, "%s: sta_add op not supported", __func__);
1835 goto out;
1836 }
1837
1838 ret = dev_ops->sta_add(if_ctx->dev_priv, params);
1839 if (ret) {
1840 wpa_printf(MSG_ERROR, "%s: sta_add op failed: %d", __func__, ret);
1841 goto out;
1842 }
1843
1844 out:
1845 return ret;
1846 }
1847
wpa_drv_zep_sta_set_flags(void * priv,const u8 * addr,u32 total_flags,u32 flags_or,u32 flags_and)1848 int wpa_drv_zep_sta_set_flags(void *priv, const u8 *addr, u32 total_flags,
1849 u32 flags_or, u32 flags_and)
1850 {
1851 struct zep_drv_if_ctx *if_ctx = priv;
1852 const struct zep_wpa_supp_dev_ops *dev_ops;
1853 int ret = -1;
1854
1855 if ((!priv) || (!addr)) {
1856 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1857 goto out;
1858 }
1859
1860 dev_ops = if_ctx->dev_ctx->config;
1861 if (!dev_ops->sta_set_flags) {
1862 wpa_printf(MSG_ERROR, "%s: sta_set_flags op not supported",
1863 __func__);
1864 goto out;
1865 }
1866
1867 ret = dev_ops->sta_set_flags(if_ctx->dev_priv, addr, total_flags, flags_or, flags_and);
1868 if (ret) {
1869 wpa_printf(MSG_ERROR, "%s: sta_set_flags op failed: %d", __func__, ret);
1870 goto out;
1871 }
1872
1873 out:
1874 return ret;
1875 }
1876
wpa_drv_zep_sta_deauth(void * priv,const u8 * own_addr,const u8 * addr,u16 reason_code)1877 int wpa_drv_zep_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, u16 reason_code)
1878 {
1879 struct zep_drv_if_ctx *if_ctx = priv;
1880 const struct zep_wpa_supp_dev_ops *dev_ops;
1881 int ret = -1;
1882 struct ieee80211_mgmt mgmt;
1883
1884 if ((!priv) || (!addr)) {
1885 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1886 goto out;
1887 }
1888
1889 dev_ops = if_ctx->dev_ctx->config;
1890
1891 wpa_printf(MSG_DEBUG, "%s: addr %p reason_code %d",
1892 __func__, addr, reason_code);
1893
1894 memset(&mgmt, 0, sizeof(mgmt));
1895 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1896 WLAN_FC_STYPE_DEAUTH);
1897 memcpy(mgmt.da, addr, ETH_ALEN);
1898 memcpy(mgmt.sa, own_addr, ETH_ALEN);
1899 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
1900 mgmt.u.deauth.reason_code = host_to_le16(reason_code);
1901
1902 return wpa_drv_zep_send_mlme(priv, (u8 *) &mgmt,
1903 IEEE80211_HDRLEN +
1904 sizeof(mgmt.u.deauth), 0, if_ctx->freq, 0, 0,
1905 0, 0);
1906 out:
1907 return ret;
1908 }
1909
wpa_drv_zep_sta_disassoc(void * priv,const u8 * own_addr,const u8 * addr,u16 reason_code)1910 int wpa_drv_zep_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, u16 reason_code)
1911 {
1912 struct zep_drv_if_ctx *if_ctx = priv;
1913 const struct zep_wpa_supp_dev_ops *dev_ops;
1914 int ret = -1;
1915 struct ieee80211_mgmt mgmt;
1916
1917 if ((!priv) || (!addr)) {
1918 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1919 goto out;
1920 }
1921
1922 dev_ops = if_ctx->dev_ctx->config;
1923
1924 wpa_printf(MSG_DEBUG, "%s: addr %p reason_code %d",
1925 __func__, addr, reason_code);
1926
1927 memset(&mgmt, 0, sizeof(mgmt));
1928 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1929 WLAN_FC_STYPE_DISASSOC);
1930 memcpy(mgmt.da, addr, ETH_ALEN);
1931 memcpy(mgmt.sa, own_addr, ETH_ALEN);
1932 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
1933 mgmt.u.disassoc.reason_code = host_to_le16(reason_code);
1934
1935 return wpa_drv_zep_send_mlme(priv, (u8 *) &mgmt,
1936 IEEE80211_HDRLEN +
1937 sizeof(mgmt.u.disassoc), 0, if_ctx->freq, 0, 0,
1938 0, 0);
1939 out:
1940 return ret;
1941 }
1942
wpa_drv_zep_sta_remove(void * priv,const u8 * addr)1943 int wpa_drv_zep_sta_remove(void *priv, const u8 *addr)
1944 {
1945 struct zep_drv_if_ctx *if_ctx = priv;
1946 const struct zep_wpa_supp_dev_ops *dev_ops;
1947 int ret = -1;
1948
1949 if ((!priv) || (!addr)) {
1950 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1951 goto out;
1952 }
1953
1954 dev_ops = if_ctx->dev_ctx->config;
1955 if (!dev_ops->sta_remove) {
1956 wpa_printf(MSG_ERROR, "%s: sta_remove op not supported",
1957 __func__);
1958 goto out;
1959 }
1960
1961 ret = dev_ops->sta_remove(if_ctx->dev_priv, addr);
1962 if (ret) {
1963 wpa_printf(MSG_ERROR, "%s: sta_remove op failed: %d", __func__, ret);
1964 goto out;
1965 }
1966
1967 out:
1968 return ret;
1969 }
1970
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)1971 int wpa_drv_zep_send_mlme(void *priv, const u8 *data, size_t data_len, int noack,
1972 unsigned int freq, const u16 *csa_offs, size_t csa_offs_len, int no_encrypt,
1973 unsigned int wait)
1974 {
1975 struct zep_drv_if_ctx *if_ctx = priv;
1976 const struct zep_wpa_supp_dev_ops *dev_ops;
1977 int ret = -1;
1978
1979 dev_ops = if_ctx->dev_ctx->config;
1980 if (!dev_ops->send_mlme) {
1981 wpa_printf(MSG_ERROR, "%s: send_mlme op not supported",
1982 __func__);
1983 goto out;
1984 }
1985
1986 if (freq == 0) {
1987 freq = if_ctx->freq;
1988 }
1989
1990 ret = dev_ops->send_mlme(if_ctx->dev_priv, data, data_len, noack, freq, 0, 0, wait, 0);
1991 if (ret) {
1992 wpa_printf(MSG_ERROR, "%s: send_mlme op failed: %d", __func__, ret);
1993 goto out;
1994 }
1995 ret = 0;
1996 out:
1997 return ret;
1998 }
1999
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)2000 int wpa_drv_hapd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
2001 int encrypt, const u8 *own_addr, u32 flags)
2002 {
2003 struct zep_drv_if_ctx *if_ctx = priv;
2004 const struct zep_wpa_supp_dev_ops *dev_ops;
2005 int ret = -1;
2006 struct wpa_supplicant *wpa_s = NULL;
2007
2008 /* TODO: Unused for now, but might need for rekeying */
2009 (void)own_addr;
2010 (void)flags;
2011 (void)encrypt;
2012
2013 wpa_s = if_ctx->supp_if_ctx;
2014 dev_ops = if_ctx->dev_ctx->config;
2015
2016 wpa_printf(MSG_DEBUG, "wpa_supp: Send EAPOL frame (encrypt=%d)", encrypt);
2017
2018 ret = l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data, data_len);
2019 if (ret < 0) {
2020 wpa_printf(MSG_ERROR, "%s: l2_packet_send failed: %d", __func__, ret);
2021 goto out;
2022 }
2023
2024 ret = 0;
2025 out:
2026 return ret;
2027 }
2028
2029 #endif /* CONFIG_AP */
2030
wpa_drv_zep_dpp_listen(void * priv,bool enable)2031 int wpa_drv_zep_dpp_listen(void *priv, bool enable)
2032 {
2033 struct zep_drv_if_ctx *if_ctx = NULL;
2034 const struct zep_wpa_supp_dev_ops *dev_ops;
2035 int ret = -1;
2036
2037 if ((!priv)) {
2038 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
2039 goto out;
2040 }
2041
2042 if_ctx = priv;
2043 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2044
2045 if (!dev_ops || !dev_ops->dpp_listen) {
2046 wpa_printf(MSG_ERROR, "%s: dpp_listen op not supported", __func__);
2047 goto out;
2048 }
2049
2050 ret = dev_ops->dpp_listen(if_ctx->dev_priv, enable);
2051 if (ret) {
2052 wpa_printf(MSG_ERROR, "%s: dpp_listen op failed", __func__);
2053 goto out;
2054 }
2055
2056 out:
2057 return ret;
2058
2059 }
2060
wpa_drv_zep_remain_on_channel(void * priv,unsigned int freq,unsigned int duration)2061 int wpa_drv_zep_remain_on_channel(void *priv, unsigned int freq,
2062 unsigned int duration)
2063 {
2064 struct zep_drv_if_ctx *if_ctx = NULL;
2065 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
2066 int ret = -1;
2067
2068 if (!priv) {
2069 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
2070 goto out;
2071 }
2072
2073 if_ctx = priv;
2074 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2075
2076 if (!dev_ops || !dev_ops->remain_on_channel) {
2077 wpa_printf(MSG_ERROR, "%s: remain_on_channel op not supported", __func__);
2078 goto out;
2079 }
2080
2081 ret = dev_ops->remain_on_channel(if_ctx->dev_priv, freq, duration);
2082 if (ret) {
2083 wpa_printf(MSG_ERROR, "%s: dpp_listen op failed", __func__);
2084 goto out;
2085 }
2086
2087 out:
2088 return ret;
2089 }
2090
wpa_drv_zep_cancel_remain_on_channel(void * priv)2091 int wpa_drv_zep_cancel_remain_on_channel(void *priv)
2092 {
2093 struct zep_drv_if_ctx *if_ctx = NULL;
2094 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
2095 int ret = -1;
2096
2097 if (!priv) {
2098 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
2099 goto out;
2100 }
2101
2102 if_ctx = priv;
2103 dev_ops = get_dev_ops(if_ctx->dev_ctx);
2104
2105 if (!dev_ops || !dev_ops->cancel_remain_on_channel) {
2106 wpa_printf(MSG_ERROR, "%s: cancel_remain_on_channel op not supported", __func__);
2107 goto out;
2108 }
2109
2110 ret = dev_ops->cancel_remain_on_channel(if_ctx->dev_priv);
2111 if (ret) {
2112 wpa_printf(MSG_ERROR, "%s: dpp_listen op failed", __func__);
2113 goto out;
2114 }
2115
2116 out:
2117 return ret;
2118 }
2119
2120
2121 const struct wpa_driver_ops wpa_driver_zep_ops = {
2122 .name = "zephyr",
2123 .desc = "Zephyr wpa_supplicant driver",
2124 .global_init = wpa_drv_zep_global_init,
2125 .global_deinit = wpa_drv_zep_global_deinit,
2126 .init2 = wpa_drv_zep_init,
2127 .deinit = wpa_drv_zep_deinit,
2128 .scan2 = wpa_drv_zep_scan2,
2129 .abort_scan = wpa_drv_zep_abort_scan,
2130 .get_scan_results2 = wpa_drv_zep_get_scan_results2,
2131 .authenticate = wpa_drv_zep_authenticate,
2132 .associate = wpa_drv_zep_associate,
2133 .get_capa = wpa_drv_zep_get_capa,
2134 .get_bssid = wpa_drv_zep_get_bssid,
2135 .get_ssid = wpa_drv_zep_get_ssid,
2136 .set_supp_port = wpa_drv_zep_set_supp_port,
2137 .deauthenticate = wpa_drv_zep_deauthenticate,
2138 .set_key = wpa_drv_zep_set_key,
2139 .signal_poll = wpa_drv_zep_signal_poll,
2140 .send_action = wpa_drv_zep_send_action,
2141 .get_hw_feature_data = wpa_drv_zep_get_hw_feature_data,
2142 .get_ext_capab = wpa_drv_zep_get_ext_capab,
2143 .get_conn_info = wpa_drv_zep_get_conn_info,
2144 #ifdef CONFIG_AP
2145 .hapd_send_eapol = wpa_drv_hapd_send_eapol,
2146 .send_mlme = wpa_drv_zep_send_mlme,
2147 .set_ap = wpa_drv_zep_set_ap,
2148 .stop_ap = wpa_drv_zep_stop_ap,
2149 .deinit_ap = wpa_drv_zep_deinit_ap,
2150 .sta_add = wpa_drv_zep_sta_add,
2151 .sta_set_flags = wpa_drv_zep_sta_set_flags,
2152 .sta_deauth = wpa_drv_zep_sta_deauth,
2153 .sta_disassoc = wpa_drv_zep_sta_disassoc,
2154 .sta_remove = wpa_drv_zep_sta_remove,
2155 #endif /* CONFIG_AP */
2156 .dpp_listen = wpa_drv_zep_dpp_listen,
2157 .remain_on_channel = wpa_drv_zep_remain_on_channel,
2158 .cancel_remain_on_channel = wpa_drv_zep_cancel_remain_on_channel,
2159 };
2160