1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: wlan_hdd_hostapd_wext.c
22  *
23  * Linux Wireless Extensions Implementation
24  */
25 
26 #include "osif_sync.h"
27 #include <wlan_hdd_hostapd_wext.h>
28 #include <wlan_hdd_includes.h>
29 #include <qc_sap_ioctl.h>
30 #include <wlan_hdd_green_ap.h>
31 #include <wlan_hdd_hostapd.h>
32 #include <wlan_hdd_ioctl.h>
33 #include <wlan_hdd_stats.h>
34 #include "wlan_hdd_p2p.h"
35 #include "wma.h"
36 #ifdef WLAN_DEBUG
37 #include "wma_api.h"
38 #endif
39 #include "wlan_hdd_power.h"
40 #include "wlan_policy_mgr_ucfg.h"
41 #include <ol_defines.h>
42 #include <cdp_txrx_stats.h>
43 #include "wlan_dfs_utils_api.h"
44 #include <wlan_ipa_ucfg_api.h>
45 #include <wlan_cfg80211_mc_cp_stats.h>
46 #include "wlan_mlme_ucfg_api.h"
47 #include "wlan_reg_ucfg_api.h"
48 #include "wlan_hdd_sta_info.h"
49 #include "wlan_hdd_object_manager.h"
50 #include "wlan_dp_ucfg_api.h"
51 #include "cfg_ucfg_api.h"
52 
53 #define WE_WLAN_VERSION     1
54 
55 /* WEXT limitation: MAX allowed buf len for any *
56  * IW_PRIV_TYPE_CHAR is 2Kbytes *
57  */
58 #define WE_SAP_MAX_STA_INFO 0x7FF
59 
60 #define RC_2_RATE_IDX(_rc)        ((_rc) & 0x7)
61 #define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
62 #define RC_2_RATE_IDX_11AC(_rc)        ((_rc) & 0xf)
63 #define HT_RC_2_STREAMS_11AC(_rc)    ((((_rc) & 0x30) >> 4) + 1)
64 
hdd_sap_get_chan_width(struct hdd_adapter * adapter,int * value)65 static int hdd_sap_get_chan_width(struct hdd_adapter *adapter, int *value)
66 {
67 	struct sap_context *sap_ctx;
68 	struct hdd_hostapd_state *hostapdstate;
69 
70 	hdd_enter();
71 	hostapdstate = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter->deflink);
72 
73 	if (hostapdstate->bss_state != BSS_START) {
74 		*value = -EINVAL;
75 		return -EINVAL;
76 	}
77 
78 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink);
79 
80 	*value = wlansap_get_chan_width(sap_ctx);
81 	hdd_debug("chan_width = %d", *value);
82 
83 	return 0;
84 }
85 
86 int
__iw_softap_get_ini_cfg(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)87 static __iw_softap_get_ini_cfg(struct net_device *dev,
88 			       struct iw_request_info *info,
89 			       union iwreq_data *wrqu, char *extra)
90 {
91 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
92 	struct hdd_context *hdd_ctx;
93 	int ret;
94 
95 	hdd_enter_dev(dev);
96 
97 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
98 	ret = wlan_hdd_validate_context(hdd_ctx);
99 	if (ret != 0)
100 		return ret;
101 
102 	ret = hdd_check_private_wext_control(hdd_ctx, info);
103 	if (0 != ret)
104 		return ret;
105 
106 	hdd_debug("Printing CLD global INI Config");
107 	hdd_cfg_get_global_config(hdd_ctx, extra, QCSAP_IOCTL_MAX_STR_LEN);
108 	wrqu->data.length = strlen(extra) + 1;
109 
110 	return 0;
111 }
112 
113 int
iw_softap_get_ini_cfg(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)114 static iw_softap_get_ini_cfg(struct net_device *dev,
115 			     struct iw_request_info *info,
116 			     union iwreq_data *wrqu, char *extra)
117 {
118 	int errno;
119 	struct osif_vdev_sync *vdev_sync;
120 
121 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
122 	if (errno)
123 		return errno;
124 
125 	errno = __iw_softap_get_ini_cfg(dev, info, wrqu, extra);
126 
127 	osif_vdev_sync_op_stop(vdev_sync);
128 
129 	return errno;
130 }
131 
132 /**
133  * __iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler
134  * @dev: device upon which the ioctl was received
135  * @info: ioctl request information
136  * @wrqu: ioctl request data
137  * @extra: ioctl extra data
138  *
139  * Return: 0 on success, non-zero on error
140  */
__iw_softap_set_two_ints_getnone(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)141 static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
142 					    struct iw_request_info *info,
143 					    union iwreq_data *wrqu, char *extra)
144 {
145 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
146 	int ret;
147 	int *value = (int *)extra;
148 	int sub_cmd = value[0];
149 	struct hdd_context *hdd_ctx;
150 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
151 	struct cdp_txrx_stats_req req = {0};
152 	struct hdd_station_info *sta_info, *tmp = NULL;
153 
154 	hdd_enter_dev(dev);
155 
156 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
157 	ret = wlan_hdd_validate_context(hdd_ctx);
158 	if (ret != 0)
159 		return ret;
160 
161 	ret = hdd_check_private_wext_control(hdd_ctx, info);
162 	if (0 != ret)
163 		return ret;
164 
165 	if (qdf_unlikely(!soc)) {
166 		hdd_err("soc is NULL");
167 		return -EINVAL;
168 	}
169 
170 	switch (sub_cmd) {
171 	case QCSAP_PARAM_SET_TXRX_STATS:
172 	{
173 		req.stats = value[1];
174 		req.mac_id = value[2];
175 		hdd_info("QCSAP_PARAM_SET_TXRX_STATS stats_id: %d mac_id: %d",
176 			req.stats, req.mac_id);
177 
178 		if (value[1] == CDP_TXRX_STATS_28) {
179 			req.peer_addr = (char *)&adapter->mac_addr;
180 			ret = cdp_txrx_stats_request(soc,
181 						     adapter->deflink->vdev_id,
182 						     &req);
183 
184 			hdd_for_each_sta_ref_safe(
185 					adapter->sta_info_list, sta_info, tmp,
186 					STA_INFO_SAP_SET_TWO_INTS_GETNONE) {
187 				hdd_debug("bss_id: " QDF_MAC_ADDR_FMT,
188 					  QDF_MAC_ADDR_REF(
189 					  sta_info->sta_mac.bytes));
190 
191 				req.peer_addr = (char *)
192 					&sta_info->sta_mac;
193 				ret = cdp_txrx_stats_request(
194 					soc, adapter->deflink->vdev_id, &req);
195 				hdd_put_sta_info_ref(
196 					&adapter->sta_info_list, &sta_info,
197 					true,
198 					STA_INFO_SAP_SET_TWO_INTS_GETNONE);
199 			}
200 		} else {
201 			ret = cdp_txrx_stats_request(soc,
202 						     adapter->deflink->vdev_id,
203 						     &req);
204 		}
205 
206 		break;
207 	}
208 
209 	/* Firmware debug log */
210 	case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
211 		ret = hdd_crash_inject(adapter, value[1], value[2]);
212 		break;
213 
214 	case QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL:
215 		hdd_set_dump_dp_trace(value[1], value[2]);
216 		break;
217 
218 	case QCSAP_ENABLE_FW_PROFILE:
219 		hdd_debug("QCSAP_ENABLE_FW_PROFILE: %d %d",
220 		       value[1], value[2]);
221 		ret = wma_cli_set2_command(
222 				adapter->deflink->vdev_id,
223 				WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
224 				value[1], value[2], DBG_CMD);
225 		break;
226 
227 	case QCSAP_SET_FW_PROFILE_HIST_INTVL:
228 		hdd_debug("QCSAP_SET_FW_PROFILE_HIST_INTVL: %d %d",
229 		       value[1], value[2]);
230 		ret = wma_cli_set2_command(
231 					adapter->deflink->vdev_id,
232 					WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
233 					value[1], value[2], DBG_CMD);
234 		break;
235 
236 	case QCSAP_SET_WLAN_SUSPEND:
237 		hdd_info("SAP unit-test suspend(%d, %d)", value[1], value[2]);
238 		ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev,
239 						 value[1], value[2]);
240 		break;
241 
242 	case QCSAP_SET_WLAN_RESUME:
243 		ret = hdd_wlan_fake_apps_resume(hdd_ctx->wiphy, dev);
244 		break;
245 
246 	case QCSAP_SET_BA_AGEING_TIMEOUT:
247 		hdd_info("QCSAP_SET_BA_AGEING_TIMEOUT: AC[%d] timeout[%d]",
248 			 value[1], value[2]);
249 		/*
250 		 *  value[1] : suppose to be access class, value between[0-3]
251 		 *  value[2]: suppose to be duration in seconds
252 		 */
253 		cdp_set_ba_timeout(soc, value[1], value[2]);
254 		break;
255 
256 	default:
257 		hdd_err("Invalid IOCTL command: %d", sub_cmd);
258 		break;
259 	}
260 
261 	return ret;
262 }
263 
264 /**
265  * iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler
266  * @dev: device upon which the ioctl was received
267  * @info: ioctl request information
268  * @wrqu: ioctl request data
269  * @extra: ioctl extra data
270  *
271  * Return: 0 on success, non-zero on error
272  */
iw_softap_set_two_ints_getnone(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)273 static int iw_softap_set_two_ints_getnone(struct net_device *dev,
274 					  struct iw_request_info *info,
275 					  union iwreq_data *wrqu, char *extra)
276 {
277 	int errno;
278 	struct osif_vdev_sync *vdev_sync;
279 
280 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
281 	if (errno)
282 		return errno;
283 
284 	errno = __iw_softap_set_two_ints_getnone(dev, info, wrqu, extra);
285 
286 	osif_vdev_sync_op_stop(vdev_sync);
287 
288 	return errno;
289 }
290 
print_mac_list(struct qdf_mac_addr * macList,uint8_t size)291 static void print_mac_list(struct qdf_mac_addr *macList, uint8_t size)
292 {
293 	int i;
294 	uint8_t *macArray;
295 
296 	for (i = 0; i < size; i++) {
297 		macArray = (macList + i)->bytes;
298 		pr_info("ACL entry %i - "QDF_MAC_ADDR_FMT"\n",
299 			i, QDF_MAC_ADDR_REF(macArray));
300 	}
301 }
302 
hdd_print_acl(struct hdd_adapter * adapter)303 static QDF_STATUS hdd_print_acl(struct hdd_adapter *adapter)
304 {
305 	eSapMacAddrACL acl_mode;
306 	struct qdf_mac_addr maclist[MAX_ACL_MAC_ADDRESS];
307 	uint16_t listnum;
308 	struct sap_context *sap_ctx;
309 
310 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink);
311 	qdf_mem_zero(&maclist[0], sizeof(maclist));
312 	if (QDF_STATUS_SUCCESS == wlansap_get_acl_mode(sap_ctx, &acl_mode)) {
313 		pr_info("******** ACL MODE *********\n");
314 		switch (acl_mode) {
315 		case eSAP_ACCEPT_UNLESS_DENIED:
316 			pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n");
317 			break;
318 		case eSAP_DENY_UNLESS_ACCEPTED:
319 			pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n");
320 			break;
321 		case eSAP_SUPPORT_ACCEPT_AND_DENY:
322 			pr_info("ACL Mode = ACCEPT_AND_DENY\n");
323 			break;
324 		case eSAP_ALLOW_ALL:
325 			pr_info("ACL Mode = ALLOW_ALL\n");
326 			break;
327 		default:
328 			pr_info("Invalid SAP ACL Mode = %d\n", acl_mode);
329 			return QDF_STATUS_E_FAILURE;
330 		}
331 	} else {
332 		return QDF_STATUS_E_FAILURE;
333 	}
334 
335 	if (QDF_STATUS_SUCCESS == wlansap_get_acl_accept_list(sap_ctx,
336 							      &maclist[0],
337 							      &listnum)) {
338 		pr_info("******* ALLOW LIST ***********\n");
339 		if (listnum <= MAX_ACL_MAC_ADDRESS)
340 			print_mac_list(&maclist[0], listnum);
341 	} else {
342 		return QDF_STATUS_E_FAILURE;
343 	}
344 
345 	if (QDF_STATUS_SUCCESS == wlansap_get_acl_deny_list(sap_ctx,
346 							    &maclist[0],
347 							    &listnum)) {
348 		pr_info("******* DENY LIST ***********\n");
349 		if (listnum <= MAX_ACL_MAC_ADDRESS)
350 			print_mac_list(&maclist[0], listnum);
351 	} else {
352 		return QDF_STATUS_E_FAILURE;
353 	}
354 	return QDF_STATUS_SUCCESS;
355 }
356 
357 int
__iw_softap_setparam(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)358 static __iw_softap_setparam(struct net_device *dev,
359 			    struct iw_request_info *info,
360 			    union iwreq_data *wrqu, char *extra)
361 {
362 	struct hdd_adapter *adapter = (netdev_priv(dev));
363 	mac_handle_t mac_handle;
364 	int *value = (int *)extra;
365 	int sub_cmd = value[0];
366 	int set_value = value[1];
367 	QDF_STATUS status;
368 	int ret = 0;
369 	struct hdd_context *hdd_ctx;
370 	bool bval = false;
371 	struct wlan_hdd_link_info *link_info = adapter->deflink;
372 
373 	hdd_enter_dev(dev);
374 
375 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
376 	ret = wlan_hdd_validate_context(hdd_ctx);
377 	if (0 != ret)
378 		return -EINVAL;
379 
380 	ret = hdd_check_private_wext_control(hdd_ctx, info);
381 	if (0 != ret)
382 		return ret;
383 
384 	mac_handle = hdd_ctx->mac_handle;
385 	if (!mac_handle) {
386 		hdd_err("mac handle is null");
387 		return -EINVAL;
388 	}
389 
390 	switch (sub_cmd) {
391 	case QCASAP_SET_RADAR_DBG:
392 		hdd_debug("QCASAP_SET_RADAR_DBG called with: value: %x",
393 				set_value);
394 		wlan_sap_enable_phy_error_logs(mac_handle, set_value);
395 		break;
396 
397 	case QCSAP_PARAM_CLR_ACL:
398 		if (QDF_STATUS_SUCCESS != wlansap_clear_acl(
399 		    WLAN_HDD_GET_SAP_CTX_PTR(link_info))) {
400 			ret = -EIO;
401 		}
402 		break;
403 
404 	case QCSAP_PARAM_ACL_MODE:
405 		if ((eSAP_ALLOW_ALL < (eSapMacAddrACL) set_value) ||
406 		    (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL) set_value)) {
407 			hdd_err("Invalid ACL Mode value: %d", set_value);
408 			ret = -EINVAL;
409 		} else {
410 			wlansap_set_acl_mode(
411 				WLAN_HDD_GET_SAP_CTX_PTR(link_info),
412 				set_value);
413 		}
414 		break;
415 
416 	case QCSAP_PARAM_SET_CHANNEL_CHANGE:
417 		if ((QDF_SAP_MODE == adapter->device_mode) ||
418 		   (QDF_P2P_GO_MODE == adapter->device_mode)) {
419 			wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc,
420 						    link_info->vdev_id,
421 						    CSA_REASON_USER_INITIATED);
422 			hdd_debug("SET Channel Change to new channel= %d",
423 			       set_value);
424 			if (set_value <= wlan_reg_max_5ghz_ch_num())
425 				set_value = wlan_reg_legacy_chan_to_freq(
426 								hdd_ctx->pdev,
427 								set_value);
428 
429 			ret = hdd_softap_set_channel_change(dev, set_value,
430 							    CH_WIDTH_MAX,
431 							    false);
432 		} else {
433 			hdd_err("Channel Change Failed, Device in test mode");
434 			ret = -EINVAL;
435 		}
436 		break;
437 
438 	case QCSAP_PARAM_CONC_SYSTEM_PREF:
439 		hdd_debug("New preference: %d", set_value);
440 		ucfg_policy_mgr_set_sys_pref(hdd_ctx->psoc, set_value);
441 		break;
442 
443 	case QCSAP_PARAM_MAX_ASSOC:
444 		if (set_value < cfg_min(CFG_ASSOC_STA_LIMIT)) {
445 			hdd_err("Invalid setMaxAssoc value %d",
446 			       set_value);
447 			ret = -EINVAL;
448 		} else {
449 			if (set_value > cfg_max(CFG_ASSOC_STA_LIMIT)) {
450 				hdd_warn("setMaxAssoc %d > max allowed %d.",
451 					 set_value,
452 					 cfg_max(CFG_ASSOC_STA_LIMIT));
453 				hdd_warn("Setting it to max allowed and continuing");
454 				set_value = cfg_max(CFG_ASSOC_STA_LIMIT);
455 			}
456 			if (ucfg_mlme_set_assoc_sta_limit(hdd_ctx->psoc,
457 							  set_value) !=
458 			    QDF_STATUS_SUCCESS) {
459 				hdd_err("CFG_ASSOC_STA_LIMIT failed");
460 				ret = -EIO;
461 			}
462 
463 		}
464 		break;
465 
466 	case QCSAP_PARAM_HIDE_SSID:
467 	{
468 		QDF_STATUS status;
469 
470 		/*
471 		 * Reject hidden ssid param update  if reassoc in progress on
472 		 * any adapter. sme_is_any_session_in_middle_of_roaming is for
473 		 * LFR2 and hdd_is_roaming_in_progress is for LFR3
474 		 */
475 		if (hdd_is_roaming_in_progress(hdd_ctx) ||
476 		    sme_is_any_session_in_middle_of_roaming(mac_handle)) {
477 			hdd_info("Reassociation in progress");
478 			return -EINVAL;
479 		}
480 
481 		/*
482 		 * Disable Roaming on all adapters before start of
483 		 * start of Hidden ssid connection
484 		 */
485 		wlan_hdd_set_roaming_state(link_info, RSO_START_BSS, false);
486 
487 		status = sme_update_session_param(mac_handle,
488 				link_info->vdev_id,
489 				SIR_PARAM_SSID_HIDDEN, set_value);
490 		if (QDF_STATUS_SUCCESS != status) {
491 			hdd_err("QCSAP_PARAM_HIDE_SSID failed");
492 			wlan_hdd_set_roaming_state(link_info, RSO_START_BSS,
493 						   true);
494 			return -EIO;
495 		}
496 		break;
497 	}
498 	case QCSAP_PARAM_SET_MC_RATE:
499 	{
500 		tSirRateUpdateInd rate_update = {0};
501 
502 		hdd_debug("MC Target rate %d", set_value);
503 		qdf_copy_macaddr(&rate_update.bssid,
504 				 &adapter->mac_addr);
505 		status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
506 		if (!QDF_IS_STATUS_SUCCESS(status)) {
507 			hdd_err("unable to get vht_enable2x2");
508 			ret = -1;
509 		}
510 		rate_update.nss = (bval == 0) ? 0 : 1;
511 
512 		rate_update.dev_mode = adapter->device_mode;
513 		rate_update.mcastDataRate24GHz = set_value;
514 		rate_update.mcastDataRate24GHzTxFlag = 1;
515 		rate_update.mcastDataRate5GHz = set_value;
516 		rate_update.bcastDataRate = -1;
517 		status = sme_send_rate_update_ind(mac_handle, &rate_update);
518 		if (QDF_STATUS_SUCCESS != status) {
519 			hdd_err("SET_MC_RATE failed");
520 			ret = -1;
521 		}
522 		break;
523 	}
524 
525 	case QCSAP_PARAM_SET_TXRX_FW_STATS:
526 	{
527 		hdd_debug("QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value);
528 		ret = wma_cli_set_command(link_info->vdev_id,
529 					  WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
530 					  set_value, VDEV_CMD);
531 		break;
532 	}
533 
534 	/* Firmware debug log */
535 	case QCSAP_DBGLOG_LOG_LEVEL:
536 	{
537 		hdd_debug("QCSAP_DBGLOG_LOG_LEVEL val %d", set_value);
538 		ret = wma_cli_set_command(link_info->vdev_id,
539 					  WMI_DBGLOG_LOG_LEVEL,
540 					  set_value, DBG_CMD);
541 		break;
542 	}
543 
544 	case QCSAP_DBGLOG_VAP_ENABLE:
545 	{
546 		hdd_debug("QCSAP_DBGLOG_VAP_ENABLE val %d", set_value);
547 		ret = wma_cli_set_command(link_info->vdev_id,
548 					  WMI_DBGLOG_VAP_ENABLE,
549 					  set_value, DBG_CMD);
550 		break;
551 	}
552 
553 	case QCSAP_DBGLOG_VAP_DISABLE:
554 	{
555 		hdd_debug("QCSAP_DBGLOG_VAP_DISABLE val %d", set_value);
556 		ret = wma_cli_set_command(link_info->vdev_id,
557 					  WMI_DBGLOG_VAP_DISABLE,
558 					  set_value, DBG_CMD);
559 		break;
560 	}
561 
562 	case QCSAP_DBGLOG_MODULE_ENABLE:
563 	{
564 		hdd_debug("QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value);
565 		ret = wma_cli_set_command(link_info->vdev_id,
566 					  WMI_DBGLOG_MODULE_ENABLE,
567 					  set_value, DBG_CMD);
568 		break;
569 	}
570 
571 	case QCSAP_DBGLOG_MODULE_DISABLE:
572 	{
573 		hdd_debug("QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value);
574 		ret = wma_cli_set_command(link_info->vdev_id,
575 					  WMI_DBGLOG_MODULE_DISABLE,
576 					  set_value, DBG_CMD);
577 		break;
578 	}
579 
580 	case QCSAP_DBGLOG_MOD_LOG_LEVEL:
581 	{
582 		hdd_debug("QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value);
583 		ret = wma_cli_set_command(link_info->vdev_id,
584 					  WMI_DBGLOG_MOD_LOG_LEVEL,
585 					  set_value, DBG_CMD);
586 		break;
587 	}
588 
589 	case QCSAP_DBGLOG_TYPE:
590 	{
591 		hdd_debug("QCSAP_DBGLOG_TYPE val %d", set_value);
592 		ret = wma_cli_set_command(link_info->vdev_id,
593 					  WMI_DBGLOG_TYPE,
594 					  set_value, DBG_CMD);
595 		break;
596 	}
597 	case QCSAP_DBGLOG_REPORT_ENABLE:
598 	{
599 		hdd_debug("QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value);
600 		ret = wma_cli_set_command(link_info->vdev_id,
601 					  WMI_DBGLOG_REPORT_ENABLE,
602 					  set_value, DBG_CMD);
603 		break;
604 	}
605 	case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY:
606 	{
607 		wlan_hdd_set_mcc_latency(adapter, set_value);
608 		break;
609 	}
610 
611 	case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA:
612 	{
613 		hdd_debug("iwpriv cmd to set MCC quota value %dms",
614 		       set_value);
615 		ret = wlan_hdd_go_set_mcc_p2p_quota(adapter,
616 						    set_value);
617 		break;
618 	}
619 
620 	case QCASAP_TXRX_FWSTATS_RESET:
621 	{
622 		hdd_debug("WE_TXRX_FWSTATS_RESET val %d", set_value);
623 		ret = wma_cli_set_command(link_info->vdev_id,
624 					  WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
625 					  set_value, VDEV_CMD);
626 		break;
627 	}
628 
629 	case QCSAP_PARAM_RTSCTS:
630 	{
631 		ret = wma_cli_set_command(link_info->vdev_id,
632 					  wmi_vdev_param_enable_rtscts,
633 					  set_value, VDEV_CMD);
634 		if (ret) {
635 			hdd_err("FAILED TO SET RTSCTS at SAP");
636 			ret = -EIO;
637 		}
638 		break;
639 	}
640 	case QCASAP_SET_11N_RATE:
641 	{
642 		uint8_t preamble = 0, nss = 0, rix = 0;
643 		struct sap_config *config =
644 			&link_info->session.ap.sap_config;
645 
646 		hdd_debug("SET_HT_RATE val %d", set_value);
647 
648 		if (set_value != 0xff) {
649 			rix = RC_2_RATE_IDX(set_value);
650 			if (set_value & 0x80) {
651 				if (config->SapHw_mode ==
652 				    eCSR_DOT11_MODE_11b
653 				    || config->SapHw_mode ==
654 				    eCSR_DOT11_MODE_11b_ONLY
655 				    || config->SapHw_mode ==
656 				    eCSR_DOT11_MODE_11g
657 				    || config->SapHw_mode ==
658 				    eCSR_DOT11_MODE_11g_ONLY
659 				    || config->SapHw_mode ==
660 				    eCSR_DOT11_MODE_abg
661 				    || config->SapHw_mode ==
662 				    eCSR_DOT11_MODE_11a) {
663 					hdd_err("Not valid mode for HT");
664 					ret = -EIO;
665 					break;
666 				}
667 				preamble = WMI_RATE_PREAMBLE_HT;
668 				nss = HT_RC_2_STREAMS(set_value) - 1;
669 			} else if (set_value & 0x10) {
670 				if (config->SapHw_mode ==
671 				    eCSR_DOT11_MODE_11a) {
672 					hdd_err("Not valid for cck");
673 					ret = -EIO;
674 					break;
675 				}
676 				preamble = WMI_RATE_PREAMBLE_CCK;
677 				/* Enable Short preamble always
678 				 * for CCK except 1mbps
679 				 */
680 				if (rix != 0x3)
681 					rix |= 0x4;
682 			} else {
683 				if (config->SapHw_mode ==
684 				    eCSR_DOT11_MODE_11b
685 				    || config->SapHw_mode ==
686 				    eCSR_DOT11_MODE_11b_ONLY) {
687 					hdd_err("Not valid for OFDM");
688 					ret = -EIO;
689 					break;
690 				}
691 				preamble = WMI_RATE_PREAMBLE_OFDM;
692 			}
693 			set_value = hdd_assemble_rate_code(preamble, nss, rix);
694 		}
695 		hdd_debug("SET_HT_RATE val %d rix %d preamble %x nss %d",
696 		       set_value, rix, preamble, nss);
697 		ret = wma_cli_set_command(link_info->vdev_id,
698 					  wmi_vdev_param_fixed_rate,
699 					  set_value, VDEV_CMD);
700 		break;
701 	}
702 
703 	case QCASAP_SET_VHT_RATE:
704 	{
705 		uint8_t preamble = 0, nss = 0, rix = 0;
706 		struct sap_config *config =
707 			&link_info->session.ap.sap_config;
708 
709 		if (config->SapHw_mode < eCSR_DOT11_MODE_11ac ||
710 		    config->SapHw_mode == eCSR_DOT11_MODE_11ax_ONLY ||
711 		    config->SapHw_mode == eCSR_DOT11_MODE_11be_ONLY) {
712 			hdd_err("SET_VHT_RATE: SapHw_mode= 0x%x, ch_freq: %d",
713 			       config->SapHw_mode, config->chan_freq);
714 			ret = -EIO;
715 			break;
716 		}
717 
718 		if (set_value != 0xff) {
719 			rix = RC_2_RATE_IDX_11AC(set_value);
720 			preamble = WMI_RATE_PREAMBLE_VHT;
721 			nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
722 
723 			set_value = hdd_assemble_rate_code(preamble, nss, rix);
724 		}
725 		hdd_debug("SET_VHT_RATE val %d rix %d preamble %x nss %d",
726 		       set_value, rix, preamble, nss);
727 
728 		ret = wma_cli_set_command(link_info->vdev_id,
729 					  wmi_vdev_param_fixed_rate,
730 					  set_value, VDEV_CMD);
731 		break;
732 	}
733 
734 	case QCASAP_SHORT_GI:
735 	{
736 		hdd_debug("QCASAP_SET_SHORT_GI val %d", set_value);
737 		ret = hdd_we_set_short_gi(link_info, set_value);
738 		if (ret)
739 			hdd_err("Failed to set ShortGI value ret: %d", ret);
740 		break;
741 	}
742 
743 	case QCSAP_SET_AMPDU:
744 	{
745 		hdd_debug("QCSAP_SET_AMPDU %d", set_value);
746 		ret = wma_cli_set_command(link_info->vdev_id,
747 					  GEN_VDEV_PARAM_AMPDU,
748 					  set_value, GEN_CMD);
749 		break;
750 	}
751 
752 	case QCSAP_SET_AMSDU:
753 	{
754 		hdd_debug("QCSAP_SET_AMSDU %d", set_value);
755 		ret = wma_cli_set_command(link_info->vdev_id,
756 					  GEN_VDEV_PARAM_AMSDU,
757 					  set_value, GEN_CMD);
758 		break;
759 	}
760 	case QCSAP_GTX_HT_MCS:
761 	{
762 		hdd_debug("wmi_vdev_param_gtx_ht_mcs %d", set_value);
763 		ret = wma_cli_set_command(link_info->vdev_id,
764 					  wmi_vdev_param_gtx_ht_mcs,
765 					  set_value, GTX_CMD);
766 		break;
767 	}
768 
769 	case QCSAP_GTX_VHT_MCS:
770 	{
771 		hdd_debug("wmi_vdev_param_gtx_vht_mcs %d", set_value);
772 		ret = wma_cli_set_command(link_info->vdev_id,
773 					  wmi_vdev_param_gtx_vht_mcs,
774 						set_value, GTX_CMD);
775 		break;
776 	}
777 
778 	case QCSAP_GTX_USRCFG:
779 	{
780 		hdd_debug("wmi_vdev_param_gtx_usr_cfg %d", set_value);
781 		ret = wma_cli_set_command(link_info->vdev_id,
782 					  wmi_vdev_param_gtx_usr_cfg,
783 					  set_value, GTX_CMD);
784 		break;
785 	}
786 
787 	case QCSAP_GTX_THRE:
788 	{
789 		hdd_debug("wmi_vdev_param_gtx_thre %d", set_value);
790 		ret = wma_cli_set_command(link_info->vdev_id,
791 					  wmi_vdev_param_gtx_thre,
792 					  set_value, GTX_CMD);
793 		break;
794 	}
795 
796 	case QCSAP_GTX_MARGIN:
797 	{
798 		hdd_debug("wmi_vdev_param_gtx_margin %d", set_value);
799 		ret = wma_cli_set_command(link_info->vdev_id,
800 					  wmi_vdev_param_gtx_margin,
801 					  set_value, GTX_CMD);
802 		break;
803 	}
804 
805 	case QCSAP_GTX_STEP:
806 	{
807 		hdd_debug("wmi_vdev_param_gtx_step %d", set_value);
808 		ret = wma_cli_set_command(link_info->vdev_id,
809 					  wmi_vdev_param_gtx_step,
810 					  set_value, GTX_CMD);
811 		break;
812 	}
813 
814 	case QCSAP_GTX_MINTPC:
815 	{
816 		hdd_debug("wmi_vdev_param_gtx_mintpc %d", set_value);
817 		ret = wma_cli_set_command(link_info->vdev_id,
818 					  wmi_vdev_param_gtx_mintpc,
819 					  set_value, GTX_CMD);
820 		break;
821 	}
822 
823 	case QCSAP_GTX_BWMASK:
824 	{
825 		hdd_debug("wmi_vdev_param_gtx_bw_mask%d", set_value);
826 		ret = wma_cli_set_command(link_info->vdev_id,
827 					  wmi_vdev_param_gtx_bw_mask,
828 					  set_value, GTX_CMD);
829 		break;
830 	}
831 
832 	case QCASAP_SET_TM_LEVEL:
833 	{
834 		hdd_debug("Set Thermal Mitigation Level %d", set_value);
835 		(void)sme_set_thermal_level(mac_handle, set_value);
836 		break;
837 	}
838 
839 	case QCASAP_SET_DFS_IGNORE_CAC:
840 	{
841 		hdd_debug("Set Dfs ignore CAC  %d", set_value);
842 
843 		if (adapter->device_mode != QDF_SAP_MODE)
844 			return -EINVAL;
845 
846 		ret = wlansap_set_dfs_ignore_cac(mac_handle, set_value);
847 		break;
848 	}
849 
850 	case QCASAP_SET_DFS_TARGET_CHNL:
851 	{
852 		hdd_debug("Set Dfs target channel  %d", set_value);
853 
854 		if (adapter->device_mode != QDF_SAP_MODE)
855 			return -EINVAL;
856 
857 		ret = wlansap_set_dfs_target_chnl(mac_handle,
858 						  wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev,
859 									       set_value));
860 		break;
861 	}
862 
863 	case QCASAP_SET_HE_BSS_COLOR:
864 		if (adapter->device_mode != QDF_SAP_MODE)
865 			return -EINVAL;
866 
867 		status = sme_set_he_bss_color(mac_handle,
868 					      link_info->vdev_id,
869 					      set_value);
870 		if (QDF_STATUS_SUCCESS != status) {
871 			hdd_err("SET_HE_BSS_COLOR failed");
872 			return -EIO;
873 		}
874 		break;
875 	case QCASAP_SET_DFS_NOL:
876 		wlansap_set_dfs_nol(
877 			WLAN_HDD_GET_SAP_CTX_PTR(link_info),
878 			(eSapDfsNolType) set_value);
879 		break;
880 
881 	case QCASAP_SET_RADAR_CMD:
882 	{
883 		struct hdd_ap_ctx *ap_ctx;
884 		struct wlan_objmgr_pdev *pdev;
885 		struct radar_found_info radar;
886 
887 		hdd_debug("Set QCASAP_SET_RADAR_CMD val %d", set_value);
888 
889 		pdev = hdd_ctx->pdev;
890 		if (!pdev) {
891 			hdd_err("null pdev");
892 			return -EINVAL;
893 		}
894 
895 		ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
896 		qdf_mem_zero(&radar, sizeof(radar));
897 		if (wlansap_is_channel_in_nol_list(ap_ctx->sap_context,
898 						   ap_ctx->operating_chan_freq,
899 						   PHY_SINGLE_CHANNEL_CENTERED))
900 			hdd_debug("Ignore set radar, op ch_freq(%d) is in nol",
901 				  ap_ctx->operating_chan_freq);
902 		else if (WLAN_UMAC_VDEV_ID_MAX !=
903 			 policy_mgr_get_dfs_beaconing_session_id(hdd_ctx->psoc))
904 			tgt_dfs_process_radar_ind(pdev, &radar);
905 		else
906 			hdd_debug("Ignore set radar, op ch_freq(%d) is not dfs",
907 				  ap_ctx->operating_chan_freq);
908 
909 		break;
910 	}
911 	case QCASAP_TX_CHAINMASK_CMD:
912 	{
913 		hdd_debug("QCASAP_TX_CHAINMASK_CMD val %d", set_value);
914 		ret = wma_cli_set_command(link_info->vdev_id,
915 					  wmi_pdev_param_tx_chain_mask,
916 					  set_value, PDEV_CMD);
917 		ret = hdd_set_antenna_mode(link_info, set_value);
918 		break;
919 	}
920 
921 	case QCASAP_RX_CHAINMASK_CMD:
922 	{
923 		hdd_debug("QCASAP_RX_CHAINMASK_CMD val %d", set_value);
924 		ret = wma_cli_set_command(link_info->vdev_id,
925 					  wmi_pdev_param_rx_chain_mask,
926 					  set_value, PDEV_CMD);
927 		ret = hdd_set_antenna_mode(link_info, set_value);
928 		break;
929 	}
930 
931 	case QCASAP_NSS_CMD:
932 	{
933 		hdd_debug("QCASAP_NSS_CMD val %d", set_value);
934 		hdd_update_nss(link_info, set_value, set_value);
935 		ret = wma_cli_set_command(link_info->vdev_id,
936 					  wmi_vdev_param_nss,
937 					  set_value, VDEV_CMD);
938 		break;
939 	}
940 
941 	case QCSAP_IPA_UC_STAT:
942 	{
943 		/* If input value is non-zero get stats */
944 		switch (set_value) {
945 		case 1:
946 			ucfg_ipa_uc_stat(hdd_ctx->pdev);
947 			break;
948 		case 2:
949 			ucfg_ipa_uc_info(hdd_ctx->pdev);
950 			break;
951 		case 3:
952 			ucfg_ipa_uc_rt_debug_host_dump(hdd_ctx->pdev);
953 			break;
954 		case 4:
955 			ucfg_ipa_dump_info(hdd_ctx->pdev);
956 			break;
957 		default:
958 			/* place holder for stats clean up
959 			 * Stats clean not implemented yet on FW and IPA
960 			 */
961 			break;
962 		}
963 		return ret;
964 	}
965 
966 	case QCASAP_SET_PHYMODE:
967 		ret = hdd_we_update_phymode(link_info, set_value);
968 		break;
969 
970 	case QCASAP_DUMP_STATS:
971 	{
972 		hdd_debug("QCASAP_DUMP_STATS val %d", set_value);
973 		ret = hdd_wlan_dump_stats(adapter, set_value);
974 		break;
975 	}
976 	case QCASAP_CLEAR_STATS:
977 	{
978 		void *soc = cds_get_context(QDF_MODULE_ID_SOC);
979 
980 		hdd_debug("QCASAP_CLEAR_STATS val %d", set_value);
981 		switch (set_value) {
982 		case CDP_HDD_STATS:
983 			ucfg_dp_clear_net_dev_stats(adapter->dev);
984 			memset(&link_info->hdd_stats, 0,
985 			       sizeof(link_info->hdd_stats));
986 			break;
987 		case CDP_TXRX_HIST_STATS:
988 			ucfg_wlan_dp_clear_tx_rx_histogram(hdd_ctx->psoc);
989 			break;
990 		case CDP_HDD_NETIF_OPER_HISTORY:
991 			wlan_hdd_clear_netif_queue_history(hdd_ctx);
992 			break;
993 		case CDP_HIF_STATS:
994 			hdd_clear_hif_stats();
995 			break;
996 		default:
997 			if (soc)
998 				cdp_clear_stats(soc, OL_TXRX_PDEV_ID,
999 						set_value);
1000 		}
1001 		break;
1002 	}
1003 	case QCSAP_START_FW_PROFILING:
1004 		hdd_debug("QCSAP_START_FW_PROFILING %d", set_value);
1005 		ret = wma_cli_set_command(link_info->vdev_id,
1006 					  WMI_WLAN_PROFILE_TRIGGER_CMDID,
1007 					  set_value, DBG_CMD);
1008 		break;
1009 	case QCASAP_PARAM_LDPC:
1010 		ret = hdd_set_ldpc(link_info, set_value);
1011 		break;
1012 	case QCASAP_PARAM_TX_STBC:
1013 		ret = hdd_set_tx_stbc(link_info, set_value);
1014 		break;
1015 	case QCASAP_PARAM_RX_STBC:
1016 		ret = hdd_set_rx_stbc(link_info, set_value);
1017 		break;
1018 	case QCASAP_SET_11AX_RATE:
1019 		ret = hdd_set_11ax_rate(adapter, set_value,
1020 					&link_info->session.ap.sap_config);
1021 		break;
1022 	case QCASAP_PARAM_DCM:
1023 		hdd_debug("Set wmi_vdev_param_he_dcm_enable: %d", set_value);
1024 		ret = wma_cli_set_command(link_info->vdev_id,
1025 					  wmi_vdev_param_he_dcm_enable,
1026 					  set_value, VDEV_CMD);
1027 		break;
1028 	case QCASAP_PARAM_RANGE_EXT:
1029 		hdd_debug("Set wmi_vdev_param_he_range_ext: %d", set_value);
1030 		ret = wma_cli_set_command(link_info->vdev_id,
1031 					  wmi_vdev_param_he_range_ext,
1032 					  set_value, VDEV_CMD);
1033 		break;
1034 	case QCSAP_SET_DEFAULT_AMPDU:
1035 		hdd_debug("QCSAP_SET_DEFAULT_AMPDU val %d", set_value);
1036 		ret = wma_cli_set_command(
1037 				(int)link_info->vdev_id,
1038 				(int)wmi_pdev_param_max_mpdus_in_ampdu,
1039 				set_value, PDEV_CMD);
1040 		break;
1041 	case QCSAP_ENABLE_RTS_BURSTING:
1042 		hdd_debug("QCSAP_ENABLE_RTS_BURSTING val %d", set_value);
1043 		ret = wma_cli_set_command(
1044 				(int)link_info->vdev_id,
1045 				(int)wmi_pdev_param_enable_rts_sifs_bursting,
1046 				set_value, PDEV_CMD);
1047 		break;
1048 	case QCSAP_SET_BTCOEX_MODE:
1049 		ret =  wlan_hdd_set_btcoex_mode(link_info, set_value);
1050 		break;
1051 	case QCSAP_SET_BTCOEX_LOW_RSSI_THRESHOLD:
1052 		ret =  wlan_hdd_set_btcoex_rssi_threshold(link_info, set_value);
1053 		break;
1054 	default:
1055 		hdd_err("Invalid setparam command %d value %d",
1056 		       sub_cmd, set_value);
1057 		ret = -EINVAL;
1058 		break;
1059 	}
1060 	hdd_exit();
1061 	return ret;
1062 }
1063 
1064 /**
1065  * __iw_softap_get_three() - return three value to upper layer.
1066  * @dev: pointer of net_device of this wireless card
1067  * @info: meta data about Request sent
1068  * @wrqu: include request info
1069  * @extra: buf used for in/out
1070  *
1071  * Return: execute result
1072  */
__iw_softap_get_three(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1073 static int __iw_softap_get_three(struct net_device *dev,
1074 					struct iw_request_info *info,
1075 					union iwreq_data *wrqu, char *extra)
1076 {
1077 	uint32_t *value = (uint32_t *)extra;
1078 	uint32_t sub_cmd = value[0];
1079 	int ret = 0; /* success */
1080 	struct hdd_context *hdd_ctx;
1081 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1082 	struct hdd_tsf_op_response tsf_op_resp;
1083 
1084 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1085 	ret = wlan_hdd_validate_context(hdd_ctx);
1086 	if (ret != 0)
1087 		return ret;
1088 
1089 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1090 	if (0 != ret)
1091 		return ret;
1092 
1093 	switch (sub_cmd) {
1094 	case QCSAP_GET_TSF:
1095 		ret = hdd_indicate_tsf(adapter, &tsf_op_resp);
1096 		if (!ret) {
1097 			value[0] = tsf_op_resp.status;
1098 			value[1] = tsf_op_resp.time & 0xffffffff;
1099 			value[2] = (tsf_op_resp.time >> 32) & 0xffffffff;
1100 		}
1101 		break;
1102 	default:
1103 		hdd_err("Invalid getparam command: %d", sub_cmd);
1104 		ret = -EINVAL;
1105 		break;
1106 	}
1107 	return ret;
1108 }
1109 
1110 
1111 /**
1112  * iw_softap_get_three() - return three value to upper layer.
1113  *
1114  * @dev: pointer of net_device of this wireless card
1115  * @info: meta data about Request sent
1116  * @wrqu: include request info
1117  * @extra: buf used for in/Output
1118  *
1119  * Return: execute result
1120  */
iw_softap_get_three(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1121 static int iw_softap_get_three(struct net_device *dev,
1122 					struct iw_request_info *info,
1123 					union iwreq_data *wrqu, char *extra)
1124 {
1125 	int errno;
1126 	struct osif_vdev_sync *vdev_sync;
1127 
1128 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1129 	if (errno)
1130 		return errno;
1131 
1132 	errno = __iw_softap_get_three(dev, info, wrqu, extra);
1133 
1134 	osif_vdev_sync_op_stop(vdev_sync);
1135 
1136 	return errno;
1137 }
1138 
1139 int
iw_softap_setparam(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1140 static iw_softap_setparam(struct net_device *dev,
1141 			  struct iw_request_info *info,
1142 			  union iwreq_data *wrqu, char *extra)
1143 {
1144 	int errno;
1145 	struct osif_vdev_sync *vdev_sync;
1146 
1147 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1148 	if (errno)
1149 		return errno;
1150 
1151 	errno = __iw_softap_setparam(dev, info, wrqu, extra);
1152 
1153 	osif_vdev_sync_op_stop(vdev_sync);
1154 
1155 	return errno;
1156 }
1157 
1158 int
__iw_softap_getparam(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1159 static __iw_softap_getparam(struct net_device *dev,
1160 			    struct iw_request_info *info,
1161 			    union iwreq_data *wrqu, char *extra)
1162 {
1163 	struct hdd_adapter *adapter = (netdev_priv(dev));
1164 	int *value = (int *)extra;
1165 	int sub_cmd = value[0];
1166 	int ret;
1167 	struct hdd_context *hdd_ctx;
1168 
1169 	hdd_enter_dev(dev);
1170 
1171 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1172 	ret = wlan_hdd_validate_context(hdd_ctx);
1173 	if (0 != ret)
1174 		return ret;
1175 
1176 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1177 	if (0 != ret)
1178 		return ret;
1179 
1180 	switch (sub_cmd) {
1181 	case QCSAP_PARAM_MAX_ASSOC:
1182 		if (ucfg_mlme_get_assoc_sta_limit(hdd_ctx->psoc, value) !=
1183 		    QDF_STATUS_SUCCESS) {
1184 			hdd_err("CFG_ASSOC_STA_LIMIT failed");
1185 			ret = -EIO;
1186 		}
1187 
1188 		break;
1189 
1190 	case QCSAP_PARAM_GET_WLAN_DBG:
1191 	{
1192 		qdf_trace_display();
1193 		*value = 0;
1194 		break;
1195 	}
1196 
1197 	case QCSAP_PARAM_RTSCTS:
1198 	{
1199 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1200 					     wmi_vdev_param_enable_rtscts,
1201 					     VDEV_CMD);
1202 		break;
1203 	}
1204 
1205 	case QCASAP_SHORT_GI:
1206 	{
1207 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1208 					     wmi_vdev_param_sgi,
1209 					     VDEV_CMD);
1210 		break;
1211 	}
1212 
1213 	case QCSAP_GTX_HT_MCS:
1214 	{
1215 		hdd_debug("GET wmi_vdev_param_gtx_ht_mcs");
1216 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1217 					     wmi_vdev_param_gtx_ht_mcs,
1218 					     GTX_CMD);
1219 		break;
1220 	}
1221 
1222 	case QCSAP_GTX_VHT_MCS:
1223 	{
1224 		hdd_debug("GET wmi_vdev_param_gtx_vht_mcs");
1225 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1226 					     wmi_vdev_param_gtx_vht_mcs,
1227 					     GTX_CMD);
1228 		break;
1229 	}
1230 
1231 	case QCSAP_GTX_USRCFG:
1232 	{
1233 		hdd_debug("GET wmi_vdev_param_gtx_usr_cfg");
1234 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1235 					     wmi_vdev_param_gtx_usr_cfg,
1236 					     GTX_CMD);
1237 		break;
1238 	}
1239 
1240 	case QCSAP_GTX_THRE:
1241 	{
1242 		hdd_debug("GET wmi_vdev_param_gtx_thre");
1243 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1244 					     wmi_vdev_param_gtx_thre,
1245 					     GTX_CMD);
1246 		break;
1247 	}
1248 
1249 	case QCSAP_GTX_MARGIN:
1250 	{
1251 		hdd_debug("GET wmi_vdev_param_gtx_margin");
1252 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1253 					     wmi_vdev_param_gtx_margin,
1254 					     GTX_CMD);
1255 		break;
1256 	}
1257 
1258 	case QCSAP_GTX_STEP:
1259 	{
1260 		hdd_debug("GET wmi_vdev_param_gtx_step");
1261 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1262 					     wmi_vdev_param_gtx_step,
1263 					     GTX_CMD);
1264 		break;
1265 	}
1266 
1267 	case QCSAP_GTX_MINTPC:
1268 	{
1269 		hdd_debug("GET wmi_vdev_param_gtx_mintpc");
1270 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1271 					     wmi_vdev_param_gtx_mintpc,
1272 					     GTX_CMD);
1273 		break;
1274 	}
1275 
1276 	case QCSAP_GTX_BWMASK:
1277 	{
1278 		hdd_debug("GET wmi_vdev_param_gtx_bw_mask");
1279 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1280 					     wmi_vdev_param_gtx_bw_mask,
1281 					     GTX_CMD);
1282 		break;
1283 	}
1284 
1285 	case QCASAP_GET_DFS_NOL:
1286 	{
1287 		struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1288 		struct wlan_objmgr_pdev *pdev;
1289 
1290 		pdev = hdd_ctx->pdev;
1291 		if (!pdev) {
1292 			hdd_err("null pdev");
1293 			return -EINVAL;
1294 		}
1295 
1296 		utils_dfs_print_nol_channels(pdev);
1297 	}
1298 	break;
1299 
1300 	case QCSAP_GET_ACL:
1301 	{
1302 		hdd_debug("QCSAP_GET_ACL");
1303 		if (hdd_print_acl(adapter) !=
1304 		    QDF_STATUS_SUCCESS) {
1305 			hdd_err("QCSAP_GET_ACL returned Error: not completed");
1306 		}
1307 		*value = 0;
1308 		break;
1309 	}
1310 
1311 	case QCASAP_TX_CHAINMASK_CMD:
1312 	{
1313 		hdd_debug("QCASAP_TX_CHAINMASK_CMD");
1314 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1315 					     wmi_pdev_param_tx_chain_mask,
1316 					     PDEV_CMD);
1317 		break;
1318 	}
1319 
1320 	case QCASAP_RX_CHAINMASK_CMD:
1321 	{
1322 		hdd_debug("QCASAP_RX_CHAINMASK_CMD");
1323 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1324 					     wmi_pdev_param_rx_chain_mask,
1325 					     PDEV_CMD);
1326 		break;
1327 	}
1328 
1329 	case QCASAP_NSS_CMD:
1330 	{
1331 		hdd_debug("QCASAP_NSS_CMD");
1332 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1333 					     wmi_vdev_param_nss,
1334 					     VDEV_CMD);
1335 		break;
1336 	}
1337 	case QCSAP_CAP_TSF:
1338 		ret = hdd_capture_tsf(adapter, (uint32_t *)value, 1);
1339 		break;
1340 	case QCASAP_GET_TEMP_CMD:
1341 	{
1342 		hdd_debug("QCASAP_GET_TEMP_CMD");
1343 		ret = wlan_hdd_get_temperature(adapter, value);
1344 		break;
1345 	}
1346 	case QCSAP_GET_FW_PROFILE_DATA:
1347 		hdd_debug("QCSAP_GET_FW_PROFILE_DATA");
1348 		ret = wma_cli_set_command(
1349 				adapter->deflink->vdev_id,
1350 				WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
1351 				0, DBG_CMD);
1352 		break;
1353 	case QCASAP_PARAM_LDPC:
1354 	{
1355 		ret = hdd_get_ldpc(adapter, value);
1356 		break;
1357 	}
1358 	case QCASAP_PARAM_TX_STBC:
1359 	{
1360 		ret = hdd_get_tx_stbc(adapter, value);
1361 		break;
1362 	}
1363 	case QCASAP_PARAM_RX_STBC:
1364 	{
1365 		ret = hdd_get_rx_stbc(adapter, value);
1366 		break;
1367 	}
1368 	case QCSAP_PARAM_CHAN_WIDTH:
1369 	{
1370 		ret = hdd_sap_get_chan_width(adapter, value);
1371 		break;
1372 	}
1373 	case QCASAP_PARAM_DCM:
1374 	{
1375 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1376 					     wmi_vdev_param_he_dcm_enable,
1377 					     VDEV_CMD);
1378 		break;
1379 	}
1380 	case QCASAP_PARAM_RANGE_EXT:
1381 	{
1382 		*value = wma_cli_get_command(adapter->deflink->vdev_id,
1383 					     wmi_vdev_param_he_range_ext,
1384 					     VDEV_CMD);
1385 		break;
1386 	}
1387 	default:
1388 		hdd_err("Invalid getparam command: %d", sub_cmd);
1389 		ret = -EINVAL;
1390 		break;
1391 
1392 	}
1393 	hdd_exit();
1394 	return ret;
1395 }
1396 
1397 int
iw_softap_getparam(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1398 static iw_softap_getparam(struct net_device *dev,
1399 			  struct iw_request_info *info,
1400 			  union iwreq_data *wrqu, char *extra)
1401 {
1402 	int errno;
1403 	struct osif_vdev_sync *vdev_sync;
1404 
1405 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1406 	if (errno)
1407 		return errno;
1408 
1409 	errno = __iw_softap_getparam(dev, info, wrqu, extra);
1410 
1411 	osif_vdev_sync_op_stop(vdev_sync);
1412 
1413 	return errno;
1414 }
1415 
1416 /* Usage:
1417  *  DENY_LIST  = 0
1418  *  ALLOW_LIST  = 1
1419  *  ADD MAC = 0
1420  *  REMOVE MAC  = 1
1421  *
1422  *  mac addr will be accepted as a 6 octet mac address with each octet
1423  *  inputted in hex for e.g. 00:0a:f5:11:22:33 will be represented as
1424  *  0x00 0x0a 0xf5 0x11 0x22 0x33 while using this ioctl
1425  *
1426  *  Syntax:
1427  *  iwpriv softap.0 modify_acl
1428  *  <6 octet mac addr> <list type> <cmd type>
1429  *
1430  *  Examples:
1431  *  eg 1. to add a mac addr 00:0a:f5:89:89:90 to the deny list
1432  *  iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
1433  *  eg 2. to delete a mac addr 00:0a:f5:89:89:90 from allow list
1434  *  iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
1435  */
1436 static
__iw_softap_modify_acl(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1437 int __iw_softap_modify_acl(struct net_device *dev,
1438 			   struct iw_request_info *info,
1439 			   union iwreq_data *wrqu, char *extra)
1440 {
1441 	struct hdd_adapter *adapter = (netdev_priv(dev));
1442 	uint8_t *value = (uint8_t *) extra;
1443 	uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
1444 	int list_type, cmd, i;
1445 	int ret;
1446 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1447 	struct hdd_context *hdd_ctx;
1448 
1449 	hdd_enter_dev(dev);
1450 
1451 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1452 	ret = wlan_hdd_validate_context(hdd_ctx);
1453 	if (0 != ret)
1454 		return ret;
1455 
1456 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1457 	if (0 != ret)
1458 		return ret;
1459 
1460 	for (i = 0; i < QDF_MAC_ADDR_SIZE; i++)
1461 		peer_mac[i] = *(value + i);
1462 
1463 	list_type = (int)(*(value + i));
1464 	i++;
1465 	cmd = (int)(*(value + i));
1466 
1467 	hdd_debug("Modify ACL mac:" QDF_MAC_ADDR_FMT " type: %d cmd: %d",
1468 	       QDF_MAC_ADDR_REF(peer_mac), list_type, cmd);
1469 
1470 	qdf_status = wlansap_modify_acl(
1471 		WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
1472 		peer_mac, (eSapACLType) list_type, (eSapACLCmdType) cmd);
1473 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
1474 		hdd_err("Modify ACL failed");
1475 		ret = -EIO;
1476 	}
1477 	hdd_exit();
1478 	return ret;
1479 }
1480 
1481 static
iw_softap_modify_acl(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1482 int iw_softap_modify_acl(struct net_device *dev,
1483 			 struct iw_request_info *info,
1484 			 union iwreq_data *wrqu, char *extra)
1485 {
1486 	int errno;
1487 	struct osif_vdev_sync *vdev_sync;
1488 
1489 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1490 	if (errno)
1491 		return errno;
1492 
1493 	errno = __iw_softap_modify_acl(dev, info, wrqu, extra);
1494 
1495 	osif_vdev_sync_op_stop(vdev_sync);
1496 
1497 	return errno;
1498 }
1499 
1500 int
__iw_softap_getchannel(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1501 static __iw_softap_getchannel(struct net_device *dev,
1502 			      struct iw_request_info *info,
1503 			      union iwreq_data *wrqu, char *extra)
1504 {
1505 	struct hdd_adapter *adapter = (netdev_priv(dev));
1506 	struct hdd_context *hdd_ctx;
1507 	struct hdd_ap_ctx *ap_ctx;
1508 	int *value = (int *)extra;
1509 	int ret;
1510 
1511 	hdd_enter_dev(dev);
1512 
1513 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1514 	ret = wlan_hdd_validate_context(hdd_ctx);
1515 	if (0 != ret)
1516 		return ret;
1517 
1518 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1519 	if (0 != ret)
1520 		return ret;
1521 
1522 	*value = 0;
1523 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
1524 	if (test_bit(SOFTAP_BSS_STARTED, &adapter->deflink->link_flags))
1525 		*value = wlan_reg_freq_to_chan(
1526 				hdd_ctx->pdev,
1527 				ap_ctx->operating_chan_freq);
1528 	hdd_exit();
1529 	return 0;
1530 }
1531 
1532 int
iw_softap_getchannel(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1533 static iw_softap_getchannel(struct net_device *dev,
1534 			    struct iw_request_info *info,
1535 			    union iwreq_data *wrqu, char *extra)
1536 {
1537 	int errno;
1538 	struct osif_vdev_sync *vdev_sync;
1539 
1540 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1541 	if (errno)
1542 		return errno;
1543 
1544 	errno = __iw_softap_getchannel(dev, info, wrqu, extra);
1545 
1546 	osif_vdev_sync_op_stop(vdev_sync);
1547 
1548 	return errno;
1549 }
1550 
1551 int
__iw_softap_set_max_tx_power(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1552 static __iw_softap_set_max_tx_power(struct net_device *dev,
1553 				    struct iw_request_info *info,
1554 				    union iwreq_data *wrqu, char *extra)
1555 {
1556 	struct hdd_adapter *adapter = (netdev_priv(dev));
1557 	struct hdd_context *hdd_ctx;
1558 	int *value = (int *)extra;
1559 	int set_value;
1560 	int ret;
1561 	struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT;
1562 	struct qdf_mac_addr selfMac = QDF_MAC_ADDR_BCAST_INIT;
1563 
1564 	hdd_enter_dev(dev);
1565 
1566 	if (!value)
1567 		return -ENOMEM;
1568 
1569 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1570 	ret = wlan_hdd_validate_context(hdd_ctx);
1571 	if (0 != ret)
1572 		return ret;
1573 
1574 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1575 	if (0 != ret)
1576 		return ret;
1577 
1578 	/* Assign correct self MAC address */
1579 	qdf_copy_macaddr(&bssid, &adapter->mac_addr);
1580 	qdf_copy_macaddr(&selfMac, &adapter->mac_addr);
1581 
1582 	set_value = value[0];
1583 	if (QDF_STATUS_SUCCESS !=
1584 	    sme_set_max_tx_power(hdd_ctx->mac_handle, bssid,
1585 				 selfMac, set_value)) {
1586 		hdd_err("Setting maximum tx power failed");
1587 		return -EIO;
1588 	}
1589 	hdd_exit();
1590 	return 0;
1591 }
1592 
1593 int
iw_softap_set_max_tx_power(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1594 static iw_softap_set_max_tx_power(struct net_device *dev,
1595 				  struct iw_request_info *info,
1596 				  union iwreq_data *wrqu, char *extra)
1597 {
1598 	int errno;
1599 	struct osif_vdev_sync *vdev_sync;
1600 
1601 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1602 	if (errno)
1603 		return errno;
1604 
1605 	errno = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
1606 
1607 	osif_vdev_sync_op_stop(vdev_sync);
1608 
1609 	return errno;
1610 }
1611 
1612 #ifndef REMOVE_PKT_LOG
1613 int
__iw_softap_set_pktlog(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1614 static __iw_softap_set_pktlog(struct net_device *dev,
1615 				    struct iw_request_info *info,
1616 				    union iwreq_data *wrqu, char *extra)
1617 {
1618 	struct hdd_adapter *adapter = netdev_priv(dev);
1619 	struct hdd_context *hdd_ctx;
1620 	int *value = (int *)extra;
1621 	int ret;
1622 
1623 	hdd_enter_dev(dev);
1624 
1625 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1626 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1627 	if (0 != ret)
1628 		return ret;
1629 
1630 	if (wrqu->data.length < 1 || wrqu->data.length > 2) {
1631 		hdd_err("pktlog: either 1 or 2 parameters are required");
1632 		return -EINVAL;
1633 	}
1634 
1635 	return hdd_process_pktlog_command(hdd_ctx, value[0], value[1]);
1636 }
1637 
1638 int
iw_softap_set_pktlog(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1639 static iw_softap_set_pktlog(struct net_device *dev,
1640 				  struct iw_request_info *info,
1641 				  union iwreq_data *wrqu, char *extra)
1642 {
1643 	int errno;
1644 	struct osif_vdev_sync *vdev_sync;
1645 
1646 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1647 	if (errno)
1648 		return errno;
1649 
1650 	errno = __iw_softap_set_pktlog(dev, info, wrqu, extra);
1651 
1652 	osif_vdev_sync_op_stop(vdev_sync);
1653 
1654 	return errno;
1655 }
1656 #else
1657 int
iw_softap_set_pktlog(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1658 static iw_softap_set_pktlog(struct net_device *dev,
1659 				  struct iw_request_info *info,
1660 				  union iwreq_data *wrqu, char *extra)
1661 {
1662 	return -EINVAL;
1663 }
1664 #endif
1665 
1666 int
__iw_softap_set_tx_power(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1667 static __iw_softap_set_tx_power(struct net_device *dev,
1668 				struct iw_request_info *info,
1669 				union iwreq_data *wrqu, char *extra)
1670 {
1671 	struct hdd_adapter *adapter = (netdev_priv(dev));
1672 	struct hdd_context *hdd_ctx;
1673 	int *value = (int *)extra;
1674 	int set_value;
1675 	struct qdf_mac_addr bssid;
1676 	int ret;
1677 
1678 	hdd_enter_dev(dev);
1679 
1680 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1681 	ret = wlan_hdd_validate_context(hdd_ctx);
1682 	if (0 != ret)
1683 		return ret;
1684 
1685 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1686 	if (0 != ret)
1687 		return ret;
1688 
1689 	qdf_copy_macaddr(&bssid, &adapter->mac_addr);
1690 
1691 	set_value = value[0];
1692 	if (QDF_STATUS_SUCCESS != sme_set_tx_power(
1693 					hdd_ctx->mac_handle,
1694 					adapter->deflink->vdev_id, bssid,
1695 					adapter->device_mode, set_value)) {
1696 		hdd_err("Setting tx power failed");
1697 		return -EIO;
1698 	}
1699 	hdd_exit();
1700 	return 0;
1701 }
1702 
1703 int
iw_softap_set_tx_power(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1704 static iw_softap_set_tx_power(struct net_device *dev,
1705 			      struct iw_request_info *info,
1706 			      union iwreq_data *wrqu, char *extra)
1707 {
1708 	int errno;
1709 	struct osif_vdev_sync *vdev_sync;
1710 
1711 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1712 	if (errno)
1713 		return errno;
1714 
1715 	errno = __iw_softap_set_tx_power(dev, info, wrqu, extra);
1716 
1717 	osif_vdev_sync_op_stop(vdev_sync);
1718 
1719 	return errno;
1720 }
1721 
1722 int
__iw_softap_getassoc_stamacaddr(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1723 static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
1724 				       struct iw_request_info *info,
1725 				       union iwreq_data *wrqu, char *extra)
1726 {
1727 	struct hdd_adapter *adapter = (netdev_priv(dev));
1728 	struct hdd_station_info *sta_info, *tmp = NULL;
1729 	struct hdd_context *hdd_ctx;
1730 	char *buf;
1731 	int left;
1732 	int ret;
1733 	/* maclist_index must be u32 to match userspace */
1734 	u32 maclist_index;
1735 
1736 	hdd_enter_dev(dev);
1737 
1738 	/*
1739 	 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
1740 	 * number, and even numbered iocts are supposed to have "set"
1741 	 * semantics.  Hence the wireless extensions support in the kernel
1742 	 * won't correctly copy the result to userspace, so the ioctl
1743 	 * handler itself must copy the data.  Output format is 32-bit
1744 	 * record length, followed by 0 or more 6-byte STA MAC addresses.
1745 	 *
1746 	 * Further note that due to the incorrect semantics, the "iwpriv"
1747 	 * userspace application is unable to correctly invoke this API,
1748 	 * hence it is not registered in the hostapd_private_args.  This
1749 	 * API can only be invoked by directly invoking the ioctl() system
1750 	 * call.
1751 	 */
1752 
1753 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1754 	ret = wlan_hdd_validate_context(hdd_ctx);
1755 	if (0 != ret)
1756 		return ret;
1757 
1758 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1759 	if (0 != ret)
1760 		return ret;
1761 
1762 	/* make sure userspace allocated a reasonable buffer size */
1763 	if (wrqu->data.length < sizeof(maclist_index)) {
1764 		hdd_err("invalid userspace buffer");
1765 		return -EINVAL;
1766 	}
1767 
1768 	/* allocate local buffer to build the response */
1769 	buf = qdf_mem_malloc(wrqu->data.length);
1770 	if (!buf)
1771 		return -ENOMEM;
1772 
1773 	/* start indexing beyond where the record count will be written */
1774 	maclist_index = sizeof(maclist_index);
1775 	left = wrqu->data.length - maclist_index;
1776 
1777 	hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
1778 				  STA_INFO_SAP_GETASSOC_STAMACADDR) {
1779 		if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
1780 			memcpy(&buf[maclist_index], &sta_info->sta_mac,
1781 			       QDF_MAC_ADDR_SIZE);
1782 			maclist_index += QDF_MAC_ADDR_SIZE;
1783 			left -= QDF_MAC_ADDR_SIZE;
1784 		}
1785 		hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
1786 				     STA_INFO_SAP_GETASSOC_STAMACADDR);
1787 	}
1788 
1789 	*((u32 *) buf) = maclist_index;
1790 	wrqu->data.length = maclist_index;
1791 	if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
1792 		hdd_err("failed to copy response to user buffer");
1793 		ret = -EFAULT;
1794 	}
1795 	qdf_mem_free(buf);
1796 	hdd_exit();
1797 	return ret;
1798 }
1799 
1800 int
iw_softap_getassoc_stamacaddr(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1801 static iw_softap_getassoc_stamacaddr(struct net_device *dev,
1802 				     struct iw_request_info *info,
1803 				     union iwreq_data *wrqu, char *extra)
1804 {
1805 	int errno;
1806 	struct osif_vdev_sync *vdev_sync;
1807 
1808 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1809 	if (errno)
1810 		return errno;
1811 
1812 	errno = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
1813 
1814 	osif_vdev_sync_op_stop(vdev_sync);
1815 
1816 	return errno;
1817 }
1818 
1819 /* Usage:
1820  *  mac addr will be accepted as a 6 octet mac address with each octet
1821  *  inputted in hex for e.g. 00:0a:f5:11:22:33 will be represented as
1822  *  0x00 0x0a 0xf5 0x11 0x22 0x33 while using this ioctl
1823  *
1824  *  Syntax:
1825  *  iwpriv softap.0 disassoc_sta <6 octet mac address>
1826  *
1827  *  e.g.
1828  *  disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
1829  *  iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
1830  */
1831 
1832 int
__iw_softap_disassoc_sta(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1833 static __iw_softap_disassoc_sta(struct net_device *dev,
1834 				struct iw_request_info *info,
1835 				union iwreq_data *wrqu, char *extra)
1836 {
1837 	struct hdd_adapter *adapter = (netdev_priv(dev));
1838 	struct hdd_context *hdd_ctx;
1839 	uint8_t *peer_macaddr;
1840 	int ret;
1841 	struct csr_del_sta_params del_sta_params;
1842 
1843 	hdd_enter_dev(dev);
1844 
1845 	if (!capable(CAP_NET_ADMIN)) {
1846 		hdd_err("permission check failed");
1847 		return -EPERM;
1848 	}
1849 
1850 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1851 	ret = wlan_hdd_validate_context(hdd_ctx);
1852 	if (0 != ret)
1853 		return ret;
1854 
1855 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1856 	if (0 != ret)
1857 		return ret;
1858 
1859 	/* iwpriv tool or framework calls this ioctl with
1860 	 * data passed in extra (less than 16 octets);
1861 	 */
1862 	peer_macaddr = (uint8_t *) (extra);
1863 
1864 	hdd_debug("data " QDF_MAC_ADDR_FMT,
1865 		  QDF_MAC_ADDR_REF(peer_macaddr));
1866 	wlansap_populate_del_sta_params(peer_macaddr,
1867 					REASON_DEAUTH_NETWORK_LEAVING,
1868 					SIR_MAC_MGMT_DISASSOC,
1869 					&del_sta_params);
1870 	hdd_softap_sta_disassoc(adapter, &del_sta_params);
1871 
1872 	hdd_exit();
1873 	return 0;
1874 }
1875 
1876 int
iw_softap_disassoc_sta(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1877 static iw_softap_disassoc_sta(struct net_device *dev,
1878 			      struct iw_request_info *info,
1879 			      union iwreq_data *wrqu, char *extra)
1880 {
1881 	int errno;
1882 	struct osif_vdev_sync *vdev_sync;
1883 
1884 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1885 	if (errno)
1886 		return errno;
1887 
1888 	errno = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
1889 
1890 	osif_vdev_sync_op_stop(vdev_sync);
1891 
1892 	return errno;
1893 }
1894 
1895 /**
1896  * __iw_get_char_setnone() - Generic "get char" private ioctl handler
1897  * @dev: device upon which the ioctl was received
1898  * @info: ioctl request information
1899  * @wrqu: ioctl request data
1900  * @extra: ioctl extra data
1901  *
1902  * Return: 0 on success, non-zero on error
1903  */
__iw_get_char_setnone(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1904 static int __iw_get_char_setnone(struct net_device *dev,
1905 				struct iw_request_info *info,
1906 				union iwreq_data *wrqu, char *extra)
1907 {
1908 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1909 	int ret;
1910 	int sub_cmd = wrqu->data.flags;
1911 	struct hdd_context *hdd_ctx;
1912 
1913 	hdd_enter_dev(dev);
1914 
1915 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1916 	ret = wlan_hdd_validate_context(hdd_ctx);
1917 	if (ret != 0)
1918 		return ret;
1919 
1920 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1921 	if (0 != ret)
1922 		return ret;
1923 
1924 	switch (sub_cmd) {
1925 	case QCSAP_GET_STATS:
1926 		hdd_wlan_get_stats(adapter->deflink, &wrqu->data.length,
1927 				   extra, WE_MAX_STR_LEN);
1928 		break;
1929 	case QCSAP_LIST_FW_PROFILE:
1930 		hdd_wlan_list_fw_profile(&(wrqu->data.length),
1931 					extra, WE_MAX_STR_LEN);
1932 		break;
1933 	}
1934 
1935 	hdd_exit();
1936 	return ret;
1937 }
1938 
1939 /**
1940  * iw_get_char_setnone() - Generic "get char" private ioctl handler
1941  * @dev: device upon which the ioctl was received
1942  * @info: ioctl request information
1943  * @wrqu: ioctl request data
1944  * @extra: ioctl extra data
1945  *
1946  * Return: 0 on success, non-zero on error
1947  */
iw_get_char_setnone(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1948 static int iw_get_char_setnone(struct net_device *dev,
1949 				struct iw_request_info *info,
1950 				union iwreq_data *wrqu, char *extra)
1951 {
1952 	int errno;
1953 	struct osif_vdev_sync *vdev_sync;
1954 
1955 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
1956 	if (errno)
1957 		return errno;
1958 
1959 	errno = __iw_get_char_setnone(dev, info, wrqu, extra);
1960 
1961 	osif_vdev_sync_op_stop(vdev_sync);
1962 
1963 	return errno;
1964 }
1965 
iw_get_channel_list(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1966 static int iw_get_channel_list(struct net_device *dev,
1967 			       struct iw_request_info *info,
1968 			       union iwreq_data *wrqu, char *extra)
1969 {
1970 	uint32_t num_channels = 0;
1971 	uint8_t i = 0;
1972 	struct hdd_adapter *hostapd_adapter = (netdev_priv(dev));
1973 	struct channel_list_info *channel_list =
1974 		(struct channel_list_info *)extra;
1975 	struct regulatory_channel *cur_chan_list = NULL;
1976 	struct hdd_context *hdd_ctx;
1977 	int ret;
1978 	QDF_STATUS status;
1979 
1980 	hdd_enter_dev(dev);
1981 
1982 	hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
1983 	ret = wlan_hdd_validate_context(hdd_ctx);
1984 	if (0 != ret)
1985 		return ret;
1986 
1987 	ret = hdd_check_private_wext_control(hdd_ctx, info);
1988 	if (0 != ret)
1989 		return ret;
1990 
1991 	cur_chan_list = qdf_mem_malloc(sizeof(*cur_chan_list) * NUM_CHANNELS);
1992 	if (!cur_chan_list)
1993 		return -ENOMEM;
1994 
1995 	status = ucfg_reg_get_current_chan_list(hdd_ctx->pdev, cur_chan_list);
1996 	if (status != QDF_STATUS_SUCCESS) {
1997 		hdd_err_rl("Failed to get the current channel list");
1998 		qdf_mem_free(cur_chan_list);
1999 		return -EIO;
2000 	}
2001 
2002 	for (i = 0; i < NUM_CHANNELS; i++) {
2003 		/*
2004 		 * current channel list includes all channels. do not report
2005 		 * disabled channels
2006 		 */
2007 		if (cur_chan_list[i].chan_flags & REGULATORY_CHAN_DISABLED)
2008 			continue;
2009 
2010 		/*
2011 		 * do not include 6 GHz channels since they are ambiguous with
2012 		 * 2.4 GHz and 5 GHz channels. 6 GHz-aware applications should
2013 		 * not be using this interface, but instead should be using the
2014 		 * frequency-based interface
2015 		 */
2016 		if (wlan_reg_is_6ghz_chan_freq(cur_chan_list[i].center_freq))
2017 			continue;
2018 		channel_list->channels[num_channels] =
2019 						cur_chan_list[i].chan_num;
2020 		num_channels++;
2021 
2022 	}
2023 
2024 	qdf_mem_free(cur_chan_list);
2025 	hdd_debug_rl("number of channels %d", num_channels);
2026 	channel_list->num_channels = num_channels;
2027 	wrqu->data.length = num_channels + 1;
2028 	hdd_exit();
2029 
2030 	return 0;
2031 }
2032 
iw_get_channel_list_with_cc(struct net_device * dev,mac_handle_t mac_handle,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2033 int iw_get_channel_list_with_cc(struct net_device *dev,
2034 				mac_handle_t mac_handle,
2035 				struct iw_request_info *info,
2036 				union iwreq_data *wrqu,
2037 				char *extra)
2038 {
2039 	uint8_t i, len;
2040 	char *buf;
2041 	uint8_t ubuf[REG_ALPHA2_LEN + 1] = {0};
2042 	uint8_t ubuf_len = REG_ALPHA2_LEN + 1;
2043 	struct channel_list_info channel_list;
2044 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
2045 
2046 	hdd_enter_dev(dev);
2047 
2048 	memset(&channel_list, 0, sizeof(channel_list));
2049 
2050 	if (0 != iw_get_channel_list(dev, info, wrqu, (char *)&channel_list)) {
2051 		hdd_err_rl("GetChannelList Failed!!!");
2052 		return -EINVAL;
2053 	}
2054 
2055 	/*
2056 	 * Maximum buffer needed =
2057 	 * [4: 3 digits of num_chn + 1 space] +
2058 	 * [REG_ALPHA2_LEN: REG_ALPHA2_LEN digits] +
2059 	 * [4 * num_chn: (1 space + 3 digits of chn[i]) * num_chn] +
2060 	 * [1: Terminator].
2061 	 *
2062 	 * Check if sufficient buffer is available and then
2063 	 * proceed to fill the buffer.
2064 	 */
2065 	if (WE_MAX_STR_LEN <
2066 	    (4 + REG_ALPHA2_LEN + 4 * channel_list.num_channels + 1)) {
2067 		hdd_err_rl("Insufficient Buffer to populate channel list");
2068 		return -EINVAL;
2069 	}
2070 
2071 	buf = extra;
2072 	len = scnprintf(buf, WE_MAX_STR_LEN, "%u ", channel_list.num_channels);
2073 	wlan_reg_get_cc_and_src(mac->psoc, ubuf);
2074 	/* Printing Country code in getChannelList(break at '\0') */
2075 	for (i = 0; i < (ubuf_len - 1) && ubuf[i] != 0; i++)
2076 		len += scnprintf(buf + len, WE_MAX_STR_LEN - len, "%c", ubuf[i]);
2077 
2078 	for (i = 0; i < channel_list.num_channels; i++)
2079 		len += scnprintf(buf + len, WE_MAX_STR_LEN - len, " %u",
2080 				 channel_list.channels[i]);
2081 
2082 	wrqu->data.length = strlen(extra) + 1;
2083 
2084 	hdd_exit();
2085 	return 0;
2086 }
2087 
2088 static
__iw_get_genie(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2089 int __iw_get_genie(struct net_device *dev,
2090 		   struct iw_request_info *info,
2091 		   union iwreq_data *wrqu, char *extra)
2092 {
2093 	struct hdd_adapter *adapter = (netdev_priv(dev));
2094 	struct hdd_context *hdd_ctx;
2095 	int ret;
2096 	QDF_STATUS status;
2097 	uint32_t length = DOT11F_IE_RSN_MAX_LEN;
2098 	uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2099 
2100 	hdd_enter_dev(dev);
2101 
2102 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2103 	ret = wlan_hdd_validate_context(hdd_ctx);
2104 	if (0 != ret)
2105 		return ret;
2106 
2107 	ret = hdd_check_private_wext_control(hdd_ctx, info);
2108 	if (0 != ret)
2109 		return ret;
2110 
2111 	/*
2112 	 * Actually retrieve the RSN IE from CSR.
2113 	 * (We previously sent it down in the CSR Roam Profile.)
2114 	 */
2115 	status = wlan_sap_getstation_ie_information(
2116 		WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink),
2117 		&length, genIeBytes);
2118 	if (status == QDF_STATUS_SUCCESS) {
2119 		wrqu->data.length = length;
2120 		if (length > DOT11F_IE_RSN_MAX_LEN) {
2121 			hdd_err("Invalid buffer length: %d", length);
2122 			return -E2BIG;
2123 		}
2124 		qdf_mem_copy(extra, genIeBytes, length);
2125 		hdd_debug(" RSN IE of %d bytes returned",
2126 				wrqu->data.length);
2127 	} else {
2128 		wrqu->data.length = 0;
2129 		hdd_debug(" RSN IE failed to populate");
2130 	}
2131 
2132 	hdd_exit();
2133 	return 0;
2134 }
2135 
2136 static
iw_get_genie(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2137 int iw_get_genie(struct net_device *dev,
2138 		 struct iw_request_info *info,
2139 		 union iwreq_data *wrqu, char *extra)
2140 {
2141 	int errno;
2142 	struct osif_vdev_sync *vdev_sync;
2143 
2144 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
2145 	if (errno)
2146 		return errno;
2147 
2148 	errno = __iw_get_genie(dev, info, wrqu, extra);
2149 
2150 	osif_vdev_sync_op_stop(vdev_sync);
2151 
2152 	return errno;
2153 }
2154 
2155 static int
__iw_softap_stopbss(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2156 __iw_softap_stopbss(struct net_device *dev,
2157 		    struct iw_request_info *info,
2158 		    union iwreq_data *wrqu, char *extra)
2159 {
2160 	struct hdd_adapter *adapter = (netdev_priv(dev));
2161 	QDF_STATUS status;
2162 	struct hdd_context *hdd_ctx;
2163 	int ret;
2164 
2165 	hdd_enter_dev(dev);
2166 
2167 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2168 	ret = wlan_hdd_validate_context(hdd_ctx);
2169 	if (0 != ret)
2170 		return ret;
2171 
2172 	ret = hdd_check_private_wext_control(hdd_ctx, info);
2173 	if (0 != ret)
2174 		return ret;
2175 
2176 	if (test_bit(SOFTAP_BSS_STARTED, &adapter->deflink->link_flags)) {
2177 		struct hdd_hostapd_state *hostapd_state =
2178 			WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter->deflink);
2179 
2180 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
2181 		status = wlansap_stop_bss(
2182 			WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink));
2183 		if (QDF_IS_STATUS_SUCCESS(status)) {
2184 			status = qdf_wait_single_event(&hostapd_state->
2185 					qdf_stop_bss_event,
2186 					SME_CMD_STOP_BSS_TIMEOUT);
2187 
2188 			if (!QDF_IS_STATUS_SUCCESS(status)) {
2189 				hdd_err("wait for single_event failed!!");
2190 				QDF_ASSERT(0);
2191 			}
2192 		}
2193 		clear_bit(SOFTAP_BSS_STARTED, &adapter->deflink->link_flags);
2194 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
2195 					     adapter->device_mode,
2196 					     adapter->deflink->vdev_id);
2197 		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
2198 					    false);
2199 		ret = qdf_status_to_os_return(status);
2200 	}
2201 	hdd_exit();
2202 	return ret;
2203 }
2204 
iw_softap_stopbss(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2205 static int iw_softap_stopbss(struct net_device *dev,
2206 			     struct iw_request_info *info,
2207 			     union iwreq_data *wrqu,
2208 			     char *extra)
2209 {
2210 	int errno;
2211 	struct osif_vdev_sync *vdev_sync;
2212 
2213 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
2214 	if (errno)
2215 		return errno;
2216 
2217 	errno = __iw_softap_stopbss(dev, info, wrqu, extra);
2218 
2219 	osif_vdev_sync_op_stop(vdev_sync);
2220 
2221 	return errno;
2222 }
2223 
2224 static int
__iw_softap_version(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2225 __iw_softap_version(struct net_device *dev,
2226 		    struct iw_request_info *info,
2227 		    union iwreq_data *wrqu, char *extra)
2228 {
2229 	struct hdd_adapter *adapter = netdev_priv(dev);
2230 	struct hdd_context *hdd_ctx;
2231 	int ret;
2232 
2233 	hdd_enter_dev(dev);
2234 
2235 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2236 	ret = wlan_hdd_validate_context(hdd_ctx);
2237 	if (0 != ret)
2238 		return ret;
2239 
2240 	ret = hdd_check_private_wext_control(hdd_ctx, info);
2241 	if (0 != ret)
2242 		return ret;
2243 
2244 	wrqu->data.length = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN,
2245 						 extra);
2246 	hdd_exit();
2247 	return 0;
2248 }
2249 
iw_softap_version(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2250 static int iw_softap_version(struct net_device *dev,
2251 			     struct iw_request_info *info,
2252 			     union iwreq_data *wrqu,
2253 			     char *extra)
2254 {
2255 	int errno;
2256 	struct osif_vdev_sync *vdev_sync;
2257 
2258 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
2259 	if (errno)
2260 		return errno;
2261 
2262 	errno = __iw_softap_version(dev, info, wrqu, extra);
2263 
2264 	osif_vdev_sync_op_stop(vdev_sync);
2265 
2266 	return errno;
2267 }
2268 
hdd_softap_get_sta_info(struct hdd_adapter * adapter,uint8_t * buf,int size)2269 static int hdd_softap_get_sta_info(struct hdd_adapter *adapter,
2270 				   uint8_t *buf,
2271 				   int size)
2272 {
2273 	int written;
2274 	struct hdd_station_info *sta, *tmp = NULL;
2275 
2276 	hdd_enter();
2277 
2278 	written = scnprintf(buf, size, "\nstaId staAddress\n");
2279 
2280 	hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta, tmp,
2281 				  STA_INFO_SOFTAP_GET_STA_INFO) {
2282 		if (written >= size - 1) {
2283 			hdd_put_sta_info_ref(&adapter->sta_info_list,
2284 					     &sta, true,
2285 					     STA_INFO_SOFTAP_GET_STA_INFO);
2286 			if (tmp)
2287 				hdd_put_sta_info_ref(&adapter->sta_info_list,
2288 						&tmp, true,
2289 						STA_INFO_SOFTAP_GET_STA_INFO);
2290 			break;
2291 		}
2292 
2293 		if (QDF_IS_ADDR_BROADCAST(sta->sta_mac.bytes)) {
2294 			hdd_put_sta_info_ref(&adapter->sta_info_list,
2295 					     &sta, true,
2296 					     STA_INFO_SOFTAP_GET_STA_INFO);
2297 			continue;
2298 		}
2299 
2300 		written += scnprintf(buf + written, size - written,
2301 				     QDF_MAC_ADDR_FMT
2302 				     " ecsa=%d\n",
2303 				     QDF_MAC_ADDR_REF(sta->sta_mac.bytes),
2304 				     sta->ecsa_capable);
2305 		hdd_put_sta_info_ref(&adapter->sta_info_list, &sta, true,
2306 				     STA_INFO_SOFTAP_GET_STA_INFO);
2307 	}
2308 
2309 	hdd_exit();
2310 
2311 	return 0;
2312 }
2313 
__iw_softap_get_channel_list(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2314 static int __iw_softap_get_channel_list(struct net_device *dev,
2315 					struct iw_request_info *info,
2316 					union iwreq_data *wrqu,
2317 					char *extra)
2318 {
2319 	int ret;
2320 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2321 	struct hdd_context *hdd_ctx;
2322 	mac_handle_t mac_handle;
2323 
2324 	hdd_enter_dev(dev);
2325 
2326 	if (hdd_validate_adapter(adapter))
2327 		return -ENODEV;
2328 
2329 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2330 	ret = wlan_hdd_validate_context(hdd_ctx);
2331 	if (0 != ret)
2332 		return ret;
2333 
2334 	ret = hdd_check_private_wext_control(hdd_ctx, info);
2335 	if (0 != ret)
2336 		return ret;
2337 
2338 	mac_handle = hdd_ctx->mac_handle;
2339 
2340 	ret = iw_get_channel_list_with_cc(dev, mac_handle,
2341 					  info, wrqu, extra);
2342 
2343 	if (0 != ret)
2344 		return -EINVAL;
2345 
2346 	hdd_exit();
2347 	return 0;
2348 }
2349 
iw_softap_get_channel_list(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2350 static int iw_softap_get_channel_list(struct net_device *dev,
2351 				      struct iw_request_info *info,
2352 				      union iwreq_data *wrqu,
2353 				      char *extra)
2354 {
2355 	int errno;
2356 	struct osif_vdev_sync *vdev_sync;
2357 
2358 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
2359 	if (errno)
2360 		return errno;
2361 
2362 	errno = __iw_softap_get_channel_list(dev, info, wrqu, extra);
2363 
2364 	osif_vdev_sync_op_stop(vdev_sync);
2365 
2366 	return errno;
2367 }
2368 
__iw_softap_get_sta_info(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2369 static int __iw_softap_get_sta_info(struct net_device *dev,
2370 				    struct iw_request_info *info,
2371 				    union iwreq_data *wrqu, char *extra)
2372 {
2373 	int errno;
2374 	struct hdd_adapter *adapter;
2375 	struct hdd_context *hdd_ctx;
2376 
2377 	hdd_enter_dev(dev);
2378 
2379 	adapter = netdev_priv(dev);
2380 	errno = hdd_validate_adapter(adapter);
2381 	if (errno)
2382 		return errno;
2383 
2384 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2385 	errno = wlan_hdd_validate_context(hdd_ctx);
2386 	if (errno)
2387 		return errno;
2388 
2389 	errno = hdd_check_private_wext_control(hdd_ctx, info);
2390 	if (errno)
2391 		return errno;
2392 
2393 	errno = hdd_softap_get_sta_info(adapter, extra, WE_SAP_MAX_STA_INFO);
2394 	if (errno) {
2395 		hdd_err("Failed to get sta info; errno:%d", errno);
2396 		return errno;
2397 	}
2398 
2399 	wrqu->data.length = strlen(extra);
2400 
2401 	hdd_exit();
2402 
2403 	return 0;
2404 }
2405 
iw_softap_get_sta_info(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2406 static int iw_softap_get_sta_info(struct net_device *dev,
2407 				  struct iw_request_info *info,
2408 				  union iwreq_data *wrqu,
2409 				  char *extra)
2410 {
2411 	int errno;
2412 	struct osif_vdev_sync *vdev_sync;
2413 
2414 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
2415 	if (errno)
2416 		return errno;
2417 
2418 	errno = __iw_softap_get_sta_info(dev, info, wrqu, extra);
2419 
2420 	osif_vdev_sync_op_stop(vdev_sync);
2421 
2422 	return errno;
2423 }
2424 
__iw_softap_get_ba_timeout(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2425 static int __iw_softap_get_ba_timeout(struct net_device *dev,
2426 				      struct iw_request_info *info,
2427 				      union iwreq_data *wrqu, char *extra)
2428 {
2429 	int errno;
2430 	uint32_t i;
2431 	enum qca_wlan_ac_type duration[QCA_WLAN_AC_ALL];
2432 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
2433 	struct hdd_adapter *adapter;
2434 	struct hdd_context *hdd_ctx;
2435 
2436 	hdd_enter_dev(dev);
2437 
2438 	adapter = netdev_priv(dev);
2439 	errno = hdd_validate_adapter(adapter);
2440 	if (errno)
2441 		return errno;
2442 
2443 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2444 	errno = wlan_hdd_validate_context(hdd_ctx);
2445 	if (errno)
2446 		return errno;
2447 
2448 	if (!soc) {
2449 		hdd_err("Invalid handle");
2450 		return -EINVAL;
2451 	}
2452 
2453 	for (i = 0; i < QCA_WLAN_AC_ALL; i++)
2454 		cdp_get_ba_timeout(soc, i, &duration[i]);
2455 
2456 	snprintf(extra, WE_SAP_MAX_STA_INFO,
2457 		 "\n|------------------------------|\n"
2458 		 "|AC | BA aging timeout duration |\n"
2459 		 "|--------------------------------|\n"
2460 		 "|VO |  %d        |\n"
2461 		 "|VI |  %d        |\n"
2462 		 "|BK |  %d        |\n"
2463 		 "|BE |  %d        |\n"
2464 		 "|--------------------------------|\n",
2465 		duration[QCA_WLAN_AC_VO], duration[QCA_WLAN_AC_VI],
2466 		duration[QCA_WLAN_AC_BK], duration[QCA_WLAN_AC_BE]);
2467 
2468 	wrqu->data.length = strlen(extra) + 1;
2469 	hdd_exit();
2470 
2471 	return 0;
2472 }
2473 
iw_softap_get_ba_timeout(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2474 static int iw_softap_get_ba_timeout(struct net_device *dev,
2475 				    struct iw_request_info *info,
2476 				    union iwreq_data *wrqu,
2477 				    char *extra)
2478 {
2479 	int errno;
2480 	struct osif_vdev_sync *vdev_sync;
2481 
2482 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
2483 	if (errno)
2484 		return errno;
2485 
2486 	errno = __iw_softap_get_ba_timeout(dev, info, wrqu, extra);
2487 
2488 	osif_vdev_sync_op_stop(vdev_sync);
2489 
2490 	return errno;
2491 }
2492 
2493 static
__iw_get_softap_linkspeed(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2494 int __iw_get_softap_linkspeed(struct net_device *dev,
2495 			      struct iw_request_info *info,
2496 			      union iwreq_data *wrqu, char *extra)
2497 {
2498 	struct hdd_adapter *adapter = (netdev_priv(dev));
2499 	struct hdd_context *hdd_ctx;
2500 	char *out_link_speed = (char *)extra;
2501 	uint32_t link_speed = 0;
2502 	int len = sizeof(uint32_t) + 1;
2503 	struct qdf_mac_addr mac_address;
2504 	char macaddr_string[MAC_ADDRESS_STR_LEN + 1];
2505 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2506 	int rc, ret;
2507 
2508 	hdd_enter_dev(dev);
2509 
2510 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2511 	ret = wlan_hdd_validate_context(hdd_ctx);
2512 	if (0 != ret)
2513 		return ret;
2514 
2515 	ret = hdd_check_private_wext_control(hdd_ctx, info);
2516 	if (0 != ret)
2517 		return ret;
2518 
2519 	hdd_debug("wrqu->data.length(%d)", wrqu->data.length);
2520 
2521 	/* Linkspeed is allowed for GO/SAP mode */
2522 	if (adapter->device_mode != QDF_P2P_GO_MODE &&
2523 	    adapter->device_mode != QDF_SAP_MODE) {
2524 		hdd_err("Link Speed is not allowed in Device mode %s(%d)",
2525 			qdf_opmode_str(adapter->device_mode),
2526 			adapter->device_mode);
2527 		return -ENOTSUPP;
2528 	}
2529 
2530 	if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
2531 		if (copy_from_user(macaddr_string,
2532 				   wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) {
2533 			hdd_err("failed to copy data to user buffer");
2534 			return -EFAULT;
2535 		}
2536 		macaddr_string[MAC_ADDRESS_STR_LEN - 1] = '\0';
2537 
2538 		if (!mac_pton(macaddr_string, mac_address.bytes)) {
2539 			hdd_err("String to Hex conversion Failed");
2540 			return -EINVAL;
2541 		}
2542 	}
2543 	/* If no mac address is passed and/or its length is less than 17,
2544 	 * link speed for first connected client will be returned.
2545 	 */
2546 	if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) {
2547 		struct hdd_station_info *sta_info, *tmp = NULL;
2548 
2549 		hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
2550 					  STA_INFO_GET_SOFTAP_LINKSPEED) {
2551 			if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
2552 				qdf_copy_macaddr(&mac_address,
2553 						 &sta_info->sta_mac);
2554 				status = QDF_STATUS_SUCCESS;
2555 				hdd_put_sta_info_ref(
2556 						&adapter->sta_info_list,
2557 						&sta_info, true,
2558 						STA_INFO_GET_SOFTAP_LINKSPEED);
2559 				if (tmp)
2560 					hdd_put_sta_info_ref(
2561 						&adapter->sta_info_list,
2562 						&tmp, true,
2563 						STA_INFO_GET_SOFTAP_LINKSPEED);
2564 				break;
2565 			}
2566 			hdd_put_sta_info_ref(&adapter->sta_info_list,
2567 					     &sta_info, true,
2568 					     STA_INFO_GET_SOFTAP_LINKSPEED);
2569 		}
2570 	}
2571 	if (!QDF_IS_STATUS_SUCCESS(status)) {
2572 		hdd_err("Invalid peer macaddress");
2573 		return -EINVAL;
2574 	}
2575 	rc = wlan_hdd_get_linkspeed_for_peermac(adapter->deflink,
2576 						&mac_address, &link_speed);
2577 	if (rc) {
2578 		hdd_err("Unable to retrieve SME linkspeed");
2579 		return rc;
2580 	}
2581 
2582 	/* linkspeed in units of 500 kbps */
2583 	link_speed = link_speed / 500;
2584 	wrqu->data.length = len;
2585 	rc = snprintf(out_link_speed, len, "%u", link_speed);
2586 	if ((rc < 0) || (rc >= len)) {
2587 		/* encoding or length error? */
2588 		hdd_err("Unable to encode link speed");
2589 		return -EIO;
2590 	}
2591 	hdd_exit();
2592 	return 0;
2593 }
2594 
2595 static int
iw_get_softap_linkspeed(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2596 iw_get_softap_linkspeed(struct net_device *dev,
2597 			struct iw_request_info *info,
2598 			union iwreq_data *wrqu,
2599 			char *extra)
2600 {
2601 	int errno;
2602 	struct osif_vdev_sync *vdev_sync;
2603 
2604 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
2605 	if (errno)
2606 		return errno;
2607 
2608 	errno = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
2609 
2610 	osif_vdev_sync_op_stop(vdev_sync);
2611 
2612 	return errno;
2613 }
2614 
2615 /**
2616  * __iw_get_peer_rssi() - get station's rssi
2617  * @dev: net device
2618  * @info: iwpriv request information
2619  * @wrqu: iwpriv command parameter
2620  * @extra: extra data pointer
2621  *
2622  * This function will call wlan_cfg80211_mc_cp_stats_get_peer_rssi
2623  * to get rssi
2624  *
2625  * Return: 0 on success, otherwise error value
2626  */
2627 static int
__iw_get_peer_rssi(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2628 __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
2629 		   union iwreq_data *wrqu, char *extra)
2630 {
2631 	int ret, i;
2632 	struct hdd_context *hddctx;
2633 	struct stats_event *rssi_info;
2634 	char macaddrarray[MAC_ADDRESS_STR_LEN];
2635 	struct hdd_adapter *adapter = netdev_priv(dev);
2636 	struct qdf_mac_addr macaddress = QDF_MAC_ADDR_BCAST_INIT;
2637 	struct wlan_objmgr_vdev *vdev;
2638 
2639 	hdd_enter();
2640 
2641 	hddctx = WLAN_HDD_GET_CTX(adapter);
2642 	ret = wlan_hdd_validate_context(hddctx);
2643 	if (ret != 0)
2644 		return ret;
2645 
2646 	ret = hdd_check_private_wext_control(hddctx, info);
2647 	if (0 != ret)
2648 		return ret;
2649 
2650 	hdd_debug("wrqu->data.length= %d", wrqu->data.length);
2651 
2652 	if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
2653 		if (copy_from_user(macaddrarray,
2654 				   wrqu->data.pointer,
2655 				   MAC_ADDRESS_STR_LEN - 1)) {
2656 			hdd_info("failed to copy data from user buffer");
2657 			return -EFAULT;
2658 		}
2659 
2660 		macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0';
2661 		hdd_debug("%s", macaddrarray);
2662 
2663 		if (!mac_pton(macaddrarray, macaddress.bytes))
2664 			hdd_err("String to Hex conversion Failed");
2665 	}
2666 
2667 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink,
2668 					   WLAN_OSIF_STATS_ID);
2669 	if (!vdev)
2670 		return -EINVAL;
2671 
2672 	rssi_info = wlan_cfg80211_mc_cp_stats_get_peer_rssi(vdev,
2673 							    macaddress.bytes,
2674 							    &ret);
2675 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_STATS_ID);
2676 	if (ret || !rssi_info) {
2677 		wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
2678 		return ret;
2679 	}
2680 
2681 	wrqu->data.length = scnprintf(extra, IW_PRIV_SIZE_MASK, "\n");
2682 	for (i = 0; i < rssi_info->num_peer_stats; i++)
2683 		wrqu->data.length +=
2684 			scnprintf(extra + wrqu->data.length,
2685 				  IW_PRIV_SIZE_MASK - wrqu->data.length,
2686 				  "["QDF_MAC_ADDR_FMT"] [%d]\n",
2687 				  QDF_MAC_ADDR_REF(rssi_info->peer_stats[i].peer_macaddr),
2688 				  rssi_info->peer_stats[i].peer_rssi);
2689 
2690 	wrqu->data.length++;
2691 	wlan_cfg80211_mc_cp_stats_free_stats_event(rssi_info);
2692 	hdd_exit();
2693 
2694 	return 0;
2695 }
2696 
2697 /**
2698  * iw_get_peer_rssi() - get station's rssi
2699  * @dev: net device
2700  * @info: iwpriv request information
2701  * @wrqu: iwpriv command parameter
2702  * @extra: extra data pointer
2703  *
2704  * This function will call __iw_get_peer_rssi
2705  *
2706  * Return: 0 on success, otherwise error value
2707  */
2708 static int
iw_get_peer_rssi(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2709 iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
2710 		 union iwreq_data *wrqu, char *extra)
2711 {
2712 	int errno;
2713 	struct osif_vdev_sync *vdev_sync;
2714 
2715 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
2716 	if (errno)
2717 		return errno;
2718 
2719 	errno = __iw_get_peer_rssi(dev, info, wrqu, extra);
2720 
2721 	osif_vdev_sync_op_stop(vdev_sync);
2722 
2723 	return errno;
2724 }
2725 
2726 /*
2727  * Note that the following ioctls were defined with semantics which
2728  * cannot be handled by the "iwpriv" userspace application and hence
2729  * they are not included in the hostapd_private_args array
2730  *     QCSAP_IOCTL_ASSOC_STA_MACADDR
2731  */
2732 
2733 static const struct iw_priv_args hostapd_private_args[] = {
2734 	{
2735 		QCSAP_IOCTL_SETPARAM,
2736 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam"
2737 	}, {
2738 		QCSAP_IOCTL_SETPARAM,
2739 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""
2740 	}, {
2741 		QCSAP_PARAM_MAX_ASSOC,
2742 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2743 		"setMaxAssoc"
2744 	}, {
2745 		QCSAP_PARAM_HIDE_SSID,
2746 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID"
2747 	}, {
2748 		QCSAP_PARAM_SET_MC_RATE,
2749 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate"
2750 	}, {
2751 		QCSAP_PARAM_SET_TXRX_FW_STATS,
2752 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2753 		"txrx_fw_stats"
2754 	}, {
2755 		QCSAP_PARAM_SET_TXRX_STATS,
2756 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0,
2757 		"txrx_stats"
2758 	}, {
2759 		QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
2760 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2761 		"setMccLatency"
2762 	}, {
2763 		QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
2764 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2765 		"setMccQuota"
2766 	}, {
2767 		QCSAP_PARAM_SET_CHANNEL_CHANGE,
2768 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2769 		"setChanChange"
2770 	}, {
2771 		QCSAP_PARAM_CONC_SYSTEM_PREF,
2772 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2773 		"setConcSysPref"
2774 	},
2775 #ifdef FEATURE_FW_LOG_PARSING
2776 	/* Sub-cmds DBGLOG specific commands */
2777 	{
2778 		QCSAP_DBGLOG_LOG_LEVEL,
2779 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2780 		0, "dl_loglevel"
2781 	}, {
2782 		QCSAP_DBGLOG_VAP_ENABLE,
2783 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_vapon"
2784 	}, {
2785 		QCSAP_DBGLOG_VAP_DISABLE,
2786 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2787 		0, "dl_vapoff"
2788 	}, {
2789 		QCSAP_DBGLOG_MODULE_ENABLE,
2790 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_modon"
2791 	}, {
2792 		QCSAP_DBGLOG_MODULE_DISABLE,
2793 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2794 		0, "dl_modoff"
2795 	}, {
2796 		QCSAP_DBGLOG_MOD_LOG_LEVEL,
2797 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2798 		0, "dl_mod_loglevel"
2799 	}, {
2800 		QCSAP_DBGLOG_TYPE,
2801 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_type"
2802 	}, {
2803 		QCSAP_DBGLOG_REPORT_ENABLE,
2804 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2805 		0, "dl_report"
2806 	},
2807 #endif /* FEATURE_FW_LOG_PARSING */
2808 	{
2809 
2810 		QCASAP_TXRX_FWSTATS_RESET,
2811 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2812 		0, "txrx_fw_st_rst"
2813 	}, {
2814 		QCSAP_PARAM_RTSCTS,
2815 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2816 		0, "enablertscts"
2817 	}, {
2818 		QCASAP_SET_11N_RATE,
2819 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2820 		0, "set11NRates"
2821 	}, {
2822 		QCASAP_SET_VHT_RATE,
2823 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2824 		0, "set11ACRates"
2825 	}, {
2826 		QCASAP_SHORT_GI,
2827 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2828 		0, "enable_short_gi"
2829 	}, {
2830 		QCSAP_SET_AMPDU,
2831 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ampdu"
2832 	}, {
2833 		QCSAP_SET_AMSDU,
2834 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "amsdu"
2835 	}, {
2836 		QCSAP_GTX_HT_MCS,
2837 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxHTMcs"
2838 	}, {
2839 		QCSAP_GTX_VHT_MCS,
2840 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2841 		0, "gtxVHTMcs"
2842 	}, {
2843 		QCSAP_GTX_USRCFG,
2844 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2845 		0, "gtxUsrCfg"
2846 	}, {
2847 		QCSAP_GTX_THRE,
2848 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxThre"
2849 	}, {
2850 		QCSAP_GTX_MARGIN,
2851 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2852 		0, "gtxMargin"
2853 	}, {
2854 		QCSAP_GTX_STEP,
2855 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxStep"
2856 	}, {
2857 		QCSAP_GTX_MINTPC,
2858 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2859 		0, "gtxMinTpc"
2860 	}, {
2861 		QCSAP_GTX_BWMASK,
2862 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2863 		0, "gtxBWMask"
2864 	}, {
2865 		QCSAP_PARAM_CLR_ACL,
2866 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2867 		0, "setClearAcl"
2868 	}, {
2869 		QCSAP_PARAM_ACL_MODE,
2870 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode"
2871 	},
2872 	{
2873 		QCASAP_SET_TM_LEVEL,
2874 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2875 		0, "setTmLevel"
2876 	}, {
2877 		QCASAP_SET_DFS_IGNORE_CAC,
2878 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2879 		0, "setDfsIgnoreCAC"
2880 	}, {
2881 		QCASAP_SET_DFS_NOL,
2882 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2883 		0, "setdfsnol"
2884 	}, {
2885 		QCASAP_SET_DFS_TARGET_CHNL,
2886 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2887 		0, "setNextChnl"
2888 	}, {
2889 		QCASAP_SET_RADAR_CMD,
2890 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setRadar"
2891 	},
2892 	{
2893 		QCSAP_IPA_UC_STAT,
2894 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ipaucstat"
2895 	},
2896 	{
2897 		QCASAP_TX_CHAINMASK_CMD,
2898 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2899 		0, "set_txchainmask"
2900 	}, {
2901 		QCASAP_RX_CHAINMASK_CMD,
2902 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2903 		0, "set_rxchainmask"
2904 	}, {
2905 		QCASAP_SET_HE_BSS_COLOR,
2906 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_he_bss_clr"
2907 	}, {
2908 		QCASAP_NSS_CMD,
2909 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_nss"
2910 	}, {
2911 		QCASAP_SET_PHYMODE,
2912 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2913 		0, "setphymode"
2914 	}, {
2915 		QCASAP_DUMP_STATS,
2916 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2917 		0, "dumpStats"
2918 	}, {
2919 		QCASAP_CLEAR_STATS,
2920 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2921 		0, "clearStats"
2922 	}, {
2923 		QCSAP_START_FW_PROFILING,
2924 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2925 		0, "startProfile"
2926 	}, {
2927 		QCASAP_PARAM_LDPC,
2928 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2929 		0, "ldpc"
2930 	}, {
2931 		QCASAP_PARAM_TX_STBC,
2932 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2933 		0, "set_tx_stbc"
2934 	}, {
2935 		QCASAP_PARAM_RX_STBC,
2936 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2937 		0, "set_rx_stbc"
2938 	}, {
2939 		QCSAP_IOCTL_GETPARAM, 0,
2940 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam"
2941 	}, {
2942 		QCSAP_IOCTL_GETPARAM, 0,
2943 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""
2944 	}, {
2945 		QCSAP_PARAM_MAX_ASSOC, 0,
2946 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc"
2947 	}, {
2948 		QCSAP_PARAM_GET_WLAN_DBG, 0,
2949 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg"
2950 	}, {
2951 		QCSAP_GTX_BWMASK, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2952 		"get_gtxBWMask"
2953 	}, {
2954 		QCSAP_GTX_MINTPC, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2955 		"get_gtxMinTpc"
2956 	}, {
2957 		QCSAP_GTX_STEP, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2958 		"get_gtxStep"
2959 	}, {
2960 		QCSAP_GTX_MARGIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2961 		"get_gtxMargin"
2962 	}, {
2963 		QCSAP_GTX_THRE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2964 		"get_gtxThre"
2965 	}, {
2966 		QCSAP_GTX_USRCFG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2967 		"get_gtxUsrCfg"
2968 	}, {
2969 		QCSAP_GTX_VHT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2970 		"get_gtxVHTMcs"
2971 	}, {
2972 		QCSAP_GTX_HT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2973 		"get_gtxHTMcs"
2974 	}, {
2975 		QCASAP_SHORT_GI, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2976 		"get_short_gi"
2977 	}, {
2978 		QCSAP_PARAM_RTSCTS, 0,
2979 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rtscts"
2980 	}, {
2981 		QCASAP_GET_DFS_NOL, 0,
2982 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdfsnol"
2983 	}, {
2984 		QCSAP_GET_ACL, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2985 		"get_acl_list"
2986 	}, {
2987 		QCASAP_PARAM_LDPC, 0,
2988 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2989 		"get_ldpc"
2990 	}, {
2991 		QCASAP_PARAM_TX_STBC, 0,
2992 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2993 		"get_tx_stbc"
2994 	}, {
2995 		QCASAP_PARAM_RX_STBC, 0,
2996 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2997 		"get_rx_stbc"
2998 	}, {
2999 		QCSAP_PARAM_CHAN_WIDTH, 0,
3000 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3001 		"get_chwidth"
3002 	}, {
3003 		QCASAP_TX_CHAINMASK_CMD, 0,
3004 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3005 		"get_txchainmask"
3006 	}, {
3007 		QCASAP_RX_CHAINMASK_CMD, 0,
3008 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3009 		"get_rxchainmask"
3010 	}, {
3011 		QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3012 		"get_nss"
3013 	}, {
3014 		QCSAP_CAP_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3015 		"cap_tsf"
3016 	}, {
3017 		QCSAP_IOCTL_SET_NONE_GET_THREE, 0, IW_PRIV_TYPE_INT |
3018 		IW_PRIV_SIZE_FIXED | 3,    ""
3019 	}, {
3020 		QCSAP_GET_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
3021 		"get_tsf"
3022 	}, {
3023 		QCASAP_GET_TEMP_CMD, 0,
3024 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
3025 	}, {
3026 		QCSAP_GET_FW_PROFILE_DATA, 0,
3027 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData"
3028 	}, {
3029 		QCSAP_IOCTL_GET_STAWPAIE,
3030 		0, IW_PRIV_TYPE_BYTE | DOT11F_IE_RSN_MAX_LEN,
3031 		"get_staWPAIE"
3032 	}, {
3033 		QCSAP_IOCTL_STOPBSS, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0,
3034 		"stopbss"
3035 	}, {
3036 		QCSAP_IOCTL_VERSION, 0, IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
3037 		"version"
3038 	}, {
3039 		QCSAP_IOCTL_GET_STA_INFO, 0,
3040 		IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info"
3041 	}, {
3042 		QCSAP_IOCTL_GET_CHANNEL, 0,
3043 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
3044 	}, {
3045 		QCSAP_IOCTL_GET_BA_AGEING_TIMEOUT, 0,
3046 		IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_ba_timeout"
3047 	}, {
3048 		QCSAP_IOCTL_DISASSOC_STA,
3049 		IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6, 0,
3050 		"disassoc_sta"
3051 	}
3052 	/* handler for main ioctl */
3053 	, {
3054 		QCSAP_PRIV_GET_CHAR_SET_NONE, 0,
3055 		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, ""
3056 	}
3057 	/* handler for sub-ioctl */
3058 	, {
3059 		QCSAP_GET_STATS, 0,
3060 		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats"
3061 	}
3062 	, {
3063 		QCSAP_LIST_FW_PROFILE, 0,
3064 		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "listProfile"
3065 	}
3066 	, {
3067 		QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
3068 		IW_PRIV_TYPE_CHAR | 18,
3069 		IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
3070 	}
3071 	, {
3072 		QCSAP_IOCTL_PRIV_GET_RSSI,
3073 		IW_PRIV_TYPE_CHAR | 18,
3074 		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getRSSI"
3075 	}
3076 	, {
3077 		QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
3078 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""
3079 	}
3080 	,
3081 	/* handlers for sub-ioctl */
3082 	{
3083 		WE_SET_WLAN_DBG,
3084 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setwlandbg"
3085 	}
3086 	,
3087 #ifdef CONFIG_DP_TRACE
3088 	/* handlers for sub-ioctl */
3089 	{
3090 		WE_SET_DP_TRACE,
3091 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_dp_trace"
3092 	}
3093 	,
3094 #endif
3095 	/* handlers for main ioctl */
3096 	{
3097 		QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
3098 		IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, ""
3099 	}
3100 	, {
3101 		WE_P2P_NOA_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "SetP2pPs"
3102 	}
3103 	, {
3104 		WE_UNIT_TEST_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0,
3105 		"setUnitTestCmd"
3106 	}
3107 #ifdef WLAN_DEBUG
3108 	,
3109 	{
3110 		WE_SET_CHAN_AVOID,
3111 		IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3112 		0,
3113 		"ch_avoid"
3114 	}
3115 #endif
3116 	,
3117 	{
3118 		QCSAP_SET_BTCOEX_MODE,
3119 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3120 		0, "set_btc_mode"
3121 	}
3122 	,
3123 	{
3124 		QCSAP_SET_BTCOEX_LOW_RSSI_THRESHOLD,
3125 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3126 		0, "set_btc_rssi"
3127 	}
3128 	,
3129 #ifdef FW_THERMAL_THROTTLE_SUPPORT
3130 	{
3131 		WE_SET_THERMAL_THROTTLE_CFG,
3132 		IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3133 		0, "set_thermal_cfg"
3134 	}
3135 	,
3136 #endif /* FW_THERMAL_THROTTLE_SUPPORT */
3137 	/* handlers for main ioctl */
3138 	{
3139 		QCSAP_IOCTL_MODIFY_ACL,
3140 		IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, 0, "modify_acl"
3141 	}
3142 	,
3143 	/* handlers for main ioctl */
3144 	{
3145 		QCSAP_IOCTL_GET_CHANNEL_LIST,
3146 		0,
3147 		IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
3148 		"getChannelList"
3149 	}
3150 	,
3151 	/* handlers for main ioctl */
3152 	{
3153 		QCSAP_IOCTL_SET_TX_POWER,
3154 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setTxPower"
3155 	}
3156 	,
3157 	/* handlers for main ioctl */
3158 	{
3159 		QCSAP_IOCTL_SET_MAX_TX_POWER,
3160 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3161 		0, "setTxMaxPower"
3162 	}
3163 	,
3164 	{
3165 		QCSAP_IOCTL_SET_PKTLOG,
3166 		IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
3167 		0, "pktlog"
3168 	}
3169 	,
3170 	/* Get HDD CFG Ini param */
3171 	{
3172 		QCSAP_IOCTL_GET_INI_CFG,
3173 		0, IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, "getConfig"
3174 	}
3175 	,
3176 	/* handlers for main ioctl */
3177 	{
3178 	/* handlers for main ioctl */
3179 		QCSAP_IOCTL_SET_TWO_INT_GET_NONE,
3180 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""
3181 	}
3182 	,
3183 	/* handlers for sub-ioctl */
3184 #ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
3185 	{
3186 		QCSAP_IOCTL_SET_FW_CRASH_INJECT,
3187 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
3188 		0, "crash_inject"
3189 	}
3190 	,
3191 #endif
3192 	{
3193 		QCASAP_SET_RADAR_DBG,
3194 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3195 		0,  "setRadarDbg"
3196 	}
3197 	,
3198 #ifdef CONFIG_DP_TRACE
3199 	/* dump dp trace - descriptor or dp trace records */
3200 	{
3201 		QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL,
3202 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
3203 		0, "dump_dp_trace"
3204 	}
3205 	,
3206 #endif
3207 	{
3208 		QCSAP_ENABLE_FW_PROFILE,
3209 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
3210 		0, "enableProfile"
3211 	}
3212 	,
3213 	{
3214 		QCSAP_SET_FW_PROFILE_HIST_INTVL,
3215 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
3216 		0, "set_hist_intvl"
3217 	}
3218 	,
3219 #ifdef WLAN_SUSPEND_RESUME_TEST
3220 	{
3221 		QCSAP_SET_WLAN_SUSPEND,
3222 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
3223 		0, "wlan_suspend"
3224 	}
3225 	,
3226 	{
3227 		QCSAP_SET_WLAN_RESUME,
3228 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
3229 		0, "wlan_resume"
3230 	}
3231 	,
3232 #endif
3233 	{
3234 		QCSAP_SET_BA_AGEING_TIMEOUT,
3235 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
3236 		0, "set_ba_timeout"
3237 	}
3238 	,
3239 	{
3240 		QCASAP_SET_11AX_RATE,
3241 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3242 		0, "set_11ax_rate"
3243 	}
3244 	,
3245 	{
3246 		QCASAP_PARAM_DCM,
3247 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3248 		0, "enable_dcm"
3249 	}
3250 	,
3251 	{
3252 		QCASAP_PARAM_RANGE_EXT,
3253 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3254 		0, "range_ext"
3255 	}
3256 	,
3257 	{	QCSAP_SET_DEFAULT_AMPDU,
3258 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3259 		0, "def_ampdu"
3260 	}
3261 	,
3262 	{	QCSAP_ENABLE_RTS_BURSTING,
3263 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3264 		0, "rts_bursting"
3265 	}
3266 	,
3267 };
3268 
3269 static const iw_handler hostapd_private[] = {
3270 	/* set priv ioctl */
3271 	[QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,
3272 	/* get priv ioctl */
3273 	[QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,
3274 	[QCSAP_IOCTL_SET_NONE_GET_THREE - SIOCIWFIRSTPRIV] =
3275 							iw_softap_get_three,
3276 	/* get station genIE */
3277 	[QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie,
3278 	/* stop bss */
3279 	[QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss,
3280 	/* get driver version */
3281 	[QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version,
3282 	[QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] =
3283 		iw_softap_getchannel,
3284 	[QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] =
3285 		iw_softap_getassoc_stamacaddr,
3286 	[QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] =
3287 		iw_softap_disassoc_sta,
3288 	[QCSAP_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] =
3289 		iw_get_char_setnone,
3290 	[QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE -
3291 	 SIOCIWFIRSTPRIV] =
3292 		iw_set_three_ints_getnone,
3293 	[QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE -
3294 	 SIOCIWFIRSTPRIV] =
3295 		iw_set_var_ints_getnone,
3296 	[QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] =
3297 		iw_softap_modify_acl,
3298 	[QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] =
3299 		iw_softap_get_channel_list,
3300 	[QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] =
3301 		iw_softap_get_sta_info,
3302 	[QCSAP_IOCTL_GET_BA_AGEING_TIMEOUT - SIOCIWFIRSTPRIV] =
3303 		iw_softap_get_ba_timeout,
3304 	[QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED -
3305 	 SIOCIWFIRSTPRIV] =
3306 		iw_get_softap_linkspeed,
3307 	[QCSAP_IOCTL_PRIV_GET_RSSI - SIOCIWFIRSTPRIV] =
3308 		iw_get_peer_rssi,
3309 	[QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] =
3310 		iw_softap_set_tx_power,
3311 	[QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] =
3312 		iw_softap_set_max_tx_power,
3313 	[QCSAP_IOCTL_SET_PKTLOG - SIOCIWFIRSTPRIV] =
3314 		iw_softap_set_pktlog,
3315 	[QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] =
3316 		iw_softap_get_ini_cfg,
3317 	[QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
3318 		iw_softap_set_two_ints_getnone,
3319 };
3320 
3321 const struct iw_handler_def hostapd_handler_def = {
3322 	.num_standard = 0,
3323 	.num_private = QDF_ARRAY_SIZE(hostapd_private),
3324 	.num_private_args = QDF_ARRAY_SIZE(hostapd_private_args),
3325 	.standard = NULL,
3326 	.private = (iw_handler *)hostapd_private,
3327 	.private_args = hostapd_private_args,
3328 	.get_wireless_stats = NULL,
3329 };
3330 
3331 /**
3332  * hdd_register_hostapd_wext() - register hostapd wext context
3333  * @dev: net device handle
3334  *
3335  * Registers wext interface context for a given net device
3336  *
3337  * Returns: 0 on success, errno on failure
3338  */
hdd_register_hostapd_wext(struct net_device * dev)3339 void hdd_register_hostapd_wext(struct net_device *dev)
3340 {
3341 	hdd_enter_dev(dev);
3342 	/* Register as a wireless device */
3343 	dev->wireless_handlers = (struct iw_handler_def *)&hostapd_handler_def;
3344 
3345 	hdd_exit();
3346 }
3347 
3348