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 #define SCAN_TIMEOUT 30
18
get_dev_ops(const struct device * dev)19 const struct zep_wpa_supp_dev_ops *get_dev_ops(const struct device *dev)
20 {
21 struct net_wifi_mgmt_offload *api;
22
23 api = (struct net_wifi_mgmt_offload *)dev->api;
24
25 return api->wifi_drv_ops;
26 }
27
wpa_supplicant_event_wrapper(void * ctx,enum wpa_event_type event,union wpa_event_data * data)28 void wpa_supplicant_event_wrapper(void *ctx,
29 enum wpa_event_type event,
30 union wpa_event_data *data)
31 {
32 struct wpa_supplicant_event_msg msg = { 0 };
33
34 msg.ctx = ctx;
35 msg.event = event;
36 if (data) {
37 msg.data = os_zalloc(sizeof(*data));
38 if (!msg.data) {
39 wpa_printf(MSG_ERROR, "Failed to allocated for event: %d", event);
40 return;
41 }
42 os_memcpy(msg.data, data, sizeof(*data));
43 if (event == EVENT_AUTH) {
44 union wpa_event_data *data_tmp = msg.data;
45
46 if (data->auth.ies) {
47 char *ies = os_zalloc(data->auth.ies_len);
48
49 if (!ies) {
50 wpa_printf(MSG_ERROR, "%s: Failed to alloc ies", __func__);
51 return;
52 }
53
54 os_memcpy(ies, data->auth.ies, data->auth.ies_len);
55 data_tmp->auth.ies = ies;
56 }
57 }
58 }
59
60 zephyr_wifi_send_event(&msg);
61 }
62
wpa_drv_zep_abort_scan(void * priv,u64 scan_cookie)63 static int wpa_drv_zep_abort_scan(void *priv,
64 u64 scan_cookie)
65 {
66 struct zep_drv_if_ctx *if_ctx = NULL;
67 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
68 int ret = -1;
69
70 if_ctx = priv;
71
72 dev_ops = get_dev_ops(if_ctx->dev_ctx);
73 if (!dev_ops->scan_abort) {
74 wpa_printf(MSG_ERROR,
75 "%s: No op registered for scan_abort",
76 __func__);
77 goto out;
78 }
79
80 ret = dev_ops->scan_abort(if_ctx->dev_priv);
81 out:
82 return ret;
83 }
84
85
86 /**
87 * wpa_drv_zep_scan_timeout - Scan timeout to report scan completion
88 * @eloop_ctx: Driver private data
89 * @timeout_ctx: ctx argument given to wpa_drv_zep_init()
90 *
91 * This function can be used as registered timeout when starting a scan to
92 * generate a scan completed event if the driver does not report this.
93 */
wpa_drv_zep_scan_timeout(void * eloop_ctx,void * timeout_ctx)94 void wpa_drv_zep_scan_timeout(void *eloop_ctx, void *timeout_ctx)
95 {
96 struct zep_drv_if_ctx *if_ctx = NULL;
97
98 if_ctx = eloop_ctx;
99
100 wpa_printf(MSG_ERROR,
101 "%s: Scan timeout - try to abort it",
102 __func__);
103
104 if (wpa_drv_zep_abort_scan(if_ctx, 0) == 0) {
105 return;
106 }
107 }
108
109
wpa_drv_zep_event_proc_scan_start(struct zep_drv_if_ctx * if_ctx)110 void wpa_drv_zep_event_proc_scan_start(struct zep_drv_if_ctx *if_ctx)
111 {
112 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
113 EVENT_SCAN_STARTED,
114 NULL);
115 }
116
117
wpa_drv_zep_event_proc_scan_done(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)118 void wpa_drv_zep_event_proc_scan_done(struct zep_drv_if_ctx *if_ctx,
119 union wpa_event_data *event)
120 {
121 eloop_cancel_timeout(wpa_drv_zep_scan_timeout,
122 if_ctx,
123 if_ctx->supp_if_ctx);
124
125 if_ctx->scan_res2_get_in_prog = false;
126
127 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
128 EVENT_SCAN_RESULTS,
129 event);
130 }
131
132
wpa_drv_zep_event_proc_scan_res(struct zep_drv_if_ctx * if_ctx,struct wpa_scan_res * r,bool more_res)133 void wpa_drv_zep_event_proc_scan_res(struct zep_drv_if_ctx *if_ctx,
134 struct wpa_scan_res *r,
135 bool more_res)
136 {
137 struct wpa_scan_res **tmp = NULL;
138 size_t scan_res_len = sizeof(struct wpa_scan_res) + r->ie_len + r->beacon_ie_len;
139
140 tmp = os_realloc_array(if_ctx->scan_res2->res,
141 if_ctx->scan_res2->num + 1,
142 sizeof(struct wpa_scan_res *));
143
144 if (!tmp) {
145 os_free(r);
146 return;
147 }
148
149 struct wpa_scan_res *sr = os_zalloc(scan_res_len);
150 if (!sr) {
151 wpa_printf(MSG_ERROR, "%s: Failed to alloc scan results(%d bytes)", __func__, scan_res_len);
152 return;
153 }
154
155 os_memcpy(sr, r, scan_res_len);
156
157 tmp[if_ctx->scan_res2->num++] = sr;
158
159 if_ctx->scan_res2->res = tmp;
160
161 if_ctx->scan_res2_get_in_prog = more_res;
162 }
163
164
wpa_drv_zep_event_proc_auth_resp(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)165 void wpa_drv_zep_event_proc_auth_resp(struct zep_drv_if_ctx *if_ctx,
166 union wpa_event_data *event)
167 {
168 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
169 EVENT_AUTH,
170 event);
171 }
172
173
wpa_drv_zep_event_proc_assoc_resp(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event,unsigned int status)174 void wpa_drv_zep_event_proc_assoc_resp(struct zep_drv_if_ctx *if_ctx,
175 union wpa_event_data *event,
176 unsigned int status)
177 {
178 if (status != WLAN_STATUS_SUCCESS) {
179 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
180 EVENT_ASSOC_REJECT,
181 event);
182 } else {
183 if_ctx->associated = true;
184
185 os_memcpy(if_ctx->bssid,
186 event->assoc_info.addr,
187 ETH_ALEN);
188
189 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
190 EVENT_ASSOC,
191 event);
192 }
193 }
194
195
wpa_drv_zep_event_proc_deauth(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)196 void wpa_drv_zep_event_proc_deauth(struct zep_drv_if_ctx *if_ctx,
197 union wpa_event_data *event)
198 {
199 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
200 EVENT_DEAUTH,
201 event);
202 }
203
204
wpa_drv_zep_event_proc_disassoc(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)205 void wpa_drv_zep_event_proc_disassoc(struct zep_drv_if_ctx *if_ctx,
206 union wpa_event_data *event)
207 {
208 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
209 EVENT_DISASSOC,
210 event);
211 }
212
wpa_drv_zep_event_mgmt_tx_status(struct zep_drv_if_ctx * if_ctx,const u8 * frame,size_t len,bool ack)213 static void wpa_drv_zep_event_mgmt_tx_status(struct zep_drv_if_ctx *if_ctx,
214 const u8 *frame, size_t len, bool ack)
215 {
216 union wpa_event_data event;
217 const struct ieee80211_hdr *hdr;
218 u16 fc;
219
220 wpa_printf(MSG_DEBUG, "wpa_supp: Frame TX status event");
221
222 hdr = (const struct ieee80211_hdr *) frame;
223 fc = le_to_host16(hdr->frame_control);
224
225 os_memset(&event, 0, sizeof(event));
226 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
227 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
228 event.tx_status.dst = hdr->addr1;
229 event.tx_status.data = frame;
230 event.tx_status.data_len = len;
231 event.tx_status.ack = ack;
232
233 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
234 EVENT_TX_STATUS,
235 &event);
236 }
237
wpa_drv_zep_event_proc_unprot_deauth(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)238 static void wpa_drv_zep_event_proc_unprot_deauth(struct zep_drv_if_ctx *if_ctx,
239 union wpa_event_data *event)
240 {
241 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
242 EVENT_UNPROT_DEAUTH,
243 event);
244 }
245
wpa_drv_zep_event_proc_unprot_disassoc(struct zep_drv_if_ctx * if_ctx,union wpa_event_data * event)246 static void wpa_drv_zep_event_proc_unprot_disassoc(struct zep_drv_if_ctx *if_ctx,
247 union wpa_event_data *event)
248 {
249 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx,
250 EVENT_UNPROT_DISASSOC,
251 event);
252 }
253
254 struct phy_info_arg {
255 u16 *num_modes;
256 struct hostapd_hw_modes *modes;
257 int last_mode, last_chan_idx;
258 int failed;
259 u8 dfs_domain;
260 };
261
phy_info_freq_cfg(struct hostapd_hw_modes * mode,struct hostapd_channel_data * chan,struct wpa_supp_event_channel * chnl_info)262 static void phy_info_freq_cfg(struct hostapd_hw_modes *mode,
263 struct hostapd_channel_data *chan,
264 struct wpa_supp_event_channel *chnl_info)
265 {
266 u8 channel = 0;
267
268 chan->freq = chnl_info->center_frequency;
269 chan->flag = 0;
270 chan->allowed_bw = ~0;
271 chan->dfs_cac_ms = 0;
272
273 if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES) {
274 chan->chan = channel;
275 }
276
277 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_DISABLED)
278 chan->flag |= HOSTAPD_CHAN_DISABLED;
279 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_IR)
280 chan->flag |= HOSTAPD_CHAN_NO_IR;
281 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_RADAR)
282 chan->flag |= HOSTAPD_CHAN_RADAR;
283 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_INDOOR_ONLY)
284 chan->flag |= HOSTAPD_CHAN_INDOOR_ONLY;
285 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_GO_CONCURRENT)
286 chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT;
287 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_10MHZ)
288 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_10;
289 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_20MHZ)
290 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_20;
291 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_HT40_PLUS)
292 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40P;
293 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_HT40_MINUS)
294 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40M;
295 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_80MHZ)
296 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_80;
297 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_FLAG_FREQUENCY_ATTR_NO_160MHZ)
298 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160;
299
300 if (chnl_info->wpa_supp_flags & WPA_SUPP_CHAN_DFS_CAC_TIME_VALID) {
301 chan->dfs_cac_ms = (chnl_info->wpa_supp_time);
302 }
303
304 /* Other elements are not present */
305 chan->wmm_rules_valid = 0;
306 chan->wmm_rules_valid = 0;
307 }
308
309
phy_info_freqs_cfg(struct phy_info_arg * phy_info,struct hostapd_hw_modes * mode,struct wpa_supp_event_supported_band * band_info)310 static int phy_info_freqs_cfg(struct phy_info_arg *phy_info,
311 struct hostapd_hw_modes *mode,
312 struct wpa_supp_event_supported_band *band_info)
313 {
314 int new_channels = 0;
315 struct hostapd_channel_data *channel = NULL;
316 int idx;
317
318 if (!phy_info || !mode || !band_info)
319 return -1;
320
321 new_channels = band_info->wpa_supp_n_channels;
322 if (!new_channels)
323 return 0;
324
325 channel = os_realloc_array(mode->channels,
326 mode->num_channels + new_channels,
327 sizeof(struct hostapd_channel_data));
328 if (!channel)
329 return -1;
330
331 mode->channels = channel;
332 mode->num_channels += new_channels;
333
334 idx = phy_info->last_chan_idx;
335
336 for (int i = 0; i < new_channels; i++) {
337 phy_info_freq_cfg(mode, &mode->channels[idx], &band_info->channels[i]);
338 idx++;
339 }
340
341 phy_info->last_chan_idx = idx;
342
343 return 0;
344 }
345
phy_info_rates_cfg(struct hostapd_hw_modes * mode,struct wpa_supp_event_supported_band * band_info)346 static int phy_info_rates_cfg(struct hostapd_hw_modes *mode,
347 struct wpa_supp_event_supported_band *band_info)
348 {
349 int idx;
350
351 if (!mode || !band_info)
352 return -1;
353
354 mode->num_rates = band_info->wpa_supp_n_bitrates;
355 if (!mode->num_rates)
356 return 0;
357
358 mode->rates = os_calloc(mode->num_rates, sizeof(int));
359 if (!mode->rates)
360 return -1;
361
362 idx = 0;
363
364 for (int i = 0; i < mode->num_rates; i++) {
365 if (!band_info->bitrates[i].wpa_supp_bitrate)
366 continue;
367 mode->rates[idx] = band_info->bitrates[i].wpa_supp_bitrate;
368 idx++;
369 }
370
371 return 0;
372 }
373
374
375
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)376 static void phy_info_ht_capa_cfg(struct hostapd_hw_modes *mode, u16 capa,
377 u8 ampdu_factor,
378 u8 ampdu_density,
379 struct wpa_supp_event_mcs_info *mcs_set)
380 {
381 if (capa)
382 mode->ht_capab = (capa);
383
384 if (ampdu_factor)
385 mode->a_mpdu_params |= (ampdu_factor) & WPA_SUPP_AMPDU_FACTOR_MASK;
386
387 if (ampdu_density)
388 mode->a_mpdu_params |= (ampdu_density) << WPA_SUPP_AMPDU_DENSITY_SHIFT;
389
390 if (mcs_set) {
391 os_memcpy(mode->mcs_set, mcs_set, sizeof(*mcs_set));
392 }
393
394 }
395
phy_info_vht_capa_cfg(struct hostapd_hw_modes * mode,unsigned int capa,struct wpa_supp_event_vht_mcs_info * vht_mcs_set)396 static void phy_info_vht_capa_cfg(struct hostapd_hw_modes *mode,
397 unsigned int capa,
398 struct wpa_supp_event_vht_mcs_info *vht_mcs_set)
399 {
400 if (capa)
401 mode->vht_capab = (capa);
402
403 if (vht_mcs_set) {
404 os_memcpy(mode->vht_mcs_set, vht_mcs_set, 8);
405 }
406 }
407
phy_info_band_cfg(struct phy_info_arg * phy_info,struct wpa_supp_event_supported_band * band_info)408 static int phy_info_band_cfg(struct phy_info_arg *phy_info,
409 struct wpa_supp_event_supported_band *band_info)
410 {
411 struct hostapd_hw_modes *mode;
412 int ret;
413
414 if (phy_info->last_mode != band_info->band) {
415 mode = os_realloc_array(phy_info->modes,
416 *phy_info->num_modes + 1,
417 sizeof(*mode));
418 if (!mode) {
419 phy_info->failed = 1;
420 return -1;
421 }
422
423 phy_info->modes = mode;
424
425 mode = &phy_info->modes[*(phy_info->num_modes)];
426
427 os_memset(mode, 0, sizeof(*mode));
428
429 mode->mode = NUM_HOSTAPD_MODES;
430 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
431 HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
432
433 /*
434 * Unsupported VHT MCS stream is defined as value 3, so the VHT
435 * MCS RX/TX map must be initialized with 0xffff to mark all 8
436 * possible streams as unsupported. This will be overridden if
437 * driver advertises VHT support.
438 */
439 mode->vht_mcs_set[0] = 0xff;
440 mode->vht_mcs_set[1] = 0xff;
441 mode->vht_mcs_set[4] = 0xff;
442 mode->vht_mcs_set[5] = 0xff;
443
444 *(phy_info->num_modes) += 1;
445
446 phy_info->last_mode = band_info->band;
447 phy_info->last_chan_idx = 0;
448 }
449 else
450 mode = &phy_info->modes[*(phy_info->num_modes) - 1];
451
452 phy_info_ht_capa_cfg(mode, band_info->ht_cap.wpa_supp_cap,
453 band_info->ht_cap.wpa_supp_ampdu_factor,
454 band_info->ht_cap.wpa_supp_ampdu_density,
455 &band_info->ht_cap.mcs);
456
457 phy_info_vht_capa_cfg(mode, band_info->vht_cap.wpa_supp_cap,
458 &band_info->vht_cap.vht_mcs);
459
460 ret = phy_info_freqs_cfg(phy_info, mode, band_info);
461
462 if (ret == 0)
463 ret = phy_info_rates_cfg(mode, band_info);
464
465 if (ret != 0) {
466 phy_info->failed = 1;
467 return ret;
468 }
469
470 return 0;
471 }
472
wpa_drv_zep_event_get_wiphy(struct zep_drv_if_ctx * if_ctx,void * band_info)473 static void wpa_drv_zep_event_get_wiphy(struct zep_drv_if_ctx *if_ctx, void *band_info)
474 {
475 if (!band_info) {
476 if_ctx->get_wiphy_in_progress = false;
477 return;
478 }
479
480 phy_info_band_cfg(if_ctx->phy_info_arg, band_info);
481 }
482
wpa_drv_register_frame(struct zep_drv_if_ctx * if_ctx,u16 type,const u8 * match,size_t match_len,bool multicast)483 static int wpa_drv_register_frame(struct zep_drv_if_ctx *if_ctx,
484 u16 type, const u8 *match, size_t match_len,
485 bool multicast)
486 {
487 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
488
489 dev_ops = get_dev_ops(if_ctx->dev_ctx);
490 if (!dev_ops->register_frame)
491 return -1;
492
493 return dev_ops->register_frame(if_ctx->dev_priv, type, match, match_len, false);
494 }
495
wpa_drv_register_action_frame(struct zep_drv_if_ctx * if_ctx,const u8 * match,size_t match_len)496 static int wpa_drv_register_action_frame(struct zep_drv_if_ctx *if_ctx,
497 const u8 *match, size_t match_len)
498 {
499 u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
500
501 return wpa_drv_register_frame(if_ctx, type, match, match_len, false);
502 }
503
wpa_drv_mgmt_subscribe_non_ap(struct zep_drv_if_ctx * if_ctx)504 static int wpa_drv_mgmt_subscribe_non_ap(struct zep_drv_if_ctx *if_ctx)
505 {
506 int ret = 0;
507
508 /* WNM - BSS Transition Management Request */
509 if (wpa_drv_register_action_frame(if_ctx, (u8 *)"\x0a\x07", 2) < 0)
510 ret = -1;
511
512 return ret;
513 }
514
wpa_drv_zep_event_mgmt_rx(struct zep_drv_if_ctx * if_ctx,char * frame,int frame_len,int frequency,int rx_signal_dbm)515 static void wpa_drv_zep_event_mgmt_rx(struct zep_drv_if_ctx *if_ctx,
516 char *frame, int frame_len,
517 int frequency, int rx_signal_dbm)
518 {
519 const struct ieee80211_mgmt *mgmt;
520
521 union wpa_event_data event;
522 u16 fc, stype;
523 int rx_freq = 0;
524
525 wpa_printf(MSG_MSGDUMP, "wpa_supp: Frame event");
526 mgmt = (const struct ieee80211_mgmt *)frame;
527
528 if (frame_len < 24) {
529 wpa_printf(MSG_DEBUG, "wpa_supp: Too short management frame");
530 return;
531 }
532
533 fc = le_to_host16(mgmt->frame_control);
534 stype = WLAN_FC_GET_STYPE(fc);
535
536 os_memset(&event, 0, sizeof(event));
537
538 if (frequency) {
539 event.rx_mgmt.freq = frequency;
540 rx_freq = event.rx_mgmt.freq;
541 }
542
543 event.rx_mgmt.frame = frame;
544 event.rx_mgmt.frame_len = frame_len;
545 event.rx_mgmt.ssi_signal = rx_signal_dbm;
546
547 wpa_supplicant_event_wrapper(if_ctx->supp_if_ctx, EVENT_RX_MGMT, &event);
548 }
549
550 static struct hostapd_hw_modes *
wpa_driver_wpa_supp_postprocess_modes(struct hostapd_hw_modes * modes,u16 * num_modes)551 wpa_driver_wpa_supp_postprocess_modes(struct hostapd_hw_modes *modes,
552 u16 *num_modes)
553 {
554 u16 m;
555 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
556 int i, mode11g_idx = -1;
557
558 /* heuristic to set up modes */
559 for (m = 0; m < *num_modes; m++) {
560 if (!modes[m].num_channels)
561 continue;
562 if (modes[m].channels[0].freq < 4000) {
563 modes[m].mode = HOSTAPD_MODE_IEEE80211B;
564 for (i = 0; i < modes[m].num_rates; i++) {
565 if (modes[m].rates[i] > 200) {
566 modes[m].mode = HOSTAPD_MODE_IEEE80211G;
567 break;
568 }
569 }
570 } else if (modes[m].channels[0].freq > 50000)
571 modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
572 else
573 modes[m].mode = HOSTAPD_MODE_IEEE80211A;
574 }
575
576 /* If only 802.11g mode is included, use it to construct matching
577 * 802.11b mode data. */
578
579 for (m = 0; m < *num_modes; m++) {
580 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
581 return modes; /* 802.11b already included */
582 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
583 mode11g_idx = m;
584 }
585
586 if (mode11g_idx < 0)
587 return modes; /* 2.4 GHz band not supported at all */
588
589 nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
590 if (nmodes == NULL)
591 return modes; /* Could not add 802.11b mode */
592
593 mode = &nmodes[*num_modes];
594 os_memset(mode, 0, sizeof(*mode));
595 (*num_modes)++;
596 modes = nmodes;
597
598 mode->mode = HOSTAPD_MODE_IEEE80211B;
599 mode11g = &modes[mode11g_idx];
600 mode->num_channels = mode11g->num_channels;
601 mode->channels = os_memdup(mode11g->channels,
602 mode11g->num_channels *
603 sizeof(struct hostapd_channel_data));
604 if (mode->channels == NULL) {
605 (*num_modes)--;
606 return modes; /* Could not add 802.11b mode */
607 }
608
609 mode->num_rates = 0;
610 mode->rates = os_malloc(4 * sizeof(int));
611 if (mode->rates == NULL) {
612 os_free(mode->channels);
613 (*num_modes)--;
614 return modes; /* Could not add 802.11b mode */
615 }
616
617 for (i = 0; i < mode11g->num_rates; i++) {
618 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
619 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
620 continue;
621 mode->rates[mode->num_rates] = mode11g->rates[i];
622 mode->num_rates++;
623 if (mode->num_rates == 4)
624 break;
625 }
626
627 if (mode->num_rates == 0) {
628 os_free(mode->channels);
629 os_free(mode->rates);
630 (*num_modes)--;
631 return modes; /* No 802.11b rates */
632 }
633
634 wpa_printf(MSG_DEBUG, "wpa_supp: Added 802.11b mode based on 802.11g "
635 "information");
636
637 return modes;
638 }
639
wpa_drv_get_hw_feature_data(void * priv,u16 * num_modes,u16 * flags,u8 * dfs_domain)640 struct hostapd_hw_modes *wpa_drv_get_hw_feature_data(void *priv,
641 u16 *num_modes,
642 u16 *flags, u8 *dfs_domain)
643 {
644 struct zep_drv_if_ctx *if_ctx = NULL;
645 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
646 int ret = -1;
647 int i=0;
648
649 if_ctx = priv;
650
651 dev_ops = get_dev_ops(if_ctx->dev_ctx);
652
653 struct phy_info_arg result = {
654 .num_modes = num_modes,
655 .modes = NULL,
656 .last_mode = -1,
657 .failed = 0,
658 .dfs_domain = 0,
659 };
660
661 *num_modes = 0;
662 *flags = 0;
663 *dfs_domain = 0;
664
665 if_ctx->phy_info_arg = &result;
666
667 if_ctx->get_wiphy_in_progress = true;
668
669 ret = dev_ops->get_wiphy(if_ctx->dev_priv);
670
671 while ((if_ctx->get_wiphy_in_progress) && (i < SCAN_TIMEOUT)) {
672 k_yield();
673 os_sleep(1, 0);
674 i++;
675 }
676
677 struct hostapd_hw_modes *modes;
678
679 *dfs_domain = result.dfs_domain;
680
681 modes = wpa_driver_wpa_supp_postprocess_modes(result.modes,
682 num_modes);
683
684 return modes;
685 }
686
wpa_drv_zep_global_init(void * ctx)687 static void *wpa_drv_zep_global_init(void *ctx)
688 {
689 struct zep_drv_ctx *drv_ctx = NULL;
690
691 drv_ctx = os_zalloc(sizeof(*drv_ctx));
692 if (!drv_ctx) {
693 return NULL;
694 }
695
696 drv_ctx->supp_ctx = ctx;
697
698 return drv_ctx;
699 }
700
701
wpa_drv_zep_global_deinit(void * priv)702 static void wpa_drv_zep_global_deinit(void *priv)
703 {
704 struct zep_drv_ctx *drv_ctx = priv;
705
706 if (!drv_ctx) {
707 return;
708 }
709
710 os_free(drv_ctx);
711 }
712
713
714 /**
715 * wpa_driver_zep_init - Initialize Zephyr driver interface
716 * @ctx: Context to be used when calling wpa_supplicant functions,
717 * e.g., wpa_supplicant_event_wrapper()
718 * @ifname: Interface name, e.g., wlan0
719 * @global_priv: private driver global data from global_init()
720 *
721 * Returns: Pointer to private data, %NULL on failure
722 */
wpa_drv_zep_init(void * ctx,const char * ifname,void * global_priv)723 static void *wpa_drv_zep_init(void *ctx,
724 const char *ifname,
725 void *global_priv)
726 {
727 struct zep_drv_if_ctx *if_ctx = NULL;
728 const struct zep_wpa_supp_dev_ops *dev_ops;
729 struct zep_wpa_supp_dev_callbk_fns callbk_fns;
730 const struct device *device;
731 struct net_if *iface;
732
733 iface = net_if_get_by_index(net_if_get_by_name(ifname));
734
735 device = net_if_get_device(iface);
736 if (!device) {
737 wpa_printf(MSG_ERROR, "%s: Interface %s not found", __func__, ifname);
738 goto out;
739 }
740
741 if_ctx = os_zalloc(sizeof(*if_ctx));
742 if (if_ctx == NULL) {
743 goto out;
744 }
745
746 if_ctx->supp_if_ctx = ctx;
747 if_ctx->iface = iface;
748 if_ctx->dev_ctx = device;
749 if_ctx->drv_ctx = global_priv;
750
751 dev_ops = get_dev_ops(if_ctx->dev_ctx);
752 if (!dev_ops->init) {
753 wpa_printf(MSG_ERROR,
754 "%s: No op registered for init",
755 __func__);
756 os_free(if_ctx);
757 if_ctx = NULL;
758 goto out;
759 }
760
761 os_memset(&callbk_fns, 0, sizeof(callbk_fns));
762
763 callbk_fns.scan_start = wpa_drv_zep_event_proc_scan_start;
764 callbk_fns.scan_done = wpa_drv_zep_event_proc_scan_done;
765 callbk_fns.scan_res = wpa_drv_zep_event_proc_scan_res;
766 callbk_fns.auth_resp = wpa_drv_zep_event_proc_auth_resp;
767 callbk_fns.assoc_resp = wpa_drv_zep_event_proc_assoc_resp;
768 callbk_fns.deauth = wpa_drv_zep_event_proc_deauth;
769 callbk_fns.disassoc = wpa_drv_zep_event_proc_disassoc;
770 callbk_fns.mgmt_tx_status = wpa_drv_zep_event_mgmt_tx_status;
771 callbk_fns.unprot_deauth = wpa_drv_zep_event_proc_unprot_deauth;
772 callbk_fns.unprot_disassoc = wpa_drv_zep_event_proc_unprot_disassoc;
773 callbk_fns.get_wiphy_res = wpa_drv_zep_event_get_wiphy;
774 callbk_fns.mgmt_rx = wpa_drv_zep_event_mgmt_rx;
775
776 if_ctx->dev_priv = dev_ops->init(if_ctx,
777 ifname,
778 &callbk_fns);
779 if (!if_ctx->dev_priv) {
780 wpa_printf(MSG_ERROR,
781 "%s: Failed to initialize the interface",
782 __func__);
783 os_free(if_ctx);
784 if_ctx = NULL;
785 goto out;
786 }
787
788 wpa_drv_mgmt_subscribe_non_ap(if_ctx);
789
790 out:
791 return if_ctx;
792 }
793
794
wpa_drv_zep_deinit(void * priv)795 static void wpa_drv_zep_deinit(void *priv)
796 {
797 struct zep_drv_if_ctx *if_ctx = NULL;
798 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
799
800 if_ctx = priv;
801
802 dev_ops = get_dev_ops(if_ctx->dev_ctx);
803 if (!dev_ops->deinit) {
804 wpa_printf(MSG_ERROR, "%s: No op registered for deinit", __func__);
805 return;
806 }
807
808 dev_ops->deinit(if_ctx->dev_priv);
809
810 os_free(if_ctx);
811 }
812
813
wpa_drv_zep_scan2(void * priv,struct wpa_driver_scan_params * params)814 static int wpa_drv_zep_scan2(void *priv, struct wpa_driver_scan_params *params)
815 {
816 struct zep_drv_if_ctx *if_ctx = NULL;
817 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
818 int timeout = 0;
819 int ret = -1;
820
821 if (!priv || !params) {
822 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
823 goto out;
824 }
825
826 if_ctx = priv;
827 if (if_ctx->scan_res2_get_in_prog) {
828 wpa_printf(MSG_ERROR, "%s: Scan is already in progress", __func__);
829 goto out;
830 }
831
832 dev_ops = get_dev_ops(if_ctx->dev_ctx);
833 if (!dev_ops->scan2) {
834 wpa_printf(MSG_ERROR, "%s: No op registered for scan2", __func__);
835 goto out;
836 }
837
838 ret = dev_ops->scan2(if_ctx->dev_priv, params);
839 if (ret) {
840 wpa_printf(MSG_ERROR, "%s: scan2 op failed", __func__);
841 goto out;
842 }
843
844 /* The driver delivers events to notify when scan is
845 * complete, so use longer timeout to avoid race conditions
846 * with scanning and following association request.
847 */
848 timeout = SCAN_TIMEOUT;
849
850 wpa_printf(MSG_DEBUG,
851 "%s: Scan requested - scan timeout %d seconds",
852 __func__,
853 timeout);
854
855 eloop_cancel_timeout(wpa_drv_zep_scan_timeout,
856 if_ctx,
857 if_ctx->supp_if_ctx);
858
859 eloop_register_timeout(timeout,
860 0,
861 wpa_drv_zep_scan_timeout,
862 if_ctx,
863 if_ctx->supp_if_ctx);
864
865 ret = 0;
866
867 out:
868 return ret;
869 }
870
871
872 /**
873 * wpa_drv_zep_get_scan_results2 - Fetch the latest scan results
874 * @priv: Pointer to private data from wpa_drv_zep_init()
875 * Returns: Scan results on success, -1 on failure
876 */
wpa_drv_zep_get_scan_results2(void * priv)877 struct wpa_scan_results *wpa_drv_zep_get_scan_results2(void *priv)
878 {
879 struct zep_drv_if_ctx *if_ctx = NULL;
880 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
881 unsigned int i = 0;
882 int ret = -1;
883
884 if (!priv) {
885 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
886 goto out;
887 }
888
889 if_ctx = priv;
890
891 dev_ops = get_dev_ops(if_ctx->dev_ctx);
892 if (!dev_ops->get_scan_results2) {
893 wpa_printf(MSG_ERROR,
894 "%s: No op registered for scan2",
895 __func__);
896 goto out;
897 }
898
899 if_ctx->scan_res2 = os_zalloc(sizeof(*if_ctx->scan_res2));
900 if (!if_ctx->scan_res2) {
901 wpa_printf(MSG_ERROR, "%s: Failed to alloc memory for scan results", __func__);
902 goto out;
903 }
904
905 if_ctx->scan_res2_get_in_prog = true;
906
907 ret = dev_ops->get_scan_results2(if_ctx->dev_priv);
908 if (ret) {
909 wpa_printf(MSG_ERROR, "%s: get_scan_results2 op failed", __func__);
910 if_ctx->scan_res2_get_in_prog = false;
911 goto out;
912 }
913
914 /* Wait for the device to populate the scan results */
915 while ((if_ctx->scan_res2_get_in_prog) && (i < SCAN_TIMEOUT)) {
916 k_yield();
917 os_sleep(1, 0);
918 i++;
919 }
920
921 if (i == SCAN_TIMEOUT) {
922 wpa_printf(MSG_ERROR, "%s: Timed out waiting for scan results", __func__);
923 ret = -1;
924 goto out;
925 }
926
927 ret = 0;
928 out:
929 if (ret == -1) {
930 if (if_ctx->scan_res2) {
931 wpa_scan_results_free(if_ctx->scan_res2);
932 if_ctx->scan_res2 = NULL;
933 }
934 }
935
936 return if_ctx->scan_res2;
937 }
938
939
wpa_drv_zep_deauthenticate(void * priv,const u8 * addr,u16 reason_code)940 static int wpa_drv_zep_deauthenticate(void *priv, const u8 *addr,
941 u16 reason_code)
942 {
943 struct zep_drv_if_ctx *if_ctx = NULL;
944 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
945 int ret = -1;
946
947 if ((!priv) || (!addr)) {
948 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
949 goto out;
950 }
951
952 if_ctx = priv;
953
954 dev_ops = get_dev_ops(if_ctx->dev_ctx);
955 ret = dev_ops->deauthenticate(if_ctx->dev_priv, addr, reason_code);
956 if (ret) {
957 wpa_printf(MSG_ERROR, "%s: deauthenticate op failed", __func__);
958 goto out;
959 }
960
961 ret = 0;
962 out:
963 return ret;
964 }
965
966
wpa_drv_zep_authenticate(void * priv,struct wpa_driver_auth_params * params)967 static int wpa_drv_zep_authenticate(void *priv,
968 struct wpa_driver_auth_params *params)
969 {
970 struct zep_drv_if_ctx *if_ctx = NULL;
971 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
972 struct wpa_bss *curr_bss;
973 int ret = -1;
974
975 if ((!priv) || (!params)) {
976 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
977 goto out;
978 }
979
980 if_ctx = priv;
981
982 dev_ops = get_dev_ops(if_ctx->dev_ctx);
983
984 os_memcpy(if_ctx->ssid, params->ssid, params->ssid_len);
985
986 if_ctx->ssid_len = params->ssid_len;
987
988 curr_bss = wpa_bss_get(if_ctx->supp_if_ctx, params->bssid, params->ssid, params->ssid_len);
989 if (!curr_bss) {
990 wpa_printf(MSG_ERROR, "%s: Failed to get BSS", __func__);
991 ret = -1;
992 goto out;
993 }
994
995 ret = dev_ops->authenticate(if_ctx->dev_priv, params, curr_bss);
996 if (ret) {
997 wpa_printf(MSG_ERROR, "%s: authenticate op failed", __func__);
998 goto out;
999 }
1000
1001 ret = 0;
1002 out:
1003 return ret;
1004 }
1005
1006
wpa_drv_zep_associate(void * priv,struct wpa_driver_associate_params * params)1007 static int wpa_drv_zep_associate(void *priv,
1008 struct wpa_driver_associate_params *params)
1009 {
1010 struct zep_drv_if_ctx *if_ctx = NULL;
1011 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1012 int ret = -1;
1013
1014 if ((!priv) || (!params)) {
1015 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1016 goto out;
1017 }
1018
1019 if_ctx = priv;
1020
1021 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1022
1023 ret = dev_ops->associate(if_ctx->dev_priv, params);
1024 if (ret) {
1025 wpa_printf(MSG_ERROR, "%s: associate op failed", __func__);
1026 goto out;
1027 }
1028
1029 ret = 0;
1030 out:
1031 return ret;
1032 }
1033
1034
_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)1035 static int _wpa_drv_zep_set_key(void *priv,
1036 const char *ifname,
1037 enum wpa_alg alg,
1038 const u8 *addr,
1039 int key_idx,
1040 int set_tx,
1041 const u8 *seq,
1042 size_t seq_len,
1043 const u8 *key,
1044 size_t key_len)
1045 {
1046 struct zep_drv_if_ctx *if_ctx = NULL;
1047 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1048 int ret = -1;
1049
1050 if (!priv) {
1051 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1052 goto out;
1053 }
1054 if ((alg != WPA_ALG_NONE) && ((!seq) || (!key))) {
1055 wpa_printf(MSG_ERROR,
1056 "%s: Missing mandatory params",
1057 __func__);
1058 goto out;
1059 }
1060
1061 if_ctx = priv;
1062 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1063
1064 wpa_printf(MSG_DEBUG, "%s: priv:%p alg %d addr %p key_idx %d set_tx %d seq %p "
1065 "seq_len %d key %p key_len %d",
1066 __func__,
1067 if_ctx->dev_priv,
1068 alg, addr,
1069 key_idx,
1070 set_tx,
1071 seq,
1072 seq_len,
1073 key,
1074 key_len);
1075
1076 ret = dev_ops->set_key(if_ctx->dev_priv,
1077 ifname,
1078 alg,
1079 addr,
1080 key_idx,
1081 set_tx,
1082 seq,
1083 seq_len,
1084 key,
1085 key_len);
1086 if (ret) {
1087 wpa_printf(MSG_ERROR, "%s: set_key op failed", __func__);
1088 goto out;
1089 }
1090 out:
1091 return ret;
1092 }
1093
1094
wpa_drv_zep_set_key(void * priv,struct wpa_driver_set_key_params * params)1095 static int wpa_drv_zep_set_key(void* priv,
1096 struct wpa_driver_set_key_params *params)
1097 {
1098 return _wpa_drv_zep_set_key(priv,
1099 params->ifname,
1100 params->alg,
1101 params->addr,
1102 params->key_idx,
1103 params->set_tx,
1104 params->seq,
1105 params->seq_len,
1106 params->key,
1107 params->key_len);
1108 }
1109
1110
wpa_drv_zep_get_capa(void * priv,struct wpa_driver_capa * capa)1111 static int wpa_drv_zep_get_capa(void *priv, struct wpa_driver_capa *capa)
1112 {
1113
1114 struct zep_drv_if_ctx *if_ctx = NULL;
1115 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1116 int ret = -1;
1117
1118 if ((!priv) || (!capa)) {
1119 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1120 goto out;
1121 }
1122
1123 if_ctx = priv;
1124 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1125
1126 if (!dev_ops->get_capa) {
1127 wpa_printf(MSG_ERROR, "%s: get_capa op not supported", __func__);
1128 goto out;
1129 }
1130
1131 ret = dev_ops->get_capa(if_ctx->dev_priv, capa);
1132 if (ret) {
1133 wpa_printf(MSG_ERROR, "%s: get_capa op failed", __func__);
1134 goto out;
1135 }
1136
1137 ret = 0;
1138 out:
1139 return ret;
1140 }
1141
1142
wpa_drv_zep_get_bssid(void * priv,u8 * bssid)1143 static int wpa_drv_zep_get_bssid(void *priv, u8 *bssid)
1144 {
1145 struct zep_drv_if_ctx *if_ctx = NULL;
1146
1147 if_ctx = priv;
1148
1149 os_memcpy(bssid, if_ctx->bssid, ETH_ALEN);
1150
1151 return 0;
1152 }
1153
1154
wpa_drv_zep_get_ssid(void * priv,u8 * ssid)1155 static int wpa_drv_zep_get_ssid(void *priv,
1156 u8 *ssid)
1157 {
1158 struct zep_drv_if_ctx *if_ctx = NULL;
1159
1160 if_ctx = priv;
1161
1162 wpa_printf(MSG_INFO,
1163 "%s: SSID size: %d",
1164 __func__,
1165 if_ctx->ssid_len);
1166
1167 os_memcpy(ssid, if_ctx->ssid, if_ctx->ssid_len);
1168
1169 return if_ctx->ssid_len;
1170 }
1171
1172
wpa_drv_zep_set_supp_port(void * priv,int authorized)1173 static int wpa_drv_zep_set_supp_port(void *priv,
1174 int authorized)
1175 {
1176 struct zep_drv_if_ctx *if_ctx = NULL;
1177 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1178 struct net_if *iface = NULL;
1179
1180 int ret;
1181
1182 if_ctx = priv;
1183
1184 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1185
1186 iface = net_if_lookup_by_dev(if_ctx->dev_ctx);
1187
1188 ret = dev_ops->set_supp_port(if_ctx->dev_priv,
1189 authorized,
1190 if_ctx->bssid);
1191
1192 if (authorized) {
1193 net_dhcpv4_stop(iface);
1194 k_msleep(500);
1195 net_dhcpv4_start(iface);
1196 }
1197
1198 return ret;
1199 }
1200
1201
wpa_drv_zep_signal_poll(void * priv,struct wpa_signal_info * si)1202 static int wpa_drv_zep_signal_poll(void *priv, struct wpa_signal_info *si)
1203 {
1204 struct zep_drv_if_ctx *if_ctx = NULL;
1205 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1206 int ret = -1;
1207
1208 if (!priv) {
1209 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1210 goto out;
1211 }
1212
1213 if (!si) {
1214 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1215 goto out;
1216 }
1217
1218 if_ctx = priv;
1219 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1220
1221 os_memset(si, 0, sizeof(*si));
1222
1223 if (dev_ops && dev_ops->signal_poll) {
1224 ret = dev_ops->signal_poll(if_ctx->dev_priv, si, if_ctx->bssid);
1225 if (ret) {
1226 wpa_printf(MSG_ERROR, "%s: Signal polling failed: %d", __func__, ret);
1227 goto out;
1228 }
1229 } else {
1230 wpa_printf(MSG_ERROR, "%s: Signal polling not supported", __func__);
1231 goto out;
1232 }
1233
1234 out:
1235 return ret;
1236 }
1237
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)1238 static int wpa_drv_zep_send_action(void *priv, unsigned int freq,
1239 unsigned int wait_time,
1240 const u8 *dst, const u8 *src,
1241 const u8 *bssid,
1242 const u8 *data, size_t data_len,
1243 int no_cck)
1244 {
1245 struct zep_drv_if_ctx *if_ctx = NULL;
1246 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1247 int ret = -1;
1248 u8 *buf;
1249 struct ieee80211_hdr *hdr;
1250
1251 if_ctx = priv;
1252 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1253
1254 wpa_printf(MSG_DEBUG, "wpa_supp: Send Action frame ("
1255 "freq=%u MHz wait=%d ms no_cck=%d)",
1256 freq, wait_time, no_cck);
1257
1258 buf = os_zalloc(24 + data_len);
1259 if (buf == NULL)
1260 return ret;
1261
1262 os_memcpy(buf + 24, data, data_len);
1263
1264 hdr = (struct ieee80211_hdr *)buf;
1265 hdr->frame_control =
1266 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
1267 os_memcpy(hdr->addr1, dst, ETH_ALEN);
1268 os_memcpy(hdr->addr2, src, ETH_ALEN);
1269 os_memcpy(hdr->addr3, bssid, ETH_ALEN);
1270
1271 return dev_ops->send_mlme(if_ctx->dev_priv, buf, 24 + data_len,
1272 0, freq, no_cck, 1,
1273 wait_time, 0);
1274 }
1275
nl80211_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)1276 static int nl80211_get_ext_capab(void *priv, enum wpa_driver_if_type type,
1277 const u8 **ext_capa, const u8 **ext_capa_mask,
1278 unsigned int *ext_capa_len)
1279 {
1280 struct wpa_driver_capa capa;
1281
1282 wpa_drv_zep_get_capa(priv, &capa);
1283
1284 /* By default, use the per-radio values */
1285 *ext_capa = capa.extended_capa;
1286 *ext_capa_mask = capa.extended_capa_mask;
1287 *ext_capa_len = capa.extended_capa_len;
1288
1289 return 0;
1290 }
1291
wpa_drv_zep_get_conn_info(void * priv,struct wpa_conn_info * ci)1292 static int wpa_drv_zep_get_conn_info(void *priv, struct wpa_conn_info *ci)
1293 {
1294 struct zep_drv_if_ctx *if_ctx = NULL;
1295 const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
1296 int ret = -1;
1297
1298 if (!priv) {
1299 wpa_printf(MSG_ERROR, "%s: Invalid handle", __func__);
1300 goto out;
1301 }
1302
1303 if (!ci) {
1304 wpa_printf(MSG_ERROR, "%s: Invalid params", __func__);
1305 goto out;
1306 }
1307
1308 if_ctx = priv;
1309 dev_ops = get_dev_ops(if_ctx->dev_ctx);
1310
1311 if (!dev_ops) {
1312 wpa_printf(MSG_ERROR, "%s:Failed to get config handle", __func__);
1313 goto out;
1314 }
1315
1316 if (dev_ops->get_conn_info) {
1317 ret = dev_ops->get_conn_info(if_ctx->dev_priv, ci);
1318 if (ret) {
1319 wpa_printf(MSG_ERROR, "%s: Failed to get connection info: %d", __func__, ret);
1320 goto out;
1321 }
1322 } else {
1323 wpa_printf(MSG_ERROR, "%s: Getting connection info is not supported", __func__);
1324 goto out;
1325 }
1326
1327 out:
1328 return ret;
1329 }
1330
1331 const struct wpa_driver_ops wpa_driver_zep_ops = {
1332 .name = "zephyr",
1333 .desc = "Zephyr wpa_supplicant driver",
1334 .global_init = wpa_drv_zep_global_init,
1335 .global_deinit = wpa_drv_zep_global_deinit,
1336 .init2 = wpa_drv_zep_init,
1337 .deinit = wpa_drv_zep_deinit,
1338 .scan2 = wpa_drv_zep_scan2,
1339 .abort_scan = wpa_drv_zep_abort_scan,
1340 .get_scan_results2 = wpa_drv_zep_get_scan_results2,
1341 .authenticate = wpa_drv_zep_authenticate,
1342 .associate = wpa_drv_zep_associate,
1343 .get_capa = wpa_drv_zep_get_capa,
1344 .get_bssid = wpa_drv_zep_get_bssid,
1345 .get_ssid = wpa_drv_zep_get_ssid,
1346 .set_supp_port = wpa_drv_zep_set_supp_port,
1347 .deauthenticate = wpa_drv_zep_deauthenticate,
1348 .set_key = wpa_drv_zep_set_key,
1349 .signal_poll = wpa_drv_zep_signal_poll,
1350 .send_action = wpa_drv_zep_send_action,
1351 .get_hw_feature_data = wpa_drv_get_hw_feature_data,
1352 .get_ext_capab = nl80211_get_ext_capab,
1353 .get_conn_info = wpa_drv_zep_get_conn_info,
1354 };
1355