mwifiex: multiple bss support

This patch fixes issues observed while starting 3 different
bss simultaneously, eg, 2 AP + 1 STA or 3 AP

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Shengzhen Li 2015-12-14 04:15:03 -08:00 committed by Kalle Valo
parent eb5d912e15
commit 5b13d3e1f9
3 changed files with 51 additions and 17 deletions

View File

@ -825,18 +825,26 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
switch (type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
priv->bss_num = mwifiex_get_unused_bss_num(adapter,
MWIFIEX_BSS_TYPE_STA);
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
priv->bss_type = MWIFIEX_BSS_TYPE_STA;
break;
case NL80211_IFTYPE_P2P_CLIENT:
priv->bss_num = mwifiex_get_unused_bss_num(adapter,
MWIFIEX_BSS_TYPE_P2P);
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
break;
case NL80211_IFTYPE_P2P_GO:
priv->bss_num = mwifiex_get_unused_bss_num(adapter,
MWIFIEX_BSS_TYPE_P2P);
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
break;
case NL80211_IFTYPE_AP:
priv->bss_num = mwifiex_get_unused_bss_num(adapter,
MWIFIEX_BSS_TYPE_UAP);
priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
break;
@ -2606,7 +2614,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
return ERR_PTR(-EINVAL);
}
priv = mwifiex_get_unused_priv(adapter);
priv = mwifiex_get_unused_priv_by_bss_type(
adapter, MWIFIEX_BSS_TYPE_STA);
if (!priv) {
mwifiex_dbg(adapter, ERROR,
"could not get free private struct\n");
@ -2625,7 +2634,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
priv->bss_priority = 0;
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
priv->bss_num = adapter->curr_iface_comb.sta_intf;
break;
case NL80211_IFTYPE_AP:
@ -2636,7 +2644,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
return ERR_PTR(-EINVAL);
}
priv = mwifiex_get_unused_priv(adapter);
priv = mwifiex_get_unused_priv_by_bss_type(
adapter, MWIFIEX_BSS_TYPE_UAP);
if (!priv) {
mwifiex_dbg(adapter, ERROR,
"could not get free private struct\n");
@ -2651,7 +2660,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->bss_priority = 0;
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
priv->bss_started = 0;
priv->bss_num = adapter->curr_iface_comb.uap_intf;
priv->bss_mode = type;
break;
@ -2663,7 +2671,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
return ERR_PTR(-EINVAL);
}
priv = mwifiex_get_unused_priv(adapter);
priv = mwifiex_get_unused_priv_by_bss_type(
adapter, MWIFIEX_BSS_TYPE_P2P);
if (!priv) {
mwifiex_dbg(adapter, ERROR,
"could not get free private struct\n");
@ -2687,7 +2696,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
priv->bss_started = 0;
priv->bss_num = adapter->curr_iface_comb.p2p_intf;
if (mwifiex_cfg80211_init_p2p_client(priv)) {
memset(&priv->wdev, 0, sizeof(priv->wdev));

View File

@ -111,9 +111,9 @@
/* Rate index for OFDM 0 */
#define MWIFIEX_RATE_INDEX_OFDM0 4
#define MWIFIEX_MAX_STA_NUM 1
#define MWIFIEX_MAX_UAP_NUM 1
#define MWIFIEX_MAX_P2P_NUM 1
#define MWIFIEX_MAX_STA_NUM 3
#define MWIFIEX_MAX_UAP_NUM 3
#define MWIFIEX_MAX_P2P_NUM 3
#define MWIFIEX_A_BAND_START_FREQ 5000

View File

@ -1272,21 +1272,47 @@ mwifiex_get_priv(struct mwifiex_adapter *adapter,
return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
}
/*
* This function checks available bss_num when adding new interface or
* changing interface type.
*/
static inline u8
mwifiex_get_unused_bss_num(struct mwifiex_adapter *adapter, u8 bss_type)
{
u8 i, j;
int index[MWIFIEX_MAX_BSS_NUM];
memset(index, 0, sizeof(index));
for (i = 0; i < adapter->priv_num; i++)
if (adapter->priv[i]) {
if (adapter->priv[i]->bss_type == bss_type &&
!(adapter->priv[i]->bss_mode ==
NL80211_IFTYPE_UNSPECIFIED)) {
index[adapter->priv[i]->bss_num] = 1;
}
}
for (j = 0; j < MWIFIEX_MAX_BSS_NUM; j++)
if (!index[j])
return j;
return -1;
}
/*
* This function returns the first available unused private structure pointer.
*/
static inline struct mwifiex_private *
mwifiex_get_unused_priv(struct mwifiex_adapter *adapter)
mwifiex_get_unused_priv_by_bss_type(struct mwifiex_adapter *adapter,
u8 bss_type)
{
int i;
u8 i;
for (i = 0; i < adapter->priv_num; i++) {
if (adapter->priv[i]) {
if (adapter->priv[i]->bss_mode ==
NL80211_IFTYPE_UNSPECIFIED)
break;
for (i = 0; i < adapter->priv_num; i++)
if (adapter->priv[i]->bss_mode ==
NL80211_IFTYPE_UNSPECIFIED) {
adapter->priv[i]->bss_num =
mwifiex_get_unused_bss_num(adapter, bss_type);
break;
}
}
return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
}