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:
@@ -825,18 +825,26 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case NL80211_IFTYPE_STATION:
|
case NL80211_IFTYPE_STATION:
|
||||||
case NL80211_IFTYPE_ADHOC:
|
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_role = MWIFIEX_BSS_ROLE_STA;
|
||||||
priv->bss_type = MWIFIEX_BSS_TYPE_STA;
|
priv->bss_type = MWIFIEX_BSS_TYPE_STA;
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_P2P_CLIENT:
|
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_role = MWIFIEX_BSS_ROLE_STA;
|
||||||
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
|
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_P2P_GO:
|
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_role = MWIFIEX_BSS_ROLE_UAP;
|
||||||
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
|
priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_AP:
|
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_type = MWIFIEX_BSS_TYPE_UAP;
|
||||||
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
|
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
|
||||||
break;
|
break;
|
||||||
@@ -2606,7 +2614,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
|||||||
return ERR_PTR(-EINVAL);
|
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) {
|
if (!priv) {
|
||||||
mwifiex_dbg(adapter, ERROR,
|
mwifiex_dbg(adapter, ERROR,
|
||||||
"could not get free private struct\n");
|
"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->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
|
||||||
priv->bss_priority = 0;
|
priv->bss_priority = 0;
|
||||||
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
||||||
priv->bss_num = adapter->curr_iface_comb.sta_intf;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_AP:
|
case NL80211_IFTYPE_AP:
|
||||||
@@ -2636,7 +2644,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
|||||||
return ERR_PTR(-EINVAL);
|
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) {
|
if (!priv) {
|
||||||
mwifiex_dbg(adapter, ERROR,
|
mwifiex_dbg(adapter, ERROR,
|
||||||
"could not get free private struct\n");
|
"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_priority = 0;
|
||||||
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
|
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
|
||||||
priv->bss_started = 0;
|
priv->bss_started = 0;
|
||||||
priv->bss_num = adapter->curr_iface_comb.uap_intf;
|
|
||||||
priv->bss_mode = type;
|
priv->bss_mode = type;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -2663,7 +2671,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
|||||||
return ERR_PTR(-EINVAL);
|
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) {
|
if (!priv) {
|
||||||
mwifiex_dbg(adapter, ERROR,
|
mwifiex_dbg(adapter, ERROR,
|
||||||
"could not get free private struct\n");
|
"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_priority = MWIFIEX_BSS_ROLE_STA;
|
||||||
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
||||||
priv->bss_started = 0;
|
priv->bss_started = 0;
|
||||||
priv->bss_num = adapter->curr_iface_comb.p2p_intf;
|
|
||||||
|
|
||||||
if (mwifiex_cfg80211_init_p2p_client(priv)) {
|
if (mwifiex_cfg80211_init_p2p_client(priv)) {
|
||||||
memset(&priv->wdev, 0, sizeof(priv->wdev));
|
memset(&priv->wdev, 0, sizeof(priv->wdev));
|
||||||
|
@@ -111,9 +111,9 @@
|
|||||||
/* Rate index for OFDM 0 */
|
/* Rate index for OFDM 0 */
|
||||||
#define MWIFIEX_RATE_INDEX_OFDM0 4
|
#define MWIFIEX_RATE_INDEX_OFDM0 4
|
||||||
|
|
||||||
#define MWIFIEX_MAX_STA_NUM 1
|
#define MWIFIEX_MAX_STA_NUM 3
|
||||||
#define MWIFIEX_MAX_UAP_NUM 1
|
#define MWIFIEX_MAX_UAP_NUM 3
|
||||||
#define MWIFIEX_MAX_P2P_NUM 1
|
#define MWIFIEX_MAX_P2P_NUM 3
|
||||||
|
|
||||||
#define MWIFIEX_A_BAND_START_FREQ 5000
|
#define MWIFIEX_A_BAND_START_FREQ 5000
|
||||||
|
|
||||||
|
@@ -1272,21 +1272,47 @@ mwifiex_get_priv(struct mwifiex_adapter *adapter,
|
|||||||
return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
|
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.
|
* This function returns the first available unused private structure pointer.
|
||||||
*/
|
*/
|
||||||
static inline struct mwifiex_private *
|
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++) {
|
for (i = 0; i < adapter->priv_num; i++)
|
||||||
if (adapter->priv[i]) {
|
if (adapter->priv[i]->bss_mode ==
|
||||||
if (adapter->priv[i]->bss_mode ==
|
NL80211_IFTYPE_UNSPECIFIED) {
|
||||||
NL80211_IFTYPE_UNSPECIFIED)
|
adapter->priv[i]->bss_num =
|
||||||
break;
|
mwifiex_get_unused_bss_num(adapter, bss_type);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
|
return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user