From 5a3c1fb9c26d0462417177fbf8cc921bad3a221f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 17 Jun 2016 06:23:22 +0000 Subject: [PATCH] mac80211: brcmfmac: fix support for BCM4366 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 SVN-Revision: 49383 --- ...t-errors-if-creating-interface-fails.patch | 59 +++++++++ ...etting-AP-channel-with-new-firmwares.patch | 114 ++++++++++++++++++ ...emove-interface-on-link-down-firmwar.patch | 60 +++++++++ ...63-brcmfmac-Disable-power-management.patch | 2 +- 4 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch create mode 100644 package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch create mode 100644 package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch diff --git a/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch b/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch new file mode 100644 index 0000000000..1b119b2c85 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch @@ -0,0 +1,59 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +[arend@broadcom.com: reduce error prints upon iface creation] +Signed-off-by: Arend van Spriel +Reviewed-by: Julian Calaby +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -670,20 +670,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 +@@ -2030,8 +2030,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; + } diff --git a/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch b/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch new file mode 100644 index 0000000000..970b48f977 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch @@ -0,0 +1,114 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -4398,7 +4398,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; + +@@ -4474,16 +4474,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); +@@ -4531,6 +4523,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); +@@ -4540,6 +4534,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); +@@ -4561,7 +4566,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) { +@@ -4578,7 +4589,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); + diff --git a/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch b/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch new file mode 100644 index 0000000000..c9a5541d82 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch @@ -0,0 +1,60 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5388,7 +5388,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; +@@ -5399,8 +5398,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; + } + diff --git a/package/kernel/mac80211/patches/863-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/863-brcmfmac-Disable-power-management.patch index 53840fe3f3..5bc1a2e6ed 100644 --- a/package/kernel/mac80211/patches/863-brcmfmac-Disable-power-management.patch +++ b/package/kernel/mac80211/patches/863-brcmfmac-Disable-power-management.patch @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -2682,6 +2682,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip +@@ -2686,6 +2686,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip * preference in cfg struct to apply this to * FW later while initializing the dongle */ -- 2.30.2