mwifiex: multiple bss support
authorShengzhen Li <szli@marvell.com>
Mon, 14 Dec 2015 12:15:03 +0000 (04:15 -0800)
committerKalle Valo <kvalo@codeaurora.org>
Wed, 30 Dec 2015 14:57:54 +0000 (16:57 +0200)
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>
drivers/net/wireless/marvell/mwifiex/cfg80211.c
drivers/net/wireless/marvell/mwifiex/decl.h
drivers/net/wireless/marvell/mwifiex/main.h

index 47d8afd..ab0ba6a 100644 (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));
index 098e1f1..d9c15cd 100644 (file)
 /* 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
 
index a86e2ae..10e614e 100644 (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);
 }