From a055e9cb3beb83515f2a8dc1d42139e7ade437f1 Mon Sep 17 00:00:00 2001 From: Qun Zhang Date: Fri, 21 Jun 2019 17:13:31 +0800 Subject: [PATCH] qcacld-3.0: Align the output of getChannelList under sta/hostapd mode As requirement, it's also needed to print country code in iwpriv getChannelList under hostapd mode, align the output of getChannelList in sta/hostapd mode. At the same time, in __iw_get_channel_list(), the wrqu->data.length should be (the actual channel number+1), not sizeof(struct channel_list_info), otherwise there would be many zeros if call iw_get_channel_list() directly. Change-Id: I1e0fc1a026bf6c3fff2947ab4712a1800214ec0c CRs-Fixed: 2476458 --- core/hdd/inc/qc_sap_ioctl.h | 8 +- core/hdd/src/wlan_hdd_hostapd_wext.c | 135 ++++++++++++++++++++++----- core/hdd/src/wlan_hdd_wext.c | 46 +-------- 3 files changed, 118 insertions(+), 71 deletions(-) diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h index cdd216490090..f5d04b75563a 100644 --- a/core/hdd/inc/qc_sap_ioctl.h +++ b/core/hdd/inc/qc_sap_ioctl.h @@ -236,9 +236,11 @@ enum { QCSAP_SET_BTCOEX_LOW_RSSI_THRESHOLD, }; -int iw_get_channel_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); +int 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); #endif /* __linux__ */ diff --git a/core/hdd/src/wlan_hdd_hostapd_wext.c b/core/hdd/src/wlan_hdd_hostapd_wext.c index 5e32500d7988..62c3091d07da 100644 --- a/core/hdd/src/wlan_hdd_hostapd_wext.c +++ b/core/hdd/src/wlan_hdd_hostapd_wext.c @@ -1989,9 +1989,9 @@ static int iw_get_char_setnone(struct net_device *dev, return errno; } -static int __iw_get_channel_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) +static int iw_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { uint32_t num_channels = 0; uint8_t i = 0; @@ -2017,12 +2017,10 @@ static int __iw_get_channel_list(struct net_device *dev, if (0 != ret) return ret; - if (QDF_STATUS_SUCCESS != ucfg_reg_get_band(hdd_ctx->pdev, - &cur_band)) { - hdd_err("not able get the current frequency band"); + if (QDF_STATUS_SUCCESS != ucfg_reg_get_band(hdd_ctx->pdev, &cur_band)) { + hdd_err_rl("not able get the current frequency band"); return -EIO; } - wrqu->data.length = sizeof(struct channel_list_info); if (BAND_2G == cur_band) { band_start_channel = CHAN_ENUM_1; @@ -2042,14 +2040,14 @@ static int __iw_get_channel_list(struct net_device *dev, } else if (hostapd_adapter->device_mode == QDF_SAP_MODE) { if (QDF_STATUS_SUCCESS != ucfg_mlme_get_dfs_master_capability( hdd_ctx->psoc, &is_dfs_mode_enabled)) { - hdd_err("Fail to get dfs master mode capability"); + hdd_err_rl("Fail to get dfs master mode capability"); return -EINVAL; } } - hdd_debug("curBand = %d, StartChannel = %hu, EndChannel = %hu is_dfs_mode_enabled = %d ", - cur_band, band_start_channel, band_end_channel, - is_dfs_mode_enabled); + hdd_debug_rl("curBand = %d, StartChannel = %hu, EndChannel = %hu, is_dfs_mode_enabled = %d", + cur_band, band_start_channel, band_end_channel, + is_dfs_mode_enabled); for (i = band_start_channel; i <= band_end_channel; i++) { if ((CHANNEL_STATE_ENABLE == @@ -2064,30 +2062,60 @@ static int __iw_get_channel_list(struct net_device *dev, } } - hdd_debug("number of channels %d", num_channels); + hdd_debug_rl("number of channels %d", num_channels); channel_list->num_channels = num_channels; + wrqu->data.length = num_channels + 1; hdd_exit(); return 0; } -int iw_get_channel_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) +int 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) { - int errno; - struct osif_vdev_sync *vdev_sync; + uint8_t i, len; + char *buf; + uint8_t ubuf[CFG_COUNTRY_CODE_LEN] = {0}; + uint8_t ubuf_len = CFG_COUNTRY_CODE_LEN; + struct channel_list_info channel_list; - errno = osif_vdev_sync_op_start(dev, &vdev_sync); - if (errno) - return errno; + hdd_enter_dev(dev); - errno = __iw_get_channel_list(dev, info, wrqu, extra); + memset(&channel_list, 0, sizeof(channel_list)); - osif_vdev_sync_op_stop(vdev_sync); + if (0 != iw_get_channel_list(dev, info, wrqu, (char *)&channel_list)) { + hdd_err_rl("GetChannelList Failed!!!"); + return -EINVAL; + } + buf = extra; + /* + * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN. + * Maximum buffer needed = 5 * number of channels. + * Check if sufficient buffer is available and then + * proceed to fill the buffer. + */ + if (WE_MAX_STR_LEN < (5 * CFG_VALID_CHANNEL_LIST_LEN)) { + hdd_err_rl("Insufficient Buffer to populate channel list"); + return -EINVAL; + } + len = scnprintf(buf, WE_MAX_STR_LEN, "%u ", channel_list.num_channels); + if (QDF_STATUS_SUCCESS == sme_get_country_code(mac_handle, ubuf, + &ubuf_len)) { + /* Printing Country code in getChannelList */ + for (i = 0; i < (ubuf_len - 1); i++) + len += scnprintf(buf + len, WE_MAX_STR_LEN - len, "%c", ubuf[i]); + } + for (i = 0; i < channel_list.num_channels; i++) + len += scnprintf(buf + len, WE_MAX_STR_LEN - len, " %u", channel_list.channels[i]); - return errno; + wrqu->data.length = strlen(extra) + 1; + + hdd_exit(); + return 0; } static @@ -2314,6 +2342,63 @@ static int hdd_softap_get_sta_info(struct hdd_adapter *adapter, return 0; } +static int __iw_softap_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct hdd_context *hdd_ctx; + mac_handle_t mac_handle; + + hdd_enter_dev(dev); + + if (hdd_validate_adapter(adapter)) { + hdd_err_rl("Invalid adapter!!!"); + return -ENODEV; + } + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return ret; + + ret = hdd_check_private_wext_control(hdd_ctx, info); + if (0 != ret) + return ret; + + mac_handle = hdd_ctx->mac_handle; + + ret = iw_get_channel_list_with_cc(dev, mac_handle, + info, wrqu, extra); + + if (0 != ret) + return -EINVAL; + + hdd_exit(); + return 0; +} + +static int iw_softap_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(dev, &vdev_sync); + if (errno) + return errno; + + errno = __iw_softap_get_channel_list(dev, info, wrqu, extra); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} + static int __iw_softap_get_sta_info(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -3073,7 +3158,7 @@ static const struct iw_priv_args hostapd_private_args[] = { { QCSAP_IOCTL_GET_CHANNEL_LIST, 0, - IW_PRIV_TYPE_BYTE | sizeof(struct channel_list_info), + IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getChannelList" } , @@ -3231,7 +3316,7 @@ static const iw_handler hostapd_private[] = { [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl, [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = - iw_get_channel_list, + iw_softap_get_channel_list, [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info, [QCSAP_IOCTL_GET_BA_AGEING_TIMEOUT - SIOCIWFIRSTPRIV] = diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index ac061395f878..2f00ee94ce5e 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -7113,50 +7113,10 @@ static int __iw_get_char_setnone(struct net_device *dev, case WE_GET_CHANNEL_LIST: { - QDF_STATUS status; - uint8_t i, len; - char *buf; - uint8_t ubuf[CFG_COUNTRY_CODE_LEN]; - uint8_t ubuf_len = CFG_COUNTRY_CODE_LEN; - struct channel_list_info channel_list; - - memset(&channel_list, 0, sizeof(channel_list)); - status = iw_get_channel_list(dev, info, wrqu, - (char *)&channel_list); - if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("GetChannelList Failed!!!"); + if (0 != + iw_get_channel_list_with_cc(dev, mac_handle, + info, wrqu, extra)) return -EINVAL; - } - buf = extra; - /* - * Maximum channels = CFG_VALID_CHANNEL_LIST_LEN. - * Maximum buffer needed = 5 * number of channels. - * Check ifsufficient buffer is available and then - * proceed to fill the buffer. - */ - if (WE_MAX_STR_LEN < - (5 * CFG_VALID_CHANNEL_LIST_LEN)) { - hdd_err("Insufficient Buffer to populate channel list"); - return -EINVAL; - } - len = scnprintf(buf, WE_MAX_STR_LEN, "%u ", - channel_list.num_channels); - if (QDF_STATUS_SUCCESS == sme_get_country_code(mac_handle, - ubuf, - &ubuf_len)) { - /* Printing Country code in getChannelList */ - for (i = 0; i < (ubuf_len - 1); i++) - len += scnprintf(buf + len, - WE_MAX_STR_LEN - len, - "%c", ubuf[i]); - } - for (i = 0; i < channel_list.num_channels; i++) { - len += - scnprintf(buf + len, WE_MAX_STR_LEN - len, - " %u", channel_list.channels[i]); - } - wrqu->data.length = strlen(extra) + 1; - break; } #ifdef FEATURE_WLAN_TDLS