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