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