Commit 05910f4a authored by Amitkumar Karwar's avatar Amitkumar Karwar Committed by John W. Linville

mwifiex: add support to use basic rates in ibss join request

In mwifiex_set_rf_channel() ibss specific flags were unnecessarily
getting modified for infra and AP mode. This patch removes
mwifiex_set_rf_channel() function and adds equivalant code in infra,
ibss and AP path.

For ibss, now we are chosing band based on channel type and basic
rates provided in ibss join request. We can start ibss network in
A only, B only, G only, BG, BGN, AN mode.
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 006606c0
...@@ -48,10 +48,9 @@ static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = { ...@@ -48,10 +48,9 @@ static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = {
* Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE
*/ */
static u8 static u8
mwifiex_cfg80211_channel_type_to_sec_chan_offset(enum nl80211_channel_type mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
channel_type)
{ {
switch (channel_type) { switch (chan_type) {
case NL80211_CHAN_NO_HT: case NL80211_CHAN_NO_HT:
case NL80211_CHAN_HT20: case NL80211_CHAN_HT20:
return IEEE80211_HT_PARAM_CHA_SEC_NONE; return IEEE80211_HT_PARAM_CHA_SEC_NONE;
...@@ -338,68 +337,6 @@ static int mwifiex_reg_notifier(struct wiphy *wiphy, ...@@ -338,68 +337,6 @@ static int mwifiex_reg_notifier(struct wiphy *wiphy,
return 0; return 0;
} }
/*
* This function sets the RF channel.
*
* This function creates multiple IOCTL requests, populates them accordingly
* and issues them to set the band/channel and frequency.
*/
static int
mwifiex_set_rf_channel(struct mwifiex_private *priv,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
{
u32 config_bands = 0;
struct wiphy *wiphy = priv->wdev->wiphy;
struct mwifiex_adapter *adapter = priv->adapter;
if (chan) {
/* Set appropriate bands */
if (chan->band == IEEE80211_BAND_2GHZ) {
if (channel_type == NL80211_CHAN_NO_HT)
if (priv->adapter->config_bands == BAND_B ||
priv->adapter->config_bands == BAND_G)
config_bands =
priv->adapter->config_bands;
else
config_bands = BAND_B | BAND_G;
else
config_bands = BAND_B | BAND_G | BAND_GN;
} else {
if (channel_type == NL80211_CHAN_NO_HT)
config_bands = BAND_A;
else
config_bands = BAND_AN | BAND_A;
}
if (!((config_bands | adapter->fw_bands) &
~adapter->fw_bands)) {
adapter->config_bands = config_bands;
if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
adapter->adhoc_start_band = config_bands;
if ((config_bands & BAND_GN) ||
(config_bands & BAND_AN))
adapter->adhoc_11n_enabled = true;
else
adapter->adhoc_11n_enabled = false;
}
}
adapter->sec_chan_offset =
mwifiex_cfg80211_channel_type_to_sec_chan_offset
(channel_type);
adapter->channel_type = channel_type;
priv->adhoc_channel =
ieee80211_frequency_to_channel(chan->center_freq);
mwifiex_send_domain_info_cmd_fw(wiphy);
}
wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n",
config_bands, adapter->sec_chan_offset, priv->bss_mode);
return 0;
}
/* /*
* This function sets the fragmentation threshold. * This function sets the fragmentation threshold.
* *
...@@ -996,6 +933,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, ...@@ -996,6 +933,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
{ {
struct mwifiex_uap_bss_param *bss_cfg; struct mwifiex_uap_bss_param *bss_cfg;
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
u8 config_bands = 0;
if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP)
return -1; return -1;
...@@ -1036,13 +974,25 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, ...@@ -1036,13 +974,25 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
(u8)ieee80211_frequency_to_channel(params->channel->center_freq); (u8)ieee80211_frequency_to_channel(params->channel->center_freq);
bss_cfg->band_cfg = BAND_CONFIG_MANUAL; bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
if (mwifiex_set_rf_channel(priv, params->channel, /* Set appropriate bands */
params->channel_type)) { if (params->channel->band == IEEE80211_BAND_2GHZ) {
kfree(bss_cfg); if (params->channel_type == NL80211_CHAN_NO_HT)
wiphy_err(wiphy, "Failed to set band config information!\n"); config_bands = BAND_B | BAND_G;
return -1; else
config_bands = BAND_B | BAND_G | BAND_GN;
} else {
if (params->channel_type == NL80211_CHAN_NO_HT)
config_bands = BAND_A;
else
config_bands = BAND_AN | BAND_A;
} }
if (!((config_bands | priv->adapter->fw_bands) &
~priv->adapter->fw_bands))
priv->adapter->config_bands = config_bands;
mwifiex_send_domain_info_cmd_fw(wiphy);
if (mwifiex_set_secure_params(priv, bss_cfg, params)) { if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
kfree(bss_cfg); kfree(bss_cfg);
wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
...@@ -1176,7 +1126,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ...@@ -1176,7 +1126,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
struct cfg80211_ssid req_ssid; struct cfg80211_ssid req_ssid;
int ret, auth_type = 0; int ret, auth_type = 0;
struct cfg80211_bss *bss = NULL; struct cfg80211_bss *bss = NULL;
u8 is_scanning_required = 0; u8 is_scanning_required = 0, config_bands = 0;
memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
...@@ -1195,9 +1145,19 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ...@@ -1195,9 +1145,19 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
/* disconnect before try to associate */ /* disconnect before try to associate */
mwifiex_deauthenticate(priv, NULL); mwifiex_deauthenticate(priv, NULL);
if (channel) if (channel) {
ret = mwifiex_set_rf_channel(priv, channel, if (mode == NL80211_IFTYPE_STATION) {
priv->adapter->channel_type); if (channel->band == IEEE80211_BAND_2GHZ)
config_bands = BAND_B | BAND_G | BAND_GN;
else
config_bands = BAND_A | BAND_AN;
if (!((config_bands | priv->adapter->fw_bands) &
~priv->adapter->fw_bands))
priv->adapter->config_bands = config_bands;
}
mwifiex_send_domain_info_cmd_fw(priv->wdev->wiphy);
}
/* As this is new association, clear locally stored /* As this is new association, clear locally stored
* keys and security related flags */ * keys and security related flags */
...@@ -1361,6 +1321,76 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, ...@@ -1361,6 +1321,76 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return ret; return ret;
} }
/*
* This function sets following parameters for ibss network.
* - channel
* - start band
* - 11n flag
* - secondary channel offset
*/
static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
struct cfg80211_ibss_params *params)
{
struct wiphy *wiphy = priv->wdev->wiphy;
struct mwifiex_adapter *adapter = priv->adapter;
int index = 0, i;
u8 config_bands = 0;
if (params->channel->band == IEEE80211_BAND_2GHZ) {
if (!params->basic_rates) {
config_bands = BAND_B | BAND_G;
} else {
for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) {
/*
* Rates below 6 Mbps in the table are CCK
* rates; 802.11b and from 6 they are OFDM;
* 802.11G
*/
if (mwifiex_rates[i].bitrate == 60) {
index = 1 << i;
break;
}
}
if (params->basic_rates < index) {
config_bands = BAND_B;
} else {
config_bands = BAND_G;
if (params->basic_rates % index)
config_bands |= BAND_B;
}
}
if (params->channel_type != NL80211_CHAN_NO_HT)
config_bands |= BAND_GN;
} else {
if (params->channel_type == NL80211_CHAN_NO_HT)
config_bands = BAND_A;
else
config_bands = BAND_AN | BAND_A;
}
if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands)) {
adapter->config_bands = config_bands;
adapter->adhoc_start_band = config_bands;
if ((config_bands & BAND_GN) || (config_bands & BAND_AN))
adapter->adhoc_11n_enabled = true;
else
adapter->adhoc_11n_enabled = false;
}
adapter->sec_chan_offset =
mwifiex_chan_type_to_sec_chan_offset(params->channel_type);
priv->adhoc_channel =
ieee80211_frequency_to_channel(params->channel->center_freq);
wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n",
config_bands, priv->adhoc_channel, adapter->sec_chan_offset);
return 0;
}
/* /*
* CFG802.11 operation handler to join an IBSS. * CFG802.11 operation handler to join an IBSS.
* *
...@@ -1383,6 +1413,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, ...@@ -1383,6 +1413,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
(char *) params->ssid, params->bssid); (char *) params->ssid, params->bssid);
mwifiex_set_ibss_params(priv, params);
ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
params->bssid, priv->bss_mode, params->bssid, priv->bss_mode,
params->channel, NULL, params->privacy); params->channel, NULL, params->privacy);
...@@ -1808,6 +1840,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) ...@@ -1808,6 +1840,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1; wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1;
wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1; wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1;
wiphy->features = NL80211_FEATURE_HT_IBSS;
/* Reserve space for mwifiex specific private data for BSS */ /* Reserve space for mwifiex specific private data for BSS */
wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
......
...@@ -344,7 +344,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) ...@@ -344,7 +344,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
adapter->adhoc_awake_period = 0; adapter->adhoc_awake_period = 0;
memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
adapter->arp_filter_size = 0; adapter->arp_filter_size = 0;
adapter->channel_type = NL80211_CHAN_HT20;
adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment