xref: /freebsd/contrib/wpa/src/ap/ap_drv_ops.c (revision 4436b51dff5736e74da464946049ea6899a88938)
1 /*
2  * hostapd - Driver operations
3  * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "common/ieee802_11_defs.h"
13 #include "common/hw_features_common.h"
14 #include "wps/wps.h"
15 #include "p2p/p2p.h"
16 #include "hostapd.h"
17 #include "ieee802_11.h"
18 #include "sta_info.h"
19 #include "ap_config.h"
20 #include "p2p_hostapd.h"
21 #include "hs20.h"
22 #include "ap_drv_ops.h"
23 
24 
25 u32 hostapd_sta_flags_to_drv(u32 flags)
26 {
27 	int res = 0;
28 	if (flags & WLAN_STA_AUTHORIZED)
29 		res |= WPA_STA_AUTHORIZED;
30 	if (flags & WLAN_STA_WMM)
31 		res |= WPA_STA_WMM;
32 	if (flags & WLAN_STA_SHORT_PREAMBLE)
33 		res |= WPA_STA_SHORT_PREAMBLE;
34 	if (flags & WLAN_STA_MFP)
35 		res |= WPA_STA_MFP;
36 	return res;
37 }
38 
39 
40 int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
41 			       struct wpabuf **beacon_ret,
42 			       struct wpabuf **proberesp_ret,
43 			       struct wpabuf **assocresp_ret)
44 {
45 	struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
46 	u8 buf[200], *pos;
47 
48 	*beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
49 
50 	pos = buf;
51 	pos = hostapd_eid_time_adv(hapd, pos);
52 	if (pos != buf) {
53 		if (wpabuf_resize(&beacon, pos - buf) != 0)
54 			goto fail;
55 		wpabuf_put_data(beacon, buf, pos - buf);
56 	}
57 	pos = hostapd_eid_time_zone(hapd, pos);
58 	if (pos != buf) {
59 		if (wpabuf_resize(&proberesp, pos - buf) != 0)
60 			goto fail;
61 		wpabuf_put_data(proberesp, buf, pos - buf);
62 	}
63 
64 	pos = buf;
65 	pos = hostapd_eid_ext_capab(hapd, pos);
66 	if (pos != buf) {
67 		if (wpabuf_resize(&assocresp, pos - buf) != 0)
68 			goto fail;
69 		wpabuf_put_data(assocresp, buf, pos - buf);
70 	}
71 	pos = hostapd_eid_interworking(hapd, pos);
72 	pos = hostapd_eid_adv_proto(hapd, pos);
73 	pos = hostapd_eid_roaming_consortium(hapd, pos);
74 	if (pos != buf) {
75 		if (wpabuf_resize(&beacon, pos - buf) != 0)
76 			goto fail;
77 		wpabuf_put_data(beacon, buf, pos - buf);
78 
79 		if (wpabuf_resize(&proberesp, pos - buf) != 0)
80 			goto fail;
81 		wpabuf_put_data(proberesp, buf, pos - buf);
82 	}
83 
84 	if (hapd->wps_beacon_ie) {
85 		if (wpabuf_resize(&beacon, wpabuf_len(hapd->wps_beacon_ie)) <
86 		    0)
87 			goto fail;
88 		wpabuf_put_buf(beacon, hapd->wps_beacon_ie);
89 	}
90 
91 	if (hapd->wps_probe_resp_ie) {
92 		if (wpabuf_resize(&proberesp,
93 				  wpabuf_len(hapd->wps_probe_resp_ie)) < 0)
94 			goto fail;
95 		wpabuf_put_buf(proberesp, hapd->wps_probe_resp_ie);
96 	}
97 
98 #ifdef CONFIG_P2P
99 	if (hapd->p2p_beacon_ie) {
100 		if (wpabuf_resize(&beacon, wpabuf_len(hapd->p2p_beacon_ie)) <
101 		    0)
102 			goto fail;
103 		wpabuf_put_buf(beacon, hapd->p2p_beacon_ie);
104 	}
105 
106 	if (hapd->p2p_probe_resp_ie) {
107 		if (wpabuf_resize(&proberesp,
108 				  wpabuf_len(hapd->p2p_probe_resp_ie)) < 0)
109 			goto fail;
110 		wpabuf_put_buf(proberesp, hapd->p2p_probe_resp_ie);
111 	}
112 #endif /* CONFIG_P2P */
113 
114 #ifdef CONFIG_P2P_MANAGER
115 	if (hapd->conf->p2p & P2P_MANAGE) {
116 		if (wpabuf_resize(&beacon, 100) == 0) {
117 			u8 *start, *p;
118 			start = wpabuf_put(beacon, 0);
119 			p = hostapd_eid_p2p_manage(hapd, start);
120 			wpabuf_put(beacon, p - start);
121 		}
122 
123 		if (wpabuf_resize(&proberesp, 100) == 0) {
124 			u8 *start, *p;
125 			start = wpabuf_put(proberesp, 0);
126 			p = hostapd_eid_p2p_manage(hapd, start);
127 			wpabuf_put(proberesp, p - start);
128 		}
129 	}
130 #endif /* CONFIG_P2P_MANAGER */
131 
132 #ifdef CONFIG_WPS
133 	if (hapd->conf->wps_state) {
134 		struct wpabuf *a = wps_build_assoc_resp_ie();
135 		if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
136 			wpabuf_put_buf(assocresp, a);
137 		wpabuf_free(a);
138 	}
139 #endif /* CONFIG_WPS */
140 
141 #ifdef CONFIG_P2P_MANAGER
142 	if (hapd->conf->p2p & P2P_MANAGE) {
143 		if (wpabuf_resize(&assocresp, 100) == 0) {
144 			u8 *start, *p;
145 			start = wpabuf_put(assocresp, 0);
146 			p = hostapd_eid_p2p_manage(hapd, start);
147 			wpabuf_put(assocresp, p - start);
148 		}
149 	}
150 #endif /* CONFIG_P2P_MANAGER */
151 
152 #ifdef CONFIG_WIFI_DISPLAY
153 	if (hapd->p2p_group) {
154 		struct wpabuf *a;
155 		a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
156 		if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
157 			wpabuf_put_buf(assocresp, a);
158 		wpabuf_free(a);
159 	}
160 #endif /* CONFIG_WIFI_DISPLAY */
161 
162 #ifdef CONFIG_HS20
163 	pos = buf;
164 	pos = hostapd_eid_hs20_indication(hapd, pos);
165 	if (pos != buf) {
166 		if (wpabuf_resize(&beacon, pos - buf) != 0)
167 			goto fail;
168 		wpabuf_put_data(beacon, buf, pos - buf);
169 
170 		if (wpabuf_resize(&proberesp, pos - buf) != 0)
171 			goto fail;
172 		wpabuf_put_data(proberesp, buf, pos - buf);
173 	}
174 
175 	pos = hostapd_eid_osen(hapd, buf);
176 	if (pos != buf) {
177 		if (wpabuf_resize(&beacon, pos - buf) != 0)
178 			goto fail;
179 		wpabuf_put_data(beacon, buf, pos - buf);
180 
181 		if (wpabuf_resize(&proberesp, pos - buf) != 0)
182 			goto fail;
183 		wpabuf_put_data(proberesp, buf, pos - buf);
184 	}
185 #endif /* CONFIG_HS20 */
186 
187 	if (hapd->conf->vendor_elements) {
188 		size_t add = wpabuf_len(hapd->conf->vendor_elements);
189 		if (wpabuf_resize(&beacon, add) == 0)
190 			wpabuf_put_buf(beacon, hapd->conf->vendor_elements);
191 		if (wpabuf_resize(&proberesp, add) == 0)
192 			wpabuf_put_buf(proberesp, hapd->conf->vendor_elements);
193 	}
194 
195 	*beacon_ret = beacon;
196 	*proberesp_ret = proberesp;
197 	*assocresp_ret = assocresp;
198 
199 	return 0;
200 
201 fail:
202 	wpabuf_free(beacon);
203 	wpabuf_free(proberesp);
204 	wpabuf_free(assocresp);
205 	return -1;
206 }
207 
208 
209 void hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
210 			       struct wpabuf *beacon,
211 			       struct wpabuf *proberesp,
212 			       struct wpabuf *assocresp)
213 {
214 	wpabuf_free(beacon);
215 	wpabuf_free(proberesp);
216 	wpabuf_free(assocresp);
217 }
218 
219 
220 int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
221 {
222 	struct wpabuf *beacon, *proberesp, *assocresp;
223 	int ret;
224 
225 	if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
226 		return 0;
227 
228 	if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
229 	    0)
230 		return -1;
231 
232 	ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
233 					  assocresp);
234 
235 	hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
236 
237 	return ret;
238 }
239 
240 
241 int hostapd_set_authorized(struct hostapd_data *hapd,
242 			   struct sta_info *sta, int authorized)
243 {
244 	if (authorized) {
245 		return hostapd_sta_set_flags(hapd, sta->addr,
246 					     hostapd_sta_flags_to_drv(
247 						     sta->flags),
248 					     WPA_STA_AUTHORIZED, ~0);
249 	}
250 
251 	return hostapd_sta_set_flags(hapd, sta->addr,
252 				     hostapd_sta_flags_to_drv(sta->flags),
253 				     0, ~WPA_STA_AUTHORIZED);
254 }
255 
256 
257 int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
258 {
259 	int set_flags, total_flags, flags_and, flags_or;
260 	total_flags = hostapd_sta_flags_to_drv(sta->flags);
261 	set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
262 	if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
263 	     sta->auth_alg == WLAN_AUTH_FT) &&
264 	    sta->flags & WLAN_STA_AUTHORIZED)
265 		set_flags |= WPA_STA_AUTHORIZED;
266 	flags_or = total_flags & set_flags;
267 	flags_and = total_flags | ~set_flags;
268 	return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
269 				     flags_or, flags_and);
270 }
271 
272 
273 int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
274 			      int enabled)
275 {
276 	struct wpa_bss_params params;
277 	os_memset(&params, 0, sizeof(params));
278 	params.ifname = ifname;
279 	params.enabled = enabled;
280 	if (enabled) {
281 		params.wpa = hapd->conf->wpa;
282 		params.ieee802_1x = hapd->conf->ieee802_1x;
283 		params.wpa_group = hapd->conf->wpa_group;
284 		params.wpa_pairwise = hapd->conf->wpa_pairwise |
285 			hapd->conf->rsn_pairwise;
286 		params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
287 		params.rsn_preauth = hapd->conf->rsn_preauth;
288 #ifdef CONFIG_IEEE80211W
289 		params.ieee80211w = hapd->conf->ieee80211w;
290 #endif /* CONFIG_IEEE80211W */
291 	}
292 	return hostapd_set_ieee8021x(hapd, &params);
293 }
294 
295 
296 int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
297 {
298 	char force_ifname[IFNAMSIZ];
299 	u8 if_addr[ETH_ALEN];
300 	return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
301 			      NULL, NULL, force_ifname, if_addr, NULL, 0);
302 }
303 
304 
305 int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
306 {
307 	return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
308 }
309 
310 
311 int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
312 			const u8 *addr, int aid, int val)
313 {
314 	const char *bridge = NULL;
315 
316 	if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
317 		return -1;
318 	if (hapd->conf->wds_bridge[0])
319 		bridge = hapd->conf->wds_bridge;
320 	else if (hapd->conf->bridge[0])
321 		bridge = hapd->conf->bridge;
322 	return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
323 					 bridge, ifname_wds);
324 }
325 
326 
327 int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
328 			 u16 auth_alg)
329 {
330 	if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
331 		return 0;
332 	return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
333 }
334 
335 
336 int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
337 		     u16 seq, u16 status, const u8 *ie, size_t len)
338 {
339 	if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
340 		return 0;
341 	return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr,
342 				      seq, status, ie, len);
343 }
344 
345 
346 int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
347 		      int reassoc, u16 status, const u8 *ie, size_t len)
348 {
349 	if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
350 		return 0;
351 	return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
352 				       reassoc, status, ie, len);
353 }
354 
355 
356 int hostapd_sta_add(struct hostapd_data *hapd,
357 		    const u8 *addr, u16 aid, u16 capability,
358 		    const u8 *supp_rates, size_t supp_rates_len,
359 		    u16 listen_interval,
360 		    const struct ieee80211_ht_capabilities *ht_capab,
361 		    const struct ieee80211_vht_capabilities *vht_capab,
362 		    u32 flags, u8 qosinfo, u8 vht_opmode)
363 {
364 	struct hostapd_sta_add_params params;
365 
366 	if (hapd->driver == NULL)
367 		return 0;
368 	if (hapd->driver->sta_add == NULL)
369 		return 0;
370 
371 	os_memset(&params, 0, sizeof(params));
372 	params.addr = addr;
373 	params.aid = aid;
374 	params.capability = capability;
375 	params.supp_rates = supp_rates;
376 	params.supp_rates_len = supp_rates_len;
377 	params.listen_interval = listen_interval;
378 	params.ht_capabilities = ht_capab;
379 	params.vht_capabilities = vht_capab;
380 	params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
381 	params.vht_opmode = vht_opmode;
382 	params.flags = hostapd_sta_flags_to_drv(flags);
383 	params.qosinfo = qosinfo;
384 	return hapd->driver->sta_add(hapd->drv_priv, &params);
385 }
386 
387 
388 int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
389 		      u8 *tspec_ie, size_t tspec_ielen)
390 {
391 	if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
392 		return 0;
393 	return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
394 				       tspec_ielen);
395 }
396 
397 
398 int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
399 {
400 	if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
401 		return 0;
402 	return hapd->driver->set_privacy(hapd->drv_priv, enabled);
403 }
404 
405 
406 int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
407 			     size_t elem_len)
408 {
409 	if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
410 		return 0;
411 	return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
412 }
413 
414 
415 int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
416 {
417 	if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
418 		return 0;
419 	return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
420 }
421 
422 
423 int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
424 {
425 	if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
426 		return 0;
427 	return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
428 }
429 
430 
431 int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
432 		   const char *ifname, const u8 *addr, void *bss_ctx,
433 		   void **drv_priv, char *force_ifname, u8 *if_addr,
434 		   const char *bridge, int use_existing)
435 {
436 	if (hapd->driver == NULL || hapd->driver->if_add == NULL)
437 		return -1;
438 	return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
439 				    bss_ctx, drv_priv, force_ifname, if_addr,
440 				    bridge, use_existing);
441 }
442 
443 
444 int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
445 		      const char *ifname)
446 {
447 	if (hapd->driver == NULL || hapd->drv_priv == NULL ||
448 	    hapd->driver->if_remove == NULL)
449 		return -1;
450 	return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
451 }
452 
453 
454 int hostapd_set_ieee8021x(struct hostapd_data *hapd,
455 			  struct wpa_bss_params *params)
456 {
457 	if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
458 		return 0;
459 	return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
460 }
461 
462 
463 int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
464 		       const u8 *addr, int idx, u8 *seq)
465 {
466 	if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
467 		return 0;
468 	return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
469 					seq);
470 }
471 
472 
473 int hostapd_flush(struct hostapd_data *hapd)
474 {
475 	if (hapd->driver == NULL || hapd->driver->flush == NULL)
476 		return 0;
477 	return hapd->driver->flush(hapd->drv_priv);
478 }
479 
480 
481 int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
482 		     int freq, int channel, int ht_enabled, int vht_enabled,
483 		     int sec_channel_offset, int vht_oper_chwidth,
484 		     int center_segment0, int center_segment1)
485 {
486 	struct hostapd_freq_params data;
487 
488 	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
489 				    vht_enabled, sec_channel_offset,
490 				    vht_oper_chwidth,
491 				    center_segment0, center_segment1,
492 				    hapd->iface->current_mode ?
493 				    hapd->iface->current_mode->vht_capab : 0))
494 		return -1;
495 
496 	if (hapd->driver == NULL)
497 		return 0;
498 	if (hapd->driver->set_freq == NULL)
499 		return 0;
500 	return hapd->driver->set_freq(hapd->drv_priv, &data);
501 }
502 
503 int hostapd_set_rts(struct hostapd_data *hapd, int rts)
504 {
505 	if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
506 		return 0;
507 	return hapd->driver->set_rts(hapd->drv_priv, rts);
508 }
509 
510 
511 int hostapd_set_frag(struct hostapd_data *hapd, int frag)
512 {
513 	if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
514 		return 0;
515 	return hapd->driver->set_frag(hapd->drv_priv, frag);
516 }
517 
518 
519 int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
520 			  int total_flags, int flags_or, int flags_and)
521 {
522 	if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
523 		return 0;
524 	return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
525 					   flags_or, flags_and);
526 }
527 
528 
529 int hostapd_set_country(struct hostapd_data *hapd, const char *country)
530 {
531 	if (hapd->driver == NULL ||
532 	    hapd->driver->set_country == NULL)
533 		return 0;
534 	return hapd->driver->set_country(hapd->drv_priv, country);
535 }
536 
537 
538 int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
539 				int cw_min, int cw_max, int burst_time)
540 {
541 	if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
542 		return 0;
543 	return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
544 						 cw_min, cw_max, burst_time);
545 }
546 
547 
548 struct hostapd_hw_modes *
549 hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
550 			    u16 *flags)
551 {
552 	if (hapd->driver == NULL ||
553 	    hapd->driver->get_hw_feature_data == NULL)
554 		return NULL;
555 	return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
556 						 flags);
557 }
558 
559 
560 int hostapd_driver_commit(struct hostapd_data *hapd)
561 {
562 	if (hapd->driver == NULL || hapd->driver->commit == NULL)
563 		return 0;
564 	return hapd->driver->commit(hapd->drv_priv);
565 }
566 
567 
568 int hostapd_drv_none(struct hostapd_data *hapd)
569 {
570 	return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
571 }
572 
573 
574 int hostapd_driver_scan(struct hostapd_data *hapd,
575 			struct wpa_driver_scan_params *params)
576 {
577 	if (hapd->driver && hapd->driver->scan2)
578 		return hapd->driver->scan2(hapd->drv_priv, params);
579 	return -1;
580 }
581 
582 
583 struct wpa_scan_results * hostapd_driver_get_scan_results(
584 	struct hostapd_data *hapd)
585 {
586 	if (hapd->driver && hapd->driver->get_scan_results2)
587 		return hapd->driver->get_scan_results2(hapd->drv_priv);
588 	return NULL;
589 }
590 
591 
592 int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
593 			   int duration)
594 {
595 	if (hapd->driver && hapd->driver->set_noa)
596 		return hapd->driver->set_noa(hapd->drv_priv, count, start,
597 					     duration);
598 	return -1;
599 }
600 
601 
602 int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
603 			enum wpa_alg alg, const u8 *addr,
604 			int key_idx, int set_tx,
605 			const u8 *seq, size_t seq_len,
606 			const u8 *key, size_t key_len)
607 {
608 	if (hapd->driver == NULL || hapd->driver->set_key == NULL)
609 		return 0;
610 	return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
611 				     key_idx, set_tx, seq, seq_len, key,
612 				     key_len);
613 }
614 
615 
616 int hostapd_drv_send_mlme(struct hostapd_data *hapd,
617 			  const void *msg, size_t len, int noack)
618 {
619 	if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
620 		return 0;
621 	return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack);
622 }
623 
624 
625 int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
626 			   const u8 *addr, int reason)
627 {
628 	if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
629 		return 0;
630 	return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
631 					reason);
632 }
633 
634 
635 int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
636 			     const u8 *addr, int reason)
637 {
638 	if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
639 		return 0;
640 	return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
641 					  reason);
642 }
643 
644 
645 int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
646 			 const u8 *peer, u8 *buf, u16 *buf_len)
647 {
648 	if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
649 		return -1;
650 	return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
651 				      buf_len);
652 }
653 
654 
655 int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
656 			    unsigned int wait, const u8 *dst, const u8 *data,
657 			    size_t len)
658 {
659 	if (hapd->driver == NULL || hapd->driver->send_action == NULL)
660 		return 0;
661 	return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
662 					 hapd->own_addr, hapd->own_addr, data,
663 					 len, 0);
664 }
665 
666 
667 int hostapd_start_dfs_cac(struct hostapd_iface *iface,
668 			  enum hostapd_hw_mode mode, int freq,
669 			  int channel, int ht_enabled, int vht_enabled,
670 			  int sec_channel_offset, int vht_oper_chwidth,
671 			  int center_segment0, int center_segment1)
672 {
673 	struct hostapd_data *hapd = iface->bss[0];
674 	struct hostapd_freq_params data;
675 	int res;
676 
677 	if (!hapd->driver || !hapd->driver->start_dfs_cac)
678 		return 0;
679 
680 	if (!iface->conf->ieee80211h) {
681 		wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
682 			   "is not enabled");
683 		return -1;
684 	}
685 
686 	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
687 				    vht_enabled, sec_channel_offset,
688 				    vht_oper_chwidth, center_segment0,
689 				    center_segment1,
690 				    iface->current_mode->vht_capab)) {
691 		wpa_printf(MSG_ERROR, "Can't set freq params");
692 		return -1;
693 	}
694 
695 	res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
696 	if (!res) {
697 		iface->cac_started = 1;
698 		os_get_reltime(&iface->dfs_cac_start);
699 	}
700 
701 	return res;
702 }
703 
704 
705 int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
706 			    const u8 *qos_map_set, u8 qos_map_set_len)
707 {
708 	if (hapd->driver == NULL || hapd->driver->set_qos_map == NULL)
709 		return 0;
710 	return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
711 					 qos_map_set_len);
712 }
713 
714 
715 int hostapd_drv_do_acs(struct hostapd_data *hapd)
716 {
717 	struct drv_acs_params params;
718 
719 	if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
720 		return 0;
721 	os_memset(&params, 0, sizeof(params));
722 	params.hw_mode = hapd->iface->conf->hw_mode;
723 	params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
724 	params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
725 				 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET);
726 	return hapd->driver->do_acs(hapd->drv_priv, &params);
727 }
728