qcacld-3.0: Set Wi-Fi configurations - PHY_MODE

Add attributes in SET_WIFI_CONFIGURATION to dynamically
configure capabilities - PHY_MODE.

Change-Id: I3085cfed5b188d2ccba87a4b47ac597ebbbec76e
CRs-Fixed: 2694250
Šī revīzija ir iekļauta:
Min Liu
2020-05-25 18:47:28 +08:00
revīziju iesūtīja nshrivas
vecāks aed685234b
revīzija 22bc5b94d3
6 mainīti faili ar 469 papildinājumiem un 306 dzēšanām

Parādīt failu

@@ -4439,4 +4439,21 @@ static inline void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx)
*/
void hdd_init_start_completion(void);
/**
* hdd_update_phymode() - update the PHY mode of the adapter
* @adapter: adapter being modified
* @phymode: new PHY mode for the adapter
* @band: new band for the adapter
* @chwidth: new channel width for the adapter
*
* This function is called when the adapter is set to a new PHY mode.
* It takes a holistic look at the desired PHY mode along with the
* configured capabilities of the driver and the reported capabilities
* of the hardware in order to correctly configure all PHY-related
* parameters.
*
* Return: 0 on success, negative errno value on error
*/
int hdd_update_phymode(struct hdd_adapter *adapter, eCsrPhyMode phymode,
enum band_info band, uint32_t chwidth);
#endif /* end #if !defined(WLAN_HDD_MAIN_H) */

Parādīt failu

@@ -258,7 +258,7 @@ int hdd_set_11ax_rate(struct hdd_adapter *adapter, int value,
struct sap_config *sap_config);
/**
* wlan_hdd_update_phymode() - handle change in PHY mode
* hdd_we_update_phymode() - handle change in PHY mode
* @adapter: adapter being modified
* @new_phymode: new PHY mode for the device
*
@@ -270,7 +270,8 @@ int hdd_set_11ax_rate(struct hdd_adapter *adapter, int value,
*
* Return: 0 on success, negative errno value on error
*/
int wlan_hdd_update_phymode(struct hdd_adapter *adapter, int new_phymode);
int hdd_we_update_phymode(struct hdd_adapter *adapter, int new_phymode);
/**
* wlan_hdd_update_btcoex_mode() - set BTCoex Mode
* @adapter: adapter being modified

Parādīt failu

@@ -6713,6 +6713,7 @@ const struct nla_policy wlan_hdd_wifi_config_policy[
[QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC] = {.type = NLA_U8 },
[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 },
};
@@ -7045,6 +7046,191 @@ static int wlan_hdd_cfg80211_wifi_set_rx_blocksize(struct hdd_adapter *adapter,
return ret_val;
}
static eCsrPhyMode
hdd_vendor_mode_to_phymode(enum qca_wlan_vendor_phy_mode vendor_phy_mode)
{
eCsrPhyMode phymode;
switch (vendor_phy_mode) {
case QCA_WLAN_VENDOR_PHY_MODE_AUTO:
case QCA_WLAN_VENDOR_PHY_MODE_2G_AUTO:
case QCA_WLAN_VENDOR_PHY_MODE_5G_AUTO:
phymode = eCSR_DOT11_MODE_AUTO;
break;
case QCA_WLAN_VENDOR_PHY_MODE_11A:
phymode = eCSR_DOT11_MODE_11a;
break;
case QCA_WLAN_VENDOR_PHY_MODE_11B:
phymode = eCSR_DOT11_MODE_11b;
break;
case QCA_WLAN_VENDOR_PHY_MODE_11G:
phymode = eCSR_DOT11_MODE_11g;
break;
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AGN:
phymode = eCSR_DOT11_MODE_11n;
break;
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80P80:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160:
phymode = eCSR_DOT11_MODE_11ac;
break;
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80P80:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160:
phymode = eCSR_DOT11_MODE_11ax;
break;
default:
hdd_err("Not supported mode %d", vendor_phy_mode);
phymode = -EINVAL;
}
return phymode;
}
static enum band_info
hdd_vendor_mode_to_band(enum qca_wlan_vendor_phy_mode vendor_phy_mode)
{
enum band_info band;
switch (vendor_phy_mode) {
case QCA_WLAN_VENDOR_PHY_MODE_AUTO:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80P80:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80P80:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160:
case QCA_WLAN_VENDOR_PHY_MODE_11AGN:
band = BAND_ALL;
break;
case QCA_WLAN_VENDOR_PHY_MODE_11A:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_5G_AUTO:
band = BAND_5G;
break;
case QCA_WLAN_VENDOR_PHY_MODE_11B:
case QCA_WLAN_VENDOR_PHY_MODE_11G:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_2G_AUTO:
band = BAND_2G;
break;
default:
hdd_err("Not supported mode %d", vendor_phy_mode);
band = -EINVAL;
}
return band;
}
static uint32_t
hdd_vendor_mode_to_chwidth(enum qca_wlan_vendor_phy_mode vendor_phy_mode)
{
uint32_t chwidth;
switch (vendor_phy_mode) {
case QCA_WLAN_VENDOR_PHY_MODE_AUTO:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80P80:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80P80:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160:
case QCA_WLAN_VENDOR_PHY_MODE_2G_AUTO:
case QCA_WLAN_VENDOR_PHY_MODE_5G_AUTO:
case QCA_WLAN_VENDOR_PHY_MODE_11AGN:
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
break;
case QCA_WLAN_VENDOR_PHY_MODE_11A:
case QCA_WLAN_VENDOR_PHY_MODE_11B:
case QCA_WLAN_VENDOR_PHY_MODE_11G:
case QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20:
case QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20:
case QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20:
case QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20:
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
break;
default:
hdd_err("Not supported mode %d", vendor_phy_mode);
chwidth = -EINVAL;
}
return chwidth;
}
/**
* hdd_config_phy_mode() - set PHY mode
* @adapter: hdd adapter
* @attr: nla attr sent by supplicant
*
* Return: 0 on success; error number otherwise
*/
static int hdd_config_phy_mode(struct hdd_adapter *adapter,
const struct nlattr *attr)
{
enum qca_wlan_vendor_phy_mode vendor_phy_mode;
eCsrPhyMode phymode;
enum band_info band;
uint32_t chwidth;
vendor_phy_mode = nla_get_u8(attr);
phymode = hdd_vendor_mode_to_phymode(vendor_phy_mode);
if (phymode < 0)
return -EINVAL;
band = hdd_vendor_mode_to_band(vendor_phy_mode);
if (band < 0)
return -EINVAL;
chwidth = hdd_vendor_mode_to_chwidth(vendor_phy_mode);
if (chwidth < 0)
return -EINVAL;
return hdd_update_phymode(adapter, phymode, band, chwidth);
}
/**
* hdd_set_roam_reason_vsie_status() - enable/disable inclusion of
* roam reason vsie in Reassoc
@@ -8145,6 +8331,8 @@ static const struct independent_setters independent_setters[] = {
hdd_config_tx_stbc},
{QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC,
hdd_config_rx_stbc},
{QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
hdd_config_phy_mode},
};
#ifdef WLAN_FEATURE_ELNA

Parādīt failu

@@ -926,7 +926,7 @@ static __iw_softap_setparam(struct net_device *dev,
}
case QCASAP_SET_PHYMODE:
ret = wlan_hdd_update_phymode(adapter, set_value);
ret = hdd_we_update_phymode(adapter, set_value);
break;
case QCASAP_DUMP_STATS:

Parādīt failu

@@ -17405,6 +17405,177 @@ QDF_STATUS hdd_monitor_mode_vdev_status(struct hdd_adapter *adapter)
}
#endif
static enum hdd_dot11_mode hdd_phymode_to_dot11_mode(eCsrPhyMode phymode)
{
enum hdd_dot11_mode dot11_mode;
switch (phymode) {
case eCSR_DOT11_MODE_AUTO:
dot11_mode = eHDD_DOT11_MODE_AUTO;
break;
case eCSR_DOT11_MODE_11a:
dot11_mode = eHDD_DOT11_MODE_11a;
break;
case eCSR_DOT11_MODE_11b:
dot11_mode = eHDD_DOT11_MODE_11b;
break;
case eCSR_DOT11_MODE_11g:
dot11_mode = eHDD_DOT11_MODE_11g;
break;
case eCSR_DOT11_MODE_11n:
dot11_mode = eHDD_DOT11_MODE_11n;
break;
case eCSR_DOT11_MODE_11ac:
dot11_mode = eHDD_DOT11_MODE_11ac;
break;
case eCSR_DOT11_MODE_11ax:
dot11_mode = eHDD_DOT11_MODE_11ax;
break;
default:
hdd_err("Not supported mode %d", phymode);
dot11_mode = -EINVAL;
}
return dot11_mode;
}
int hdd_update_phymode(struct hdd_adapter *adapter, eCsrPhyMode phymode,
enum band_info band, uint32_t chwidth)
{
struct net_device *net = adapter->dev;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct sme_config_params *sme_config = NULL;
struct csr_config_params *csr_config;
eCsrPhyMode old_phymode;
enum hdd_dot11_mode hdd_dot11mode;
uint32_t channel_bonding_mode;
uint8_t ui_band;
int ret = 0;
QDF_STATUS status;
ret = wlan_hdd_validate_context(hdd_ctx);
if (ret < 0)
return ret;
hdd_dot11mode = hdd_phymode_to_dot11_mode(phymode);
if (hdd_dot11mode < 0)
return -EINVAL;
hdd_debug("phymode=%d chwidth=%d band=%d", phymode, chwidth, band);
old_phymode = sme_get_phy_mode(hdd_ctx->mac_handle);
sme_set_phy_mode(hdd_ctx->mac_handle, phymode);
switch (band) {
case BAND_ALL:
ui_band = WLAN_HDD_UI_BAND_AUTO;
break;
case BAND_5G:
ui_band = WLAN_HDD_UI_BAND_5_GHZ;
break;
case BAND_2G:
ui_band = WLAN_HDD_UI_BAND_2_4_GHZ;
break;
default:
hdd_err("Invalid band %d", band);
return -EINVAL;
}
if (hdd_reg_set_band(net, ui_band)) {
sme_set_phy_mode(hdd_ctx->mac_handle, old_phymode);
return -EIO;
}
sme_config = qdf_mem_malloc(sizeof(*sme_config));
if (!sme_config) {
hdd_err("Failed to allocate memory for sme_config");
return -ENOMEM;
}
sme_get_config_param(hdd_ctx->mac_handle, sme_config);
csr_config = &sme_config->csr_config;
csr_config->phyMode = phymode;
#ifdef QCA_HT_2040_COEX
if (phymode == eCSR_DOT11_MODE_11n &&
chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
csr_config->obssEnabled = false;
status = sme_set_ht2040_mode(hdd_ctx->mac_handle,
adapter->vdev_id,
eHT_CHAN_HT20, false);
if (status == QDF_STATUS_E_FAILURE) {
hdd_err("Failed to disable OBSS");
ret = -EIO;
goto free;
}
} else if (phymode == eCSR_DOT11_MODE_11n &&
chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
csr_config->obssEnabled = true;
status = sme_set_ht2040_mode(hdd_ctx->mac_handle,
adapter->vdev_id,
eHT_CHAN_HT20, true);
if (status == QDF_STATUS_E_FAILURE) {
hdd_err("Failed to enable OBSS");
ret = -EIO;
goto free;
}
}
#endif
status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("failed to set MLME band capability");
ret = -EIO;
goto free;
}
if (band == BAND_2G) {
status = ucfg_mlme_set_11h_enabled(hdd_ctx->psoc, 0);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("Failed to set 11h_enable flag");
ret = -EIO;
goto free;
}
}
if (band == BAND_2G) {
csr_config->channelBondingMode24GHz = chwidth;
} else if (band == BAND_5G) {
csr_config->channelBondingMode5GHz = chwidth;
} else {
csr_config->channelBondingMode24GHz = chwidth;
csr_config->channelBondingMode5GHz = chwidth;
}
sme_update_config(hdd_ctx->mac_handle, sme_config);
hdd_ctx->config->dot11Mode = hdd_dot11mode;
ucfg_mlme_set_channel_bonding_24ghz(hdd_ctx->psoc,
csr_config->channelBondingMode24GHz);
ucfg_mlme_set_channel_bonding_5ghz(hdd_ctx->psoc,
csr_config->channelBondingMode5GHz);
if (hdd_update_config_cfg(hdd_ctx) == false) {
hdd_err("could not update config_dat");
ret = -EIO;
goto free;
}
if (band == BAND_ALL || band == BAND_5G) {
struct ieee80211_supported_band *ieee_band;
ucfg_mlme_get_channel_bonding_5ghz(hdd_ctx->psoc,
&channel_bonding_mode);
ieee_band = hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
if (channel_bonding_mode)
ieee_band->ht_cap.cap |=
IEEE80211_HT_CAP_SUP_WIDTH_20_40;
else
ieee_band->ht_cap.cap &=
~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
}
free:
if (sme_config)
qdf_mem_free(sme_config);
return ret;
}
#ifdef CONFIG_WLAN_DEBUG_CRASH_INJECT
int hdd_crash_inject(struct hdd_adapter *adapter, uint32_t v1, uint32_t v2)
{

Parādīt failu

@@ -3415,342 +3415,128 @@ static int iw_get_wlm_stats(struct net_device *net_dev,
}
#endif /* FEATURE_WLM_STATS */
int wlan_hdd_update_phymode(struct hdd_adapter *adapter, int new_phymode)
static eCsrPhyMode hdd_we_ieee_to_phymode(int ieee_mode)
{
struct net_device *net = adapter->dev;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
mac_handle_t mac_handle = hdd_ctx->mac_handle;
bool band_24 = false, band_5g = false;
bool ch_bond24 = false, ch_bond5g = false;
struct sme_config_params *sme_config = NULL;
struct csr_config_params *csr_config;
uint32_t chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
uint8_t vhtchanwidth;
eCsrPhyMode phymode = -EIO, old_phymode;
enum hdd_dot11_mode hdd_dot11mode = hdd_ctx->config->dot11Mode;
enum band_info curr_band = BAND_ALL;
int retval = 0;
uint8_t band_capability;
QDF_STATUS status;
uint32_t channel_bonding_mode;
eCsrPhyMode phymode;
if (!mac_handle)
return -EINVAL;
old_phymode = sme_get_phy_mode(mac_handle);
ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
&channel_bonding_mode);
if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
sme_get_cb_phy_state_from_cb_ini_value(channel_bonding_mode))
ch_bond24 = true;
ucfg_mlme_get_channel_bonding_5ghz(hdd_ctx->psoc,
&channel_bonding_mode);
if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
sme_get_cb_phy_state_from_cb_ini_value(channel_bonding_mode))
ch_bond5g = true;
status = wlan_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("Failed to get MLME Band capability");
return -EIO;
}
if (band_capability == BAND_ALL)
band_24 = band_5g = true;
else if (band_capability == BAND_2G)
band_24 = true;
else if (band_capability == BAND_5G)
band_5g = true;
status = ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc, &vhtchanwidth);
if (!QDF_IS_STATUS_SUCCESS(status))
hdd_err("Failed to get channel_width");
hdd_debug("ch_bond24=%d ch_bond5g=%d band_24=%d band_5g=%d VHT_ch_width=%u",
ch_bond24, ch_bond5g, band_24, band_5g, vhtchanwidth);
switch (new_phymode) {
switch (ieee_mode) {
case IEEE80211_MODE_AUTO:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_AUTO);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
phymode = eCSR_DOT11_MODE_AUTO;
hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
curr_band = BAND_ALL;
vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
case IEEE80211_MODE_2G_AUTO:
case IEEE80211_MODE_5G_AUTO:
phymode = eCSR_DOT11_MODE_AUTO;
break;
case IEEE80211_MODE_11A:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11a);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0) {
phymode = eCSR_DOT11_MODE_11a;
hdd_dot11mode = eHDD_DOT11_MODE_11a;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
curr_band = BAND_5G;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
phymode = eCSR_DOT11_MODE_11a;
break;
case IEEE80211_MODE_11B:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11b);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
phymode = eCSR_DOT11_MODE_11b;
hdd_dot11mode = eHDD_DOT11_MODE_11b;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
curr_band = BAND_2G;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
phymode = eCSR_DOT11_MODE_11b;
break;
case IEEE80211_MODE_11G:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11g);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
phymode = eCSR_DOT11_MODE_11g;
hdd_dot11mode = eHDD_DOT11_MODE_11g;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
curr_band = BAND_2G;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
phymode = eCSR_DOT11_MODE_11g;
break;
/* UMAC doesn't have option to set MODE_11NA/MODE_11NG as phymode
* so setting phymode as eCSR_DOT11_MODE_11n and updating the band
* and channel bonding in configuration to reflect MODE_11NA/MODE_11NG
*/
case IEEE80211_MODE_11NA_HT20:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0) {
phymode = eCSR_DOT11_MODE_11n;
hdd_dot11mode = eHDD_DOT11_MODE_11n;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
curr_band = BAND_5G;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
break;
case IEEE80211_MODE_11NA_HT40:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0) {
phymode = eCSR_DOT11_MODE_11n;
hdd_dot11mode = eHDD_DOT11_MODE_11n;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
curr_band = BAND_5G;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
break;
case IEEE80211_MODE_11NG_HT20:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
phymode = eCSR_DOT11_MODE_11n;
hdd_dot11mode = eHDD_DOT11_MODE_11n;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
curr_band = BAND_2G;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
break;
case IEEE80211_MODE_11NG_HT40:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
phymode = eCSR_DOT11_MODE_11n;
hdd_dot11mode = eHDD_DOT11_MODE_11n;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
curr_band = BAND_2G;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
case IEEE80211_MODE_11AGN:
phymode = eCSR_DOT11_MODE_11n;
break;
case IEEE80211_MODE_11AC_VHT20:
case IEEE80211_MODE_11AC_VHT40:
case IEEE80211_MODE_11AC_VHT80:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11ac);
phymode = eCSR_DOT11_MODE_11ac;
hdd_dot11mode = eHDD_DOT11_MODE_11ac;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
if (band_5g && band_24) {
curr_band = BAND_ALL;
break;
} else if (band_5g) {
curr_band = BAND_5G;
break;
} else if (new_phymode != IEEE80211_MODE_11AC_VHT80) {
curr_band = BAND_2G;
break;
}
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
curr_band = BAND_ALL;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
break;
case IEEE80211_MODE_2G_AUTO:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_AUTO);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0) {
phymode = eCSR_DOT11_MODE_AUTO;
hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
curr_band = BAND_2G;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
break;
case IEEE80211_MODE_5G_AUTO:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_AUTO);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0) {
phymode = eCSR_DOT11_MODE_AUTO;
hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
curr_band = BAND_5G;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
break;
case IEEE80211_MODE_11AGN:
sme_set_phy_mode(mac_handle, eCSR_DOT11_MODE_11n);
if (hdd_reg_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
phymode = eCSR_DOT11_MODE_11n;
hdd_dot11mode = eHDD_DOT11_MODE_11n;
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
curr_band = BAND_ALL;
} else {
sme_set_phy_mode(mac_handle, old_phymode);
return -EIO;
}
break;
default:
return -EIO;
hdd_err("Not supported mode %d", ieee_mode);
phymode = -EINVAL;
}
switch (new_phymode) {
return phymode;
}
static enum band_info hdd_we_ieee_to_band(int ieee_mode)
{
enum band_info band;
switch (ieee_mode) {
case IEEE80211_MODE_AUTO:
case IEEE80211_MODE_11AC_VHT20:
case IEEE80211_MODE_11AC_VHT40:
case IEEE80211_MODE_11AC_VHT80:
case IEEE80211_MODE_11AGN:
band = BAND_ALL;
break;
case IEEE80211_MODE_11A:
case IEEE80211_MODE_11NA_HT20:
case IEEE80211_MODE_11NA_HT40:
case IEEE80211_MODE_5G_AUTO:
band = BAND_5G;
break;
case IEEE80211_MODE_11B:
case IEEE80211_MODE_11G:
case IEEE80211_MODE_11NG_HT20:
case IEEE80211_MODE_11NG_HT40:
case IEEE80211_MODE_2G_AUTO:
band = BAND_2G;
break;
default:
hdd_err("Not supported mode %d", ieee_mode);
band = -EINVAL;
}
return band;
}
static uint32_t hdd_we_ieee_to_chwidth(int ieee_mode)
{
uint32_t chwidth;
switch (ieee_mode) {
case IEEE80211_MODE_AUTO:
case IEEE80211_MODE_11NA_HT40:
case IEEE80211_MODE_11NG_HT40:
case IEEE80211_MODE_11AC_VHT40:
case IEEE80211_MODE_11AC_VHT80:
case IEEE80211_MODE_2G_AUTO:
case IEEE80211_MODE_5G_AUTO:
case IEEE80211_MODE_11AGN:
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
break;
case IEEE80211_MODE_11A:
case IEEE80211_MODE_11B:
case IEEE80211_MODE_11G:
case IEEE80211_MODE_11NA_HT20:
case IEEE80211_MODE_11NG_HT20:
case IEEE80211_MODE_11AC_VHT20:
chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
vhtchanwidth = eHT_CHANNEL_WIDTH_20MHZ;
break;
case IEEE80211_MODE_11AC_VHT40:
vhtchanwidth = eHT_CHANNEL_WIDTH_40MHZ;
break;
case IEEE80211_MODE_11AC_VHT80:
vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
break;
default:
status = ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc,
&vhtchanwidth);
if (!QDF_IS_STATUS_SUCCESS(status))
hdd_err("Failed to get channel_width");
break;
hdd_err("Not supported mode %d", ieee_mode);
chwidth = -EINVAL;
}
if (phymode != -EIO) {
sme_config = qdf_mem_malloc(sizeof(*sme_config));
if (!sme_config) {
hdd_err("Failed to allocate memory for sme_config");
return -ENOMEM;
}
qdf_mem_zero(sme_config, sizeof(*sme_config));
sme_get_config_param(mac_handle, sme_config);
csr_config = &sme_config->csr_config;
csr_config->phyMode = phymode;
#ifdef QCA_HT_2040_COEX
if (phymode == eCSR_DOT11_MODE_11n &&
chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
csr_config->obssEnabled = false;
status = sme_set_ht2040_mode(mac_handle,
adapter->vdev_id,
eHT_CHAN_HT20, false);
if (status == QDF_STATUS_E_FAILURE) {
hdd_err("Failed to disable OBSS");
retval = -EIO;
goto free;
}
} else if (phymode == eCSR_DOT11_MODE_11n &&
chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
csr_config->obssEnabled = true;
status = sme_set_ht2040_mode(mac_handle,
adapter->vdev_id,
eHT_CHAN_HT20, true);
if (status == QDF_STATUS_E_FAILURE) {
hdd_err("Failed to enable OBSS");
retval = -EIO;
goto free;
}
}
#endif
status = ucfg_mlme_set_band_capability(hdd_ctx->psoc,
curr_band);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("failed to set MLME band capability");
goto free;
}
return chwidth;
}
if (curr_band == BAND_2G) {
status = ucfg_mlme_set_11h_enabled(hdd_ctx->psoc, 0);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("Failed to set 11h_enable flag");
goto free;
}
}
if (curr_band == BAND_2G)
csr_config->channelBondingMode24GHz = chwidth;
else if (curr_band == BAND_5G)
csr_config->channelBondingMode5GHz = chwidth;
else {
csr_config->channelBondingMode24GHz = chwidth;
csr_config->channelBondingMode5GHz = chwidth;
}
sme_update_config(mac_handle, sme_config);
int hdd_we_update_phymode(struct hdd_adapter *adapter, int new_phymode)
{
eCsrPhyMode phymode;
enum band_info band;
uint32_t chwidth;
hdd_ctx->config->dot11Mode = hdd_dot11mode;
ucfg_mlme_set_channel_bonding_24ghz(
hdd_ctx->psoc,
csr_config->channelBondingMode24GHz);
ucfg_mlme_set_channel_bonding_5ghz(
hdd_ctx->psoc,
csr_config->channelBondingMode5GHz);
if (hdd_update_config_cfg(hdd_ctx) == false) {
hdd_err("could not update config_dat");
retval = -EIO;
goto free;
}
phymode = hdd_we_ieee_to_phymode(new_phymode);
if (phymode < 0)
return -EINVAL;
if (band_5g) {
struct ieee80211_supported_band *band;
band = hdd_we_ieee_to_band(new_phymode);
if (band < 0)
return -EINVAL;
ucfg_mlme_get_channel_bonding_5ghz(
hdd_ctx->psoc, &channel_bonding_mode);
band = hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
if (channel_bonding_mode)
band->ht_cap.cap |=
IEEE80211_HT_CAP_SUP_WIDTH_20_40;
else
band->ht_cap.cap &=
~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
}
chwidth = hdd_we_ieee_to_chwidth(new_phymode);
if (chwidth < 0)
return -EINVAL;
hdd_debug("New_Phymode= %d ch_bonding=%d band=%d VHT_ch_width=%u",
phymode, chwidth, curr_band, vhtchanwidth);
}
free:
if (sme_config)
qdf_mem_free(sme_config);
return retval;
return hdd_update_phymode(adapter, phymode, band, chwidth);
}
static int hdd_validate_pdev_reset(int value)
@@ -5155,7 +4941,7 @@ static const setint_getnone_fn setint_getnone_cb[] = {
[WE_SET_HASTINGS_BT_WAR] = hdd_we_set_hastings_bt_war,
#endif
[WE_SET_TM_LEVEL] = hdd_we_set_tm_level,
[WE_SET_PHYMODE] = wlan_hdd_update_phymode,
[WE_SET_PHYMODE] = hdd_we_update_phymode,
[WE_SET_NSS] = hdd_we_set_nss,
[WE_SET_GTX_HT_MCS] = hdd_we_set_gtx_ht_mcs,
[WE_SET_GTX_VHT_MCS] = hdd_we_set_gtx_vht_mcs,