ffaea53fbf
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 49381
120 lines
4.2 KiB
Diff
120 lines
4.2 KiB
Diff
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
|
Date: Thu, 26 May 2016 01:44:27 +0200
|
|
Subject: [PATCH] brcmfmac: rework function picking free BSS index
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
The old implementation was overcomplicated and slightly bugged in some
|
|
corner cases.
|
|
|
|
Consider following state of BSS-es (limited to 6 for simplification):
|
|
drvr->iflist[0]: { bsscfgidx:0, ndev->name:wlan1, }
|
|
drvr->iflist[1]: (null)
|
|
drvr->iflist[2]: { bsscfgidx:2, ndev->name:wlan1-1, }
|
|
drvr->iflist[3]: { bsscfgidx:3, ndev->name:wlan1-2, }
|
|
drvr->iflist[4]: (null)
|
|
drvr->iflist[5]: (null)
|
|
In such case the next AP interface should bsscfgidx 4 (we don't use 1 as
|
|
it's reserved for P2P).
|
|
|
|
With old code the loop iterations were following:
|
|
[ifidx = 0] [bsscfgidx = 2] [highest = 2]
|
|
[ifidx = 1] [bsscfgidx = 2] [highest = 2] available = true
|
|
[ifidx = 2] [bsscfgidx = 2] [highest = 2] bsscfgidx = highest + 1
|
|
[ifidx = 3] [bsscfgidx = 3] [highest = 2] bsscfgidx = highest + 1
|
|
[ifidx = 4] [bsscfgidx = 3] [highest = 2] available = true
|
|
[ifidx = 5] [bsscfgidx = 3] [highest = 2] available = true
|
|
There were 2 obvious problems:
|
|
1) Having empty BSS at index 1 was resulting in available being always
|
|
set to true, even if we would run out of BSS-es.
|
|
2) Calculated bsscfgidx was invalid (3 instead of 4) resulting in driver
|
|
not being able to create the 4th AP interface.
|
|
|
|
New code is simpler, placed in file where it's really used, handles
|
|
running out of free BSS-es and allows using 4 interfaces at the same
|
|
time. It also looks for the first free BSS instead of one after the last
|
|
in use. It works well with current driver (which doesn't allow deleting
|
|
interfaces) and should be future proof (if we ever allow deleting).
|
|
|
|
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
|
---
|
|
|
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
|
@@ -527,6 +527,21 @@ brcmf_cfg80211_update_proto_addr_mode(st
|
|
ADDR_INDIRECT);
|
|
}
|
|
|
|
+static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
|
|
+{
|
|
+ int bsscfgidx;
|
|
+
|
|
+ for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
|
|
+ /* bsscfgidx 1 is reserved for legacy P2P */
|
|
+ if (bsscfgidx == 1)
|
|
+ continue;
|
|
+ if (!drvr->iflist[bsscfgidx])
|
|
+ return bsscfgidx;
|
|
+ }
|
|
+
|
|
+ return -ENOMEM;
|
|
+}
|
|
+
|
|
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
|
|
{
|
|
struct brcmf_mbss_ssid_le mbss_ssid_le;
|
|
@@ -534,7 +549,7 @@ static int brcmf_cfg80211_request_ap_if(
|
|
int err;
|
|
|
|
memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
|
|
- bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
|
|
+ bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
|
|
if (bsscfgidx < 0)
|
|
return bsscfgidx;
|
|
|
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
|
@@ -753,30 +753,6 @@ void brcmf_remove_interface(struct brcmf
|
|
brcmf_del_if(ifp->drvr, ifp->bsscfgidx);
|
|
}
|
|
|
|
-int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr)
|
|
-{
|
|
- int ifidx;
|
|
- int bsscfgidx;
|
|
- bool available;
|
|
- int highest;
|
|
-
|
|
- available = false;
|
|
- bsscfgidx = 2;
|
|
- highest = 2;
|
|
- for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) {
|
|
- if (drvr->iflist[ifidx]) {
|
|
- if (drvr->iflist[ifidx]->bsscfgidx == bsscfgidx)
|
|
- bsscfgidx = highest + 1;
|
|
- else if (drvr->iflist[ifidx]->bsscfgidx > highest)
|
|
- highest = drvr->iflist[ifidx]->bsscfgidx;
|
|
- } else {
|
|
- available = true;
|
|
- }
|
|
- }
|
|
-
|
|
- return available ? bsscfgidx : -ENOMEM;
|
|
-}
|
|
-
|
|
#ifdef CONFIG_INET
|
|
#define ARPOL_MAX_ENTRIES 8
|
|
static int brcmf_inetaddr_changed(struct notifier_block *nb,
|
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
|
@@ -217,7 +217,6 @@ int brcmf_net_attach(struct brcmf_if *if
|
|
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
|
bool is_p2pdev, char *name, u8 *mac_addr);
|
|
void brcmf_remove_interface(struct brcmf_if *ifp);
|
|
-int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
|
|
void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
|
enum brcmf_netif_stop_reason reason, bool state);
|
|
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|