mirror of
https://github.com/hak5/wifipineapple-openwrt.git
synced 2025-10-29 16:57:19 +00:00
mac80211: brcmfmac: fix support for BCM4366
1) Fix setting AP channel 2) Improve BSS management to avoid: [ 3602.929199] brcmfmac: brcmf_ap_add_vif: timeout occurred Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Backport of r49383 git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@49386 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
0e29de61f7
commit
468fe950b8
@ -0,0 +1,59 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Fri, 27 May 2016 10:54:28 +0200
|
||||
Subject: [PATCH] brcmfmac: print errors if creating interface fails
|
||||
|
||||
This is helpful for debugging. Without this all I was getting from "iw"
|
||||
command on failed creating of P2P interface was:
|
||||
> command failed: Too many open files in system (-23)
|
||||
|
||||
Signed-off-by: Rafal Milecki <zajec5@gmail.com>
|
||||
[arend@broadcom.com: reduce error prints upon iface creation]
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Julian Calaby <julian.calaby@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
|
||||
@@ -649,20 +649,24 @@ static struct wireless_dev *brcmf_cfg802
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
case NL80211_IFTYPE_AP:
|
||||
wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
|
||||
- if (!IS_ERR(wdev))
|
||||
- brcmf_cfg80211_update_proto_addr_mode(wdev);
|
||||
- return wdev;
|
||||
+ break;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
|
||||
- if (!IS_ERR(wdev))
|
||||
- brcmf_cfg80211_update_proto_addr_mode(wdev);
|
||||
- return wdev;
|
||||
+ break;
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
default:
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
+
|
||||
+ if (IS_ERR(wdev))
|
||||
+ brcmf_err("add iface %s type %d failed: err=%d\n",
|
||||
+ name, type, (int)PTR_ERR(wdev));
|
||||
+ else
|
||||
+ brcmf_cfg80211_update_proto_addr_mode(wdev);
|
||||
+
|
||||
+ return wdev;
|
||||
}
|
||||
|
||||
static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -2020,8 +2020,6 @@ static int brcmf_p2p_request_p2p_if(stru
|
||||
|
||||
err = brcmf_fil_iovar_data_set(ifp, "p2p_ifadd", &if_request,
|
||||
sizeof(if_request));
|
||||
- if (err)
|
||||
- return err;
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Fri, 27 May 2016 21:07:19 +0200
|
||||
Subject: [PATCH] brcmfmac: fix setting AP channel with new firmwares
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Firmware for new chipsets is based on a new major version of code
|
||||
internally maintained at Broadcom. E.g. brcmfmac4366b-pcie.bin (used for
|
||||
BCM4366B1) is based on 10.10.69.3309 while brcmfmac43602-pcie.ap.bin was
|
||||
based on 7.35.177.56.
|
||||
|
||||
Currently setting AP 5 GHz channel doesn't work reliably with BCM4366B1.
|
||||
When setting e.g. 36 control channel with VHT80 (center channel 42)
|
||||
firmware may randomly pick one of:
|
||||
1) 52 control channel with 58 as center one
|
||||
2) 100 control channel with 106 as center one
|
||||
3) 116 control channel with 122 as center one
|
||||
4) 149 control channel with 155 as center one
|
||||
|
||||
It seems new firmwares require setting AP mode (BRCMF_C_SET_AP) before
|
||||
specifying a channel. Changing an order of firmware calls fixes the
|
||||
problem. This requirement resulted in two separated "chanspec" calls,
|
||||
one in AP code path and one in P2P path.
|
||||
|
||||
This fix was verified with BCM4366B1 and tested for regressions on
|
||||
BCM43602.
|
||||
|
||||
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
|
||||
@@ -4304,7 +4304,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
struct brcmf_join_params join_params;
|
||||
enum nl80211_iftype dev_role;
|
||||
struct brcmf_fil_bss_enable_le bss_enable;
|
||||
- u16 chanspec;
|
||||
+ u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
|
||||
bool mbss;
|
||||
int is_11d;
|
||||
|
||||
@@ -4380,16 +4380,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
|
||||
brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
|
||||
|
||||
+ /* Parameters shared by all radio interfaces */
|
||||
if (!mbss) {
|
||||
- chanspec = chandef_to_chanspec(&cfg->d11inf,
|
||||
- &settings->chandef);
|
||||
- err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
|
||||
- if (err < 0) {
|
||||
- brcmf_err("Set Channel failed: chspec=%d, %d\n",
|
||||
- chanspec, err);
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
if (is_11d != ifp->vif->is_11d) {
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
|
||||
is_11d);
|
||||
@@ -4437,6 +4429,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
+
|
||||
+ /* Interface specific setup */
|
||||
if (dev_role == NL80211_IFTYPE_AP) {
|
||||
if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
|
||||
brcmf_fil_iovar_int_set(ifp, "mbss", 1);
|
||||
@@ -4446,6 +4440,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
brcmf_err("setting AP mode failed %d\n", err);
|
||||
goto exit;
|
||||
}
|
||||
+ if (!mbss) {
|
||||
+ /* Firmware 10.x requires setting channel after enabling
|
||||
+ * AP and before bringing interface up.
|
||||
+ */
|
||||
+ err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
|
||||
+ if (err < 0) {
|
||||
+ brcmf_err("Set Channel failed: chspec=%d, %d\n",
|
||||
+ chanspec, err);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ }
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
|
||||
if (err < 0) {
|
||||
brcmf_err("BRCMF_C_UP error (%d)\n", err);
|
||||
@@ -4467,7 +4472,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
goto exit;
|
||||
}
|
||||
brcmf_dbg(TRACE, "AP mode configuration complete\n");
|
||||
- } else {
|
||||
+ } else if (dev_role == NL80211_IFTYPE_P2P_GO) {
|
||||
+ err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
|
||||
+ if (err < 0) {
|
||||
+ brcmf_err("Set Channel failed: chspec=%d, %d\n",
|
||||
+ chanspec, err);
|
||||
+ goto exit;
|
||||
+ }
|
||||
err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
|
||||
sizeof(ssid_le));
|
||||
if (err < 0) {
|
||||
@@ -4484,7 +4495,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
}
|
||||
|
||||
brcmf_dbg(TRACE, "GO mode configuration complete\n");
|
||||
+ } else {
|
||||
+ WARN_ON(1);
|
||||
}
|
||||
+
|
||||
set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||
brcmf_net_setcarrier(ifp, true);
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Mon, 30 May 2016 06:40:54 +0200
|
||||
Subject: [PATCH] brcmfmac: don't remove interface on link down firmware event
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There are two firmware events we handle similarly in brcmfmac:
|
||||
BRCMF_E_LINK and BRCMF_E_IF. The difference from firmware point of view
|
||||
is that the first one means BSS remains present in the firmware. Trying
|
||||
to (re)create it (e.g. when adding new virtual interface) will result in
|
||||
an error.
|
||||
|
||||
Current code treats both events in a similar way. It removes Linux
|
||||
interface for each of them. It works OK with e.g. BCM43602. Its firmware
|
||||
generates both events for each interface. It means we get BRCMF_E_LINK
|
||||
and remove interface. That is soon followed by BRCMF_E_IF which means
|
||||
BSS was also removed in a firmware. The only downside of this is a
|
||||
harmless error like:
|
||||
[ 208.643180] brcmfmac: brcmf_fweh_call_event_handler: no interface object
|
||||
|
||||
Unfortunately BCM4366 firmware doesn't automatically remove BSS and so
|
||||
it doesn't generate BRCMF_E_IF. In such case we incorrectly remove Linux
|
||||
interface on BRCMF_E_LINK as BSS is still present in the firmware. It
|
||||
results in an error when trying to re-create virtual interface, e.g.:
|
||||
> iw phy phy1 interface add wlan1-1 type __ap
|
||||
[ 3602.929199] brcmfmac: brcmf_ap_add_vif: timeout occurred
|
||||
command failed: I/O error (-5)
|
||||
|
||||
With this patch we don't remove Linux interface while firmware keeps
|
||||
BSS. Thanks to this we keep a consistent states of host driver and
|
||||
device firmware.
|
||||
|
||||
Further improvement should be to mark BSS as disabled and remove
|
||||
interface on BRCMF_E_LINK. Then we should add support for reusing
|
||||
BSS-es.
|
||||
|
||||
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
|
||||
@@ -5269,7 +5269,6 @@ brcmf_notify_connect_status_ap(struct br
|
||||
struct net_device *ndev,
|
||||
const struct brcmf_event_msg *e, void *data)
|
||||
{
|
||||
- struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
static int generation;
|
||||
u32 event = e->event_code;
|
||||
u32 reason = e->reason;
|
||||
@@ -5280,8 +5279,6 @@ brcmf_notify_connect_status_ap(struct br
|
||||
ndev != cfg_to_ndev(cfg)) {
|
||||
brcmf_dbg(CONN, "AP mode link down\n");
|
||||
complete(&cfg->vif_disabled);
|
||||
- if (ifp->vif->mbss)
|
||||
- brcmf_remove_interface(ifp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user