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