qcacld-3.0: Set Wi-Fi configurations - bandwidth configurations

Add attributes in SET(GET)_WIFI_CONFIGURATION to dynamically
configure capabilities - CHANNEL_WIDTH and DYNAMIC_BW.

Change-Id: I4d577f057e5d1b385ab7a6fadcb344dc30b85c4c
CRs-Fixed: 2694656
This commit is contained in:
Min Liu 2020-05-26 17:35:24 +08:00 • committed by nshrivas
commit fde76d4e9c
4 changed files with 245 additions and 29 deletions

View file

@ -34,6 +34,7 @@
#include <qdf_types.h>
#include <csr_api.h>
#include <sap_api.h>
#include <sir_mac_prot_def.h>
#include "osapi_linux.h"
#include <wmi_unified.h>
#include "wlan_pmo_hw_filter_public_struct.h"
@ -383,4 +384,16 @@ int hdd_get_rx_stbc(struct hdd_adapter *adapter, int *value);
* Return: 0 on success, negative errno on failure
*/
int hdd_set_rx_stbc(struct hdd_adapter *adapter, int value);
/**
* hdd_update_channel_width() - Update adapter channel width settings
* @adapter: adapter being modified
* @chwidth: new channel width of enum eSirMacHTChannelWidth
* @bonding_mode: channel bonding mode of the new channel width
*
* Return: 0 on success, negative errno on failure
*/
int hdd_update_channel_width(struct hdd_adapter *adapter,
enum eSirMacHTChannelWidth chwidth,
uint32_t bonding_mode);
#endif /* end #if !defined(HDD_CONFIG_H__) */

View file

@ -47,6 +47,7 @@
#include "wlan_fwol_ucfg_api.h"
#include "cfg_ucfg_api.h"
#include "hdd_dp_cfg.h"
#include <wma_api.h>
/**
* get_next_line() - find and locate the new line pointer
@ -1403,3 +1404,37 @@ int hdd_set_rx_stbc(struct hdd_adapter *adapter, int value)
return ret;
}
int hdd_update_channel_width(struct hdd_adapter *adapter,
enum eSirMacHTChannelWidth chwidth,
uint32_t bonding_mode)
{
struct hdd_context *hdd_ctx;
struct sme_config_params *sme_config;
int ret;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (!hdd_ctx) {
hdd_err("hdd_ctx failure");
return -EINVAL;
}
sme_config = qdf_mem_malloc(sizeof(*sme_config));
if (!sme_config)
return -ENOMEM;
ret = wma_cli_set_command(adapter->vdev_id, WMI_VDEV_PARAM_CHWIDTH,
chwidth, VDEV_CMD);
if (ret)
goto free_config;
sme_get_config_param(hdd_ctx->mac_handle, sme_config);
sme_config->csr_config.channelBondingMode5GHz = bonding_mode;
sme_config->csr_config.channelBondingMode24GHz = bonding_mode;
sme_update_config(hdd_ctx->mac_handle, sme_config);
free_config:
qdf_mem_free(sme_config);
return ret;
}

View file

@ -6714,6 +6714,8 @@ const struct nla_policy wlan_hdd_wifi_config_policy[
[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE] = {.type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_BW] = {.type = NLA_U8 },
};
@ -8233,6 +8235,125 @@ static int hdd_set_elna_bypass(struct hdd_adapter *adapter,
}
#endif
static enum eSirMacHTChannelWidth
hdd_nl80211_chwidth_to_chwidth(uint8_t nl80211_chwidth)
{
int chwidth;
switch (nl80211_chwidth) {
case NL80211_CHAN_WIDTH_20:
chwidth = eHT_CHANNEL_WIDTH_20MHZ;
break;
case NL80211_CHAN_WIDTH_40:
chwidth = eHT_CHANNEL_WIDTH_40MHZ;
break;
case NL80211_CHAN_WIDTH_80:
chwidth = eHT_CHANNEL_WIDTH_80MHZ;
break;
case NL80211_CHAN_WIDTH_80P80:
chwidth = eHT_CHANNEL_WIDTH_80P80MHZ;
break;
case NL80211_CHAN_WIDTH_160:
chwidth = eHT_CHANNEL_WIDTH_160MHZ;
break;
default:
hdd_err("Unsupported channel width %d", nl80211_chwidth);
chwidth = -EINVAL;
}
return chwidth;
}
static uint8_t
hdd_chwidth_to_nl80211_chwidth(enum eSirMacHTChannelWidth chwidth)
{
uint8_t nl80211_chwidth;
switch (chwidth) {
case eHT_CHANNEL_WIDTH_20MHZ:
nl80211_chwidth = NL80211_CHAN_WIDTH_20;
break;
case eHT_CHANNEL_WIDTH_40MHZ:
nl80211_chwidth = NL80211_CHAN_WIDTH_40;
break;
case eHT_CHANNEL_WIDTH_80MHZ:
nl80211_chwidth = NL80211_CHAN_WIDTH_80;
break;
case eHT_CHANNEL_WIDTH_80P80MHZ:
nl80211_chwidth = NL80211_CHAN_WIDTH_80P80;
break;
case eHT_CHANNEL_WIDTH_160MHZ:
nl80211_chwidth = NL80211_CHAN_WIDTH_160;
break;
default:
hdd_err("Unsupported channel width %d", chwidth);
nl80211_chwidth = 0xFF;
}
return nl80211_chwidth;
}
static uint32_t hdd_nl80211_chwidth_to_bonding_mode(uint8_t nl80211_chwidth)
{
uint32_t bonding_mode;
switch (nl80211_chwidth) {
case NL80211_CHAN_WIDTH_20:
bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
break;
default:
bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
}
return bonding_mode;
}
/**
* hdd_set_channel_width() - set channel width
*
* @adapter: hdd adapter
* @attr: nla attr sent by supplicant
*
* Return: 0 on success, negative errno on failure
*/
static int hdd_set_channel_width(struct hdd_adapter *adapter,
const struct nlattr *attr)
{
uint8_t nl80211_chwidth;
enum eSirMacHTChannelWidth chwidth;
uint32_t bonding_mode;
nl80211_chwidth = nla_get_u8(attr);
chwidth = hdd_nl80211_chwidth_to_chwidth(nl80211_chwidth);
if (chwidth < 0) {
hdd_err("Invalid channel width");
return -EINVAL;
}
bonding_mode = hdd_nl80211_chwidth_to_bonding_mode(nl80211_chwidth);
return hdd_update_channel_width(adapter, chwidth, bonding_mode);
}
/**
* hdd_set_dynamic_bw() - enable / disable dynamic bandwidth
*
* @adapter: hdd adapter
* @attr: nla attr sent by supplicant
*
* Return: 0 on success, negative errno on failure
*/
static int hdd_set_dynamic_bw(struct hdd_adapter *adapter,
const struct nlattr *attr)
{
uint8_t enable;
enable = nla_get_u8(attr);
return wma_cli_set_command(adapter->vdev_id, WMI_PDEV_PARAM_DYNAMIC_BW,
enable, PDEV_CMD);
}
/**
* typedef independent_setter_fn - independent attribute handler
* @adapter: The adapter being configured
@ -8333,6 +8454,10 @@ static const struct independent_setters independent_setters[] = {
hdd_config_rx_stbc},
{QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
hdd_config_phy_mode},
{QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
hdd_set_channel_width},
{QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_BW,
hdd_set_dynamic_bw},
};
#ifdef WLAN_FEATURE_ELNA
@ -8596,6 +8721,68 @@ static int hdd_get_rx_amsdu(struct hdd_adapter *adapter,
return 0;
}
/**
* hdd_get_channel_width() - Get channel width
* @adapter: Pointer to HDD adapter
* @skb: sk buffer to hold nl80211 attributes
* @attr: Pointer to struct nlattr
*
* Return: 0 on success; error number otherwise
*/
static int hdd_get_channel_width(struct hdd_adapter *adapter,
struct sk_buff *skb,
const struct nlattr *attr)
{
enum eSirMacHTChannelWidth chwidth;
uint8_t nl80211_chwidth;
chwidth = wma_cli_get_command(adapter->vdev_id, WMI_VDEV_PARAM_CHWIDTH,
VDEV_CMD);
if (chwidth < 0) {
hdd_err("Failed to get chwidth");
return -EINVAL;
}
nl80211_chwidth = hdd_chwidth_to_nl80211_chwidth(chwidth);
if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
nl80211_chwidth)) {
hdd_err("nla_put failure");
return -EINVAL;
}
return 0;
}
/**
* hdd_get_dynamic_bw() - Get dynamic bandwidth disabled / enabled
* @adapter: Pointer to HDD adapter
* @skb: sk buffer to hold nl80211 attributes
* @attr: Pointer to struct nlattr
*
* Return: 0 on success; error number otherwise
*/
static int hdd_get_dynamic_bw(struct hdd_adapter *adapter,
struct sk_buff *skb,
const struct nlattr *attr)
{
int enable;
enable = wma_cli_get_command(adapter->vdev_id,
WMI_PDEV_PARAM_DYNAMIC_BW, PDEV_CMD);
if (enable < 0) {
hdd_err("Failed to get dynamic_bw");
return -EINVAL;
}
if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_BW,
(uint8_t)enable)) {
hdd_err("nla_put failure");
return -EINVAL;
}
return 0;
}
/**
* typedef config_getter_fn - get configuration handler
* @adapter: The adapter being configured
@ -8652,6 +8839,12 @@ static const struct config_getters config_getters[] = {
{QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC,
sizeof(uint8_t),
hdd_vendor_attr_rx_stbc_get},
{QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
sizeof(uint8_t),
hdd_get_channel_width},
{QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_BW,
sizeof(uint8_t),
hdd_get_dynamic_bw},
};
/**

View file

@ -3574,15 +3574,7 @@ static int hdd_handle_pdev_reset(struct hdd_adapter *adapter, int value)
static int hdd_we_set_ch_width(struct hdd_adapter *adapter, int ch_width)
{
int errno;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
uint32_t bonding_mode;
struct sme_config_params *sme_config;
mac_handle_t mac_handle;
mac_handle = hdd_ctx->mac_handle;
if (!mac_handle)
return -EINVAL;
/* updating channel bonding only on 5Ghz */
hdd_debug("WMI_VDEV_PARAM_CHWIDTH val %d", ch_width);
@ -3594,7 +3586,9 @@ static int hdd_we_set_ch_width(struct hdd_adapter *adapter, int ch_width)
case eHT_CHANNEL_WIDTH_40MHZ:
case eHT_CHANNEL_WIDTH_80MHZ:
bonding_mode = 1;
case eHT_CHANNEL_WIDTH_80P80MHZ:
case eHT_CHANNEL_WIDTH_160MHZ:
bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
break;
default:
@ -3602,26 +3596,7 @@ static int hdd_we_set_ch_width(struct hdd_adapter *adapter, int ch_width)
return -EINVAL;
}
sme_config = qdf_mem_malloc(sizeof(*sme_config));
if (!sme_config) {
hdd_err("failed to allocate memory for sme_config");
return -ENOMEM;
}
errno = wma_cli_set_command(adapter->vdev_id, WMI_VDEV_PARAM_CHWIDTH,
ch_width, VDEV_CMD);
if (errno)
goto free_config;
sme_get_config_param(mac_handle, sme_config);
sme_config->csr_config.channelBondingMode5GHz = bonding_mode;
sme_config->csr_config.channelBondingMode24GHz = bonding_mode;
sme_update_config(mac_handle, sme_config);
free_config:
qdf_mem_free(sme_config);
return errno;
return hdd_update_channel_width(adapter, ch_width, bonding_mode);
}
static int hdd_we_set_11d_state(struct hdd_adapter *adapter, int state_11d)