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