Add cypress patches, patching work but many patch adjustements are needed

This commit is contained in:
Igor
2023-05-20 09:49:23 +02:00
parent f1836416d2
commit 4b8efb0857
181 changed files with 22826 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
From 520405c6e198c757510573cad2965d982eb34de6 Mon Sep 17 00:00:00 2001
From: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Date: Tue, 15 Aug 2017 00:25:14 -0500
Subject: [PATCH 001/179] non-upstream: add sg parameters dts parsing
broken_sg_support, sd_head_align, and sd_sgentry_align are used in
brcmfmac code but not configurable in dts file. Add the parsing logic.
Now they can be configured like below in dts:
brcm,broken_sg_support;
brcm,sd_head_align = /bits/ 16 <4>;
brcm,sd_sgentry_align = /bits/ 16 <4>;
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/of.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
index 2f7bc3a70c65..7c80958e709b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -66,7 +66,8 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
int irq;
int err;
u32 irqf;
- u32 val;
+ u32 val32;
+ u16 val16;
/* Set board-type to the first string of the machine compatible prop */
root = of_find_node_by_path("/");
@@ -100,8 +101,15 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
if (bus_type != BRCMF_BUSTYPE_SDIO)
return;
- if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
- sdio->drive_strength = val;
+ if (of_property_read_u32(np, "brcm,drive-strength", &val32) == 0)
+ sdio->drive_strength = val32;
+
+ sdio->broken_sg_support = of_property_read_bool(np,
+ "brcm,broken_sg_support");
+ if (of_property_read_u16(np, "brcm,sd_head_align", &val16) == 0)
+ sdio->sd_head_align = val16;
+ if (of_property_read_u16(np, "brcm,sd_sgentry_align", &val16) == 0)
+ sdio->sd_sgentry_align = val16;
/* make sure there are interrupts defined in the node */
if (!of_find_property(np, "interrupts", NULL))
--
2.17.1

View File

@@ -0,0 +1,58 @@
From b29a8e3605a59e239a160580e0478cef9117b05d Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Wed, 31 Jan 2018 04:07:12 -0600
Subject: [PATCH 002/179] brcmfmac: support AP isolation
Hostap daemon has a parameter "ap_isolate which is used to prevent
low-level bridging of frames between associated stations in the BSS.
For driver side, we add cfg80211 ops method change_bss to support
setting AP isolation from user space.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 9db12ffd2ff8..c264ea1fb527 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5525,6 +5525,26 @@ static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,
return brcmf_set_pmk(ifp, NULL, 0);
}
+static int
+brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,
+ struct bss_parameters *params)
+{
+ struct brcmf_if *ifp;
+ int ret = 0;
+ u32 ap_isolate;
+
+ brcmf_dbg(TRACE, "Enter\n");
+ ifp = netdev_priv(dev);
+ if (params->ap_isolate >= 0) {
+ ap_isolate = (u32)params->ap_isolate;
+ ret = brcmf_fil_iovar_int_set(ifp, "ap_isolate", ap_isolate);
+ if (ret < 0)
+ brcmf_err("ap_isolate iovar failed: ret=%d\n", ret);
+ }
+
+ return ret;
+}
+
static struct cfg80211_ops brcmf_cfg80211_ops = {
.add_virtual_intf = brcmf_cfg80211_add_iface,
.del_virtual_intf = brcmf_cfg80211_del_iface,
@@ -5572,6 +5592,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
.update_connect_params = brcmf_cfg80211_update_conn_params,
.set_pmk = brcmf_cfg80211_set_pmk,
.del_pmk = brcmf_cfg80211_del_pmk,
+ .change_bss = brcmf_cfg80211_change_bss,
};
struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
--
2.17.1

View File

@@ -0,0 +1,93 @@
From 0c9dac2b21c1b225cbc625534617a27cf6f6a25a Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Fri, 2 Mar 2018 00:45:32 -0600
Subject: [PATCH 003/179] non-upstream: make firmware eap_restrict a module
parameter
When eap_restrict is enabled, firmware will toss non-802.1x frames from
tx/rx data path if station not yet authorized.
Internal firmware eap_restrict is disabled by default. This patch makes
it possible to enable firmware eap_restrict by specifying
eap_restrict=1 as module parameter.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 9 +++++++++
.../net/wireless/broadcom/brcm80211/brcmfmac/common.c | 5 +++++
.../net/wireless/broadcom/brcm80211/brcmfmac/common.h | 2 ++
3 files changed, 16 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index c264ea1fb527..bd5f822dea15 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -7313,6 +7313,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
struct wireless_dev *wdev;
struct brcmf_if *ifp;
s32 power_mode;
+ s32 eap_restrict;
s32 err = 0;
if (cfg->dongle_up)
@@ -7337,6 +7338,14 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
err = brcmf_dongle_roam(ifp);
if (err)
goto default_conf_out;
+
+ eap_restrict = ifp->drvr->settings->eap_restrict;
+ if (eap_restrict) {
+ err = brcmf_fil_iovar_int_set(ifp, "eap_restrict",
+ eap_restrict);
+ if (err)
+ brcmf_info("eap_restrict error (%d)\n", err);
+ }
err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
NULL);
if (err)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index e3758bd86acf..a123e4f8eb0b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -67,6 +67,10 @@ static int brcmf_iapp_enable;
module_param_named(iapp, brcmf_iapp_enable, int, 0);
MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol");
+static int brcmf_eap_restrict;
+module_param_named(eap_restrict, brcmf_eap_restrict, int, 0400);
+MODULE_PARM_DESC(eap_restrict, "Block non-802.1X frames until auth finished");
+
#ifdef DEBUG
/* always succeed brcmf_bus_started() */
static int brcmf_ignore_probe_fail;
@@ -413,6 +417,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
settings->fcmode = brcmf_fcmode;
settings->roamoff = !!brcmf_roamoff;
settings->iapp = !!brcmf_iapp_enable;
+ settings->eap_restrict = !!brcmf_eap_restrict;
#ifdef DEBUG
settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
#endif
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index 8b5f49997c8b..d060d66f0868 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -37,6 +37,7 @@ extern struct brcmf_mp_global_t brcmf_mp_global;
* @feature_disable: Feature_disable bitmask.
* @fcmode: FWS flow control.
* @roamoff: Firmware roaming off?
+ * @eap_restrict: Not allow data tx/rx until 802.1X auth succeeds
* @ignore_probe_fail: Ignore probe failure.
* @country_codes: If available, pointer to struct for translating country codes
* @bus: Bus specific platform data. Only SDIO at the mmoment.
@@ -47,6 +48,7 @@ struct brcmf_mp_device {
int fcmode;
bool roamoff;
bool iapp;
+ bool eap_restrict;
bool ignore_probe_fail;
struct brcmfmac_pd_cc *country_codes;
const char *board_type;
--
2.17.1

View File

@@ -0,0 +1,431 @@
From a3440f3441e9e60e289f87525ecf7d3e61044ebf Mon Sep 17 00:00:00 2001
From: Double Lo <dblo@cypress.com>
Date: Tue, 6 Feb 2018 05:07:05 -0600
Subject: [PATCH 004/179] non-upstream: support wake on ping packet
Host driver needs to provide a dummy wowlan filter for kernel and
provided the the well configured wowlan stack. So the system will
keep driver in connected state in suspend mode and can be wake
up by ping packet.
Enable unicast packet filter before system suspend and disable it after
resume.
Signed-off-by: Double Lo <dblo@cypress.com>
Signed-off-by: Double Lo <double.lo@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 31 ++-
.../broadcom/brcm80211/brcmfmac/cfg80211.h | 7 +
.../broadcom/brcm80211/brcmfmac/common.c | 18 +-
.../broadcom/brcm80211/brcmfmac/core.c | 176 ++++++++++++++++++
.../broadcom/brcm80211/brcmfmac/core.h | 7 +-
.../broadcom/brcm80211/brcmfmac/feature.c | 1 -
.../broadcom/brcm80211/brcmfmac/fwil.h | 2 +
.../broadcom/brcm80211/brcmfmac/fwil_types.h | 13 ++
8 files changed, 249 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index bd5f822dea15..a59f606768a9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3841,6 +3841,10 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
brcmf_notify_sched_scan_results);
cfg->wowl.nd_enabled = false;
}
+
+ /* disable packet filters */
+ brcmf_pktfilter_enable(ifp->ndev, false);
+
}
return 0;
}
@@ -3899,6 +3903,9 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
brcmf_bus_wowl_config(cfg->pub->bus_if, true);
cfg->wowl.active = true;
+
+ /* enable packet filters */
+ brcmf_pktfilter_enable(ifp->ndev, true);
}
static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
@@ -3945,7 +3952,7 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
brcmf_set_mpc(ifp, 1);
} else {
- /* Configure WOWL paramaters */
+ /* Configure WOWL parameters */
brcmf_configure_wowl(cfg, ifp, wowl);
}
@@ -7141,6 +7148,7 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_pub *drvr = cfg->pub;
struct wiphy_wowlan_support *wowl;
+ struct cfg80211_wowlan *brcmf_wowlan_config = NULL;
wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
GFP_KERNEL);
@@ -7163,6 +7171,27 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
}
wiphy->wowlan = wowl;
+
+ /* wowlan_config structure report for kernels */
+ brcmf_wowlan_config = kzalloc(sizeof(*brcmf_wowlan_config),
+ GFP_KERNEL);
+ if (brcmf_wowlan_config) {
+ brcmf_wowlan_config->any = false;
+ brcmf_wowlan_config->disconnect = true;
+ brcmf_wowlan_config->eap_identity_req = true;
+ brcmf_wowlan_config->four_way_handshake = true;
+ brcmf_wowlan_config->rfkill_release = false;
+ brcmf_wowlan_config->patterns = NULL;
+ brcmf_wowlan_config->n_patterns = 0;
+ brcmf_wowlan_config->tcp = NULL;
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
+ brcmf_wowlan_config->gtk_rekey_failure = true;
+ else
+ brcmf_wowlan_config->gtk_rekey_failure = false;
+ } else {
+ brcmf_err("Can not allocate memory for brcm_wowlan_config\n");
+ }
+ wiphy->wowlan_config = brcmf_wowlan_config;
#endif
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index e90a30808c22..2bdefdaeca12 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -92,6 +92,13 @@
#define BRCMF_VIF_EVENT_TIMEOUT msecs_to_jiffies(1500)
+/* cfg80211 wowlan definitions */
+#define WL_WOWLAN_MAX_PATTERNS 8
+#define WL_WOWLAN_MIN_PATTERN_LEN 1
+#define WL_WOWLAN_MAX_PATTERN_LEN 255
+#define WL_WOWLAN_PKT_FILTER_ID_FIRST 201
+#define WL_WOWLAN_PKT_FILTER_ID_LAST (WL_WOWLAN_PKT_FILTER_ID_FIRST + \
+ WL_WOWLAN_MAX_PATTERNS - 1)
/**
* enum brcmf_scan_status - scan engine status
*
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index a123e4f8eb0b..489f7920f889 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -206,7 +206,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
char *ptr;
s32 err;
- /* retreive mac address */
+ /* retrieve mac addresses */
err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
sizeof(ifp->mac_addr));
if (err < 0) {
@@ -340,6 +340,18 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
/* Enable tx beamforming, errors can be ignored (not supported) */
(void)brcmf_fil_iovar_int_set(ifp, "txbf", 1);
+
+ /* add unicast packet filter */
+ err = brcmf_pktfilter_add_remove(ifp->ndev,
+ BRCMF_UNICAST_FILTER_NUM, true);
+ if (err == -BRCMF_FW_UNSUPPORTED) {
+ /* FW not support can be ignored */
+ err = 0;
+ goto done;
+ } else if (err) {
+ bphy_err(drvr, "Add unicast filter error (%d)\n", err);
+ }
+
done:
return err;
}
@@ -411,7 +423,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
if (!settings)
return NULL;
- /* start by using the module paramaters */
+ /* start by using the module parameters */
settings->p2p_enable = !!brcmf_p2p_enable;
settings->feature_disable = brcmf_feature_disable;
settings->fcmode = brcmf_fcmode;
@@ -497,7 +509,7 @@ static int __init brcmfmac_module_init(void)
if (err == -ENODEV)
brcmf_dbg(INFO, "No platform data available.\n");
- /* Initialize global module paramaters */
+ /* Initialize global module parameters */
brcmf_mp_attach();
/* Continue the initialization by registering the different busses */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index db5f8535fdb5..f4a7e23e5667 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1554,3 +1554,179 @@ void __exit brcmf_core_exit(void)
brcmf_pcie_exit();
}
+int
+brcmf_pktfilter_add_remove(struct net_device *ndev, int filter_num, bool add)
+{
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_pkt_filter_le *pkt_filter;
+ int filter_fixed_len = offsetof(struct brcmf_pkt_filter_le, u);
+ int pattern_fixed_len = offsetof(struct brcmf_pkt_filter_pattern_le,
+ mask_and_pattern);
+ u16 mask_and_pattern[MAX_PKTFILTER_PATTERN_SIZE];
+ int buflen = 0;
+ int ret = 0;
+
+ brcmf_dbg(INFO, "%s packet filter number %d\n",
+ (add ? "add" : "remove"), filter_num);
+
+ pkt_filter = kzalloc(sizeof(*pkt_filter) +
+ (MAX_PKTFILTER_PATTERN_SIZE * 2), GFP_ATOMIC);
+ if (!pkt_filter)
+ return -ENOMEM;
+
+ switch (filter_num) {
+ case BRCMF_UNICAST_FILTER_NUM:
+ pkt_filter->id = 100;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 1;
+ mask_and_pattern[0] = 0x0001;
+ break;
+ case BRCMF_BROADCAST_FILTER_NUM:
+ //filter_pattern = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
+ pkt_filter->id = 101;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 6;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0xFFFF;
+ mask_and_pattern[2] = 0xFFFF;
+ mask_and_pattern[3] = 0xFFFF;
+ mask_and_pattern[4] = 0xFFFF;
+ mask_and_pattern[5] = 0xFFFF;
+ break;
+ case BRCMF_MULTICAST4_FILTER_NUM:
+ //filter_pattern = "102 0 0 0 0xFFFFFF 0x01005E";
+ pkt_filter->id = 102;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 3;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0x01FF;
+ mask_and_pattern[2] = 0x5E00;
+ break;
+ case BRCMF_MULTICAST6_FILTER_NUM:
+ //filter_pattern = "103 0 0 0 0xFFFF 0x3333";
+ pkt_filter->id = 103;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 2;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0x3333;
+ break;
+ case BRCMF_MDNS_FILTER_NUM:
+ //filter_pattern = "104 0 0 0 0xFFFFFFFFFFFF 0x01005E0000FB";
+ pkt_filter->id = 104;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 6;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0xFFFF;
+ mask_and_pattern[2] = 0xFFFF;
+ mask_and_pattern[3] = 0x0001;
+ mask_and_pattern[4] = 0x005E;
+ mask_and_pattern[5] = 0xFB00;
+ break;
+ case BRCMF_ARP_FILTER_NUM:
+ //filter_pattern = "105 0 0 12 0xFFFF 0x0806";
+ pkt_filter->id = 105;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 12;
+ pkt_filter->u.pattern.size_bytes = 2;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0x0608;
+ break;
+ case BRCMF_BROADCAST_ARP_FILTER_NUM:
+ //filter_pattern = "106 0 0 0
+ //0xFFFFFFFFFFFF0000000000000806
+ //0xFFFFFFFFFFFF0000000000000806";
+ pkt_filter->id = 106;
+ pkt_filter->type = 0;
+ pkt_filter->negate_match = 0;
+ pkt_filter->u.pattern.offset = 0;
+ pkt_filter->u.pattern.size_bytes = 14;
+ mask_and_pattern[0] = 0xFFFF;
+ mask_and_pattern[1] = 0xFFFF;
+ mask_and_pattern[2] = 0xFFFF;
+ mask_and_pattern[3] = 0x0000;
+ mask_and_pattern[4] = 0x0000;
+ mask_and_pattern[5] = 0x0000;
+ mask_and_pattern[6] = 0x0608;
+ mask_and_pattern[7] = 0xFFFF;
+ mask_and_pattern[8] = 0xFFFF;
+ mask_and_pattern[9] = 0xFFFF;
+ mask_and_pattern[10] = 0x0000;
+ mask_and_pattern[11] = 0x0000;
+ mask_and_pattern[12] = 0x0000;
+ mask_and_pattern[13] = 0x0608;
+ break;
+ default:
+ ret = -EINVAL;
+ goto failed;
+ }
+ memcpy(pkt_filter->u.pattern.mask_and_pattern, mask_and_pattern,
+ pkt_filter->u.pattern.size_bytes * 2);
+ buflen = filter_fixed_len + pattern_fixed_len +
+ pkt_filter->u.pattern.size_bytes * 2;
+
+ if (add) {
+ /* Add filter */
+ ifp->fwil_fwerr = true;
+ ret = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add",
+ pkt_filter, buflen);
+ ifp->fwil_fwerr = false;
+ if (ret)
+ goto failed;
+ drvr->pkt_filter[filter_num].id = pkt_filter->id;
+ drvr->pkt_filter[filter_num].enable = 0;
+
+ } else {
+ /* Delete filter */
+ ret = brcmf_fil_iovar_int_set(ifp, "pkt_filter_delete",
+ pkt_filter->id);
+ if (ret == -ENOENT)
+ ret = 0;
+ if (ret)
+ goto failed;
+
+ drvr->pkt_filter[filter_num].id = 0;
+ drvr->pkt_filter[filter_num].enable = 0;
+ }
+failed:
+ if (ret)
+ brcmf_err("%s packet filter failed, ret=%d\n",
+ (add ? "add" : "remove"), ret);
+
+ kfree(pkt_filter);
+ return ret;
+}
+
+int brcmf_pktfilter_enable(struct net_device *ndev, bool enable)
+{
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
+ int ret = 0;
+ int idx = 0;
+
+ for (idx = 0; idx < MAX_PKT_FILTER_COUNT; ++idx) {
+ if (drvr->pkt_filter[idx].id != 0) {
+ drvr->pkt_filter[idx].enable = enable;
+ ret = brcmf_fil_iovar_data_set(ifp, "pkt_filter_enable",
+ &drvr->pkt_filter[idx],
+ sizeof(struct brcmf_pkt_filter_enable_le));
+ if (ret) {
+ brcmf_err("%s packet filter id(%d) failed, ret=%d\n",
+ (enable ? "enable" : "disable"),
+ drvr->pkt_filter[idx].id, ret);
+ }
+ }
+ }
+ return ret;
+}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index 8212c9de14f1..bf4b877acf48 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -12,6 +12,7 @@
#include <net/cfg80211.h>
#include "fweh.h"
+#include "fwil_types.h"
#define TOE_TX_CSUM_OL 0x00000001
#define TOE_RX_CSUM_OL 0x00000002
@@ -136,6 +137,8 @@ struct brcmf_pub {
struct work_struct bus_reset;
u8 clmver[BRCMF_DCMD_SMLEN];
+ struct brcmf_pkt_filter_enable_le pkt_filter[MAX_PKT_FILTER_COUNT];
+
};
/* forward declarations */
@@ -215,5 +218,7 @@ int brcmf_net_mon_attach(struct brcmf_if *ifp);
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
int __init brcmf_core_init(void);
void __exit brcmf_core_exit(void);
-
+int brcmf_pktfilter_add_remove(struct net_device *ndev, int filter_num,
+ bool add);
+int brcmf_pktfilter_enable(struct net_device *ndev, bool enable);
#endif /* BRCMFMAC_CORE_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 7c68d9849324..2733977b07a8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -16,7 +16,6 @@
#include "feature.h"
#include "common.h"
-#define BRCMF_FW_UNSUPPORTED 23
/*
* expand feature list to array of feature strings.
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
index cb26f8c59c21..caf18d3b4cca 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
@@ -79,6 +79,8 @@
#define BRCMF_C_SET_VAR 263
#define BRCMF_C_SET_WSEC_PMK 268
+#define BRCMF_FW_UNSUPPORTED 23
+
s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index ff2ef557f0ea..ba7ac24121d4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -138,6 +138,19 @@
#define BRCMF_WOWL_MAXPATTERNS 8
#define BRCMF_WOWL_MAXPATTERNSIZE 128
+enum {
+ BRCMF_UNICAST_FILTER_NUM = 0,
+ BRCMF_BROADCAST_FILTER_NUM,
+ BRCMF_MULTICAST4_FILTER_NUM,
+ BRCMF_MULTICAST6_FILTER_NUM,
+ BRCMF_MDNS_FILTER_NUM,
+ BRCMF_ARP_FILTER_NUM,
+ BRCMF_BROADCAST_ARP_FILTER_NUM,
+ MAX_PKT_FILTER_COUNT
+};
+
+#define MAX_PKTFILTER_PATTERN_SIZE 16
+
#define BRCMF_COUNTRY_BUF_SZ 4
#define BRCMF_ANT_MAX 4
--
2.17.1

View File

@@ -0,0 +1,32 @@
From db294a675780b6ff7d27e3e9b836fc0c05012e83 Mon Sep 17 00:00:00 2001
From: Double Lo <dblo@cypress.com>
Date: Tue, 13 Mar 2018 03:22:20 -0500
Subject: [PATCH 005/179] non-upstream: remove WOWL configuration in disconnect
state
Set wowl configuration in disconnect state is redundant.
Remove it to fix no scan result issue after resume.
Signed-off-by: Double Lo <dblo@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index a59f606768a9..d306c551780f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3932,7 +3932,8 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
brcmf_abort_scanning(cfg);
- if (wowl == NULL) {
+ if (!wowl || !test_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state)) {
brcmf_bus_wowl_config(cfg->pub->bus_if, false);
list_for_each_entry(vif, &cfg->vif_list, list) {
if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
--
2.17.1

View File

@@ -0,0 +1,105 @@
From 120f714bc5e261a6e7da2a319321f7ff08fcfae2 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Sun, 25 Mar 2018 21:53:42 -0500
Subject: [PATCH 006/179] non-upstream: make setting SDIO workqueue WQ_HIGHPRI
a module parameter
With setting sdio_wq_highpri=1 in module parameters, tasks submitted to
SDIO workqueue will put at the head of the queue and run immediately.
This parameter is for getting higher TX/RX throughput with SDIO bus.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/common.c | 5 +++++
.../broadcom/brcm80211/brcmfmac/common.h | 2 ++
.../broadcom/brcm80211/brcmfmac/sdio.c | 22 ++++++++++++-------
3 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 489f7920f889..1224a7773681 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -71,6 +71,10 @@ static int brcmf_eap_restrict;
module_param_named(eap_restrict, brcmf_eap_restrict, int, 0400);
MODULE_PARM_DESC(eap_restrict, "Block non-802.1X frames until auth finished");
+static int brcmf_sdio_wq_highpri;
+module_param_named(sdio_wq_highpri, brcmf_sdio_wq_highpri, int, 0);
+MODULE_PARM_DESC(sdio_wq_highpri, "SDIO workqueue is set to high priority");
+
#ifdef DEBUG
/* always succeed brcmf_bus_started() */
static int brcmf_ignore_probe_fail;
@@ -430,6 +434,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
settings->roamoff = !!brcmf_roamoff;
settings->iapp = !!brcmf_iapp_enable;
settings->eap_restrict = !!brcmf_eap_restrict;
+ settings->sdio_wq_highpri = !!brcmf_sdio_wq_highpri;
#ifdef DEBUG
settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
#endif
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index d060d66f0868..34991a853c06 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -38,6 +38,7 @@ extern struct brcmf_mp_global_t brcmf_mp_global;
* @fcmode: FWS flow control.
* @roamoff: Firmware roaming off?
* @eap_restrict: Not allow data tx/rx until 802.1X auth succeeds
+ * @sdio_wq_highpri: Tasks submitted to SDIO workqueue will run immediately.
* @ignore_probe_fail: Ignore probe failure.
* @country_codes: If available, pointer to struct for translating country codes
* @bus: Bus specific platform data. Only SDIO at the mmoment.
@@ -49,6 +50,7 @@ struct brcmf_mp_device {
bool roamoff;
bool iapp;
bool eap_restrict;
+ bool sdio_wq_highpri;
bool ignore_probe_fail;
struct brcmfmac_pd_cc *country_codes;
const char *board_type;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index f7961b22e051..786d6ab4ac53 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4453,9 +4453,21 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
bus->txminmax = BRCMF_TXMINMAX;
bus->tx_seq = SDPCM_SEQ_WRAP - 1;
+ /* attempt to attach to the dongle */
+ if (!(brcmf_sdio_probe_attach(bus))) {
+ brcmf_err("brcmf_sdio_probe_attach failed\n");
+ goto fail;
+ }
+
/* single-threaded workqueue */
- wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM | WQ_HIGHPRI,
- dev_name(&sdiodev->func1->dev));
+ if (sdiodev->settings->sdio_wq_highpri) {
+ wq = alloc_workqueue("brcmf_wq/%s",
+ WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND,
+ 1, dev_name(&sdiodev->func1->dev));
+ } else {
+ wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
+ dev_name(&sdiodev->func1->dev));
+ }
if (!wq) {
brcmf_err("insufficient memory to create txworkqueue\n");
goto fail;
@@ -4464,12 +4476,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
bus->brcmf_wq = wq;
- /* attempt to attach to the dongle */
- if (!(brcmf_sdio_probe_attach(bus))) {
- brcmf_err("brcmf_sdio_probe_attach failed\n");
- goto fail;
- }
-
spin_lock_init(&bus->rxctl_lock);
spin_lock_init(&bus->txq_lock);
init_waitqueue_head(&bus->ctrl_wait);
--
2.17.1

View File

@@ -0,0 +1,30 @@
linux-3.8 kernel, wowlan packet filter is mandated to avoid
the disconnection of connected network before suspend in commit
812569699119 ("cfg80211/mac80211: disconnect on suspend").
So as a dummy wowlan filter is configured for kernels linux-3.8
and above. Later all private command implementation of packet
filters can be moved to wowlan based filters.
Signed-off-by: Double Lo <dblo@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index d306c551780f..32bbf45fae72 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -7277,8 +7277,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
wiphy->vendor_commands = brcmf_vendor_cmds;
wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
- brcmf_wiphy_wowl_params(wiphy, ifp);
+ brcmf_wiphy_wowl_params(wiphy, ifp);
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
sizeof(bandlist));
if (err) {
--
2.17.1

View File

@@ -0,0 +1,34 @@
From 671bc68ac0d6d1e97bb0838746632e0ecefa2205 Mon Sep 17 00:00:00 2001
From: Raveendran Somu <raveendran.somu@cypress.com>
Date: Tue, 11 Sep 2018 19:06:06 -0500
Subject: [PATCH 008/179] non-upstream: Changes to improve USB Tx throughput
The inbound buffer been duplicated and returned to
the upper layer to increase the througput.
Below the improvement observed in different traffic
UDP Rx UDP Tx TCP Rx TCP Tx
237 138 161 71 Without Tx improvement
238 155 162 137 With Tx improvement
Signed-off-by: Raveendran Somu <raveendran.somu@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 9fb68c2dc7e3..2e2280e76e70 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -638,6 +638,7 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
goto fail;
}
+ skb_orphan(skb);
req->skb = skb;
req->devinfo = devinfo;
usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
--
2.17.1

View File

@@ -0,0 +1,93 @@
From 03f45fcc1fb766a2193415a203695802eb3c8796 Mon Sep 17 00:00:00 2001
From: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Date: Mon, 17 Sep 2018 04:51:08 -0500
Subject: [PATCH 009/179] brcmfmac: introduce module parameter to configure
default PM mode
Add module parameter max_pm to allow using PM_MAX as default power
management mode. Default PM mode is set to PM_MAX when max_pm=1, and is
set to PM_FAST when max_pm=0 or max_pm is not set.
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++--
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 6 ++++++
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h | 2 ++
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 32bbf45fae72..3b876b9a549c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2947,7 +2947,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
goto done;
}
- pm = enabled ? PM_FAST : PM_OFF;
+ pm = enabled ? ifp->drvr->settings->default_pm : PM_OFF;
/* Do not enable the power save after assoc if it is a p2p interface */
if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
@@ -7357,7 +7357,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
brcmf_dongle_scantime(ifp);
- power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
+ power_mode = cfg->pwr_save ? ifp->drvr->settings->default_pm : PM_OFF;
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
if (err)
goto default_conf_out;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 1224a7773681..ae16781dd527 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -20,6 +20,7 @@
#include "of.h"
#include "firmware.h"
#include "chip.h"
+#include "defs.h"
MODULE_AUTHOR("Broadcom Corporation");
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -75,6 +76,10 @@ static int brcmf_sdio_wq_highpri;
module_param_named(sdio_wq_highpri, brcmf_sdio_wq_highpri, int, 0);
MODULE_PARM_DESC(sdio_wq_highpri, "SDIO workqueue is set to high priority");
+static int brcmf_max_pm;
+module_param_named(max_pm, brcmf_max_pm, int, 0);
+MODULE_PARM_DESC(max_pm, "Use max power management mode by default");
+
#ifdef DEBUG
/* always succeed brcmf_bus_started() */
static int brcmf_ignore_probe_fail;
@@ -435,6 +440,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
settings->iapp = !!brcmf_iapp_enable;
settings->eap_restrict = !!brcmf_eap_restrict;
settings->sdio_wq_highpri = !!brcmf_sdio_wq_highpri;
+ settings->default_pm = !!brcmf_max_pm ? PM_MAX : PM_FAST;
#ifdef DEBUG
settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
#endif
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index 34991a853c06..c0bf5867af5f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -39,6 +39,7 @@ extern struct brcmf_mp_global_t brcmf_mp_global;
* @roamoff: Firmware roaming off?
* @eap_restrict: Not allow data tx/rx until 802.1X auth succeeds
* @sdio_wq_highpri: Tasks submitted to SDIO workqueue will run immediately.
+ * @default_pm: default power management (PM) mode.
* @ignore_probe_fail: Ignore probe failure.
* @country_codes: If available, pointer to struct for translating country codes
* @bus: Bus specific platform data. Only SDIO at the mmoment.
@@ -51,6 +52,7 @@ struct brcmf_mp_device {
bool iapp;
bool eap_restrict;
bool sdio_wq_highpri;
+ int default_pm;
bool ignore_probe_fail;
struct brcmfmac_pd_cc *country_codes;
const char *board_type;
--
2.17.1

View File

@@ -0,0 +1,34 @@
From 12405072670b9c03cebe7f84ac9c88aac4cdbee1 Mon Sep 17 00:00:00 2001
From: Double Lo <dblo@cypress.com>
Date: Thu, 20 Sep 2018 01:44:01 -0500
Subject: [PATCH 010/179] non-upstream: configure wowl parameters in suspend
function only if firmware support wowl
This patch removes the redundant wowl configuration for none wowl
FW.
Signed-off-by: Double Lo <dblo@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 3b876b9a549c..5d249d5c9a9f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3953,8 +3953,9 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
brcmf_set_mpc(ifp, 1);
} else {
- /* Configure WOWL parameters */
- brcmf_configure_wowl(cfg, ifp, wowl);
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
+ /* Configure WOWL parameters */
+ brcmf_configure_wowl(cfg, ifp, wowl);
}
exit:
--
2.17.1

View File

@@ -0,0 +1,39 @@
From be124487a2a863febd90c34af548c349a849017f Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Mon, 17 Dec 2018 00:54:07 -0600
Subject: [PATCH 011/179] non-upstream: disable command decode in sdio_aos for
4356
AOS is a part of the SDIOD core that becomes active when the rest of
SDIOD is sleeping to keep SDIO bus alive responding to reduced set of
commands.
Transaction between AOS and SDIOD is not protected, and if cmd 52 is
received in AOS and in the middle of response state changed from AOS to
SDIOD, response is corrupted and it causes to SDIO Host controller to
hang.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 786d6ab4ac53..77cc05d9a33d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3423,7 +3423,9 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
{
if (bus->ci->chip == CY_CC_43012_CHIP_ID ||
- bus->ci->chip == CY_CC_43752_CHIP_ID)
+ bus->ci->chip == CY_CC_43752_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4354_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4356_CHIP_ID)
return true;
else
return false;
--
2.17.1

View File

@@ -0,0 +1,29 @@
From 51292423ac0230e75ed6fa2691b7dfed72f7e6a6 Mon Sep 17 00:00:00 2001
From: Ryohei Kondo <ryohei.kondo@cypress.com>
Date: Thu, 8 Nov 2018 10:37:29 +0900
Subject: [PATCH 012/179] brcmfmac: increase default max WOWL patterns to 16
4373 has support of 16 WOWL patterns thus increasing the default value
Signed-off-by: Ryohei Kondo <ryohei.kondo@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index ba7ac24121d4..0706e04b983e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -135,7 +135,7 @@
/* Link Down indication in WoWL mode: */
#define BRCMF_WOWL_LINKDOWN (1 << 31)
-#define BRCMF_WOWL_MAXPATTERNS 8
+#define BRCMF_WOWL_MAXPATTERNS 16
#define BRCMF_WOWL_MAXPATTERNSIZE 128
enum {
--
2.17.1

View File

@@ -0,0 +1,180 @@
From 806187583bf02d23b736b2440c71ab559a0264a4 Mon Sep 17 00:00:00 2001
From: Robert Trask <robert.trask@cypress.com>
Date: Thu, 20 Dec 2018 11:55:30 -0600
Subject: [PATCH 013/179] non-upstream: Enable, Process, and forward PHY_TEMP
event
New code enables PHY_TEMP event in firmware, receives it, processes
into cfg80211 vendor specific event, and forwards to waiting host.
-1- Enable rx PHY_TEMP event from underlying hardware
-2- Process PHY_TEMP event into vendor specific event
-3- Forward vendor specific event to host layer
Signed-off-by: Robert Trask <robert.trask@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 5 ++
.../broadcom/brcm80211/brcmfmac/fweh.h | 1 +
.../broadcom/brcm80211/brcmfmac/vendor.c | 57 +++++++++++++++++++
.../broadcom/brcm80211/brcmfmac/vendor.h | 19 +++++++
4 files changed, 82 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 5d249d5c9a9f..2ed7cf1c939d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -7200,6 +7200,7 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
{
struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
const struct ieee80211_iface_combination *combo;
struct ieee80211_supported_band *band;
u16 max_interfaces = 0;
@@ -7277,6 +7278,10 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
/* vendor commands/events support */
wiphy->vendor_commands = brcmf_vendor_cmds;
wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
+ wiphy->vendor_events = brcmf_vendor_events;
+ wiphy->n_vendor_events = BRCMF_VNDR_EVTS_LAST;
+ brcmf_fweh_register(cfg->pub, BRCMF_E_PHY_TEMP,
+ brcmf_wiphy_phy_temp_evt_handler);
brcmf_wiphy_wowl_params(wiphy, ifp);
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
index 48414e8b9389..f692933e2348 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
@@ -90,6 +90,7 @@ struct brcmf_cfg80211_info;
BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
+ BRCMF_ENUM_DEF(PHY_TEMP, 111) \
BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
#define BRCMF_ENUM_DEF(id, val) \
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
index d07e7c7355d9..4ed3287522cb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
@@ -104,6 +104,56 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
return ret;
}
+s32
+brcmf_wiphy_phy_temp_evt_handler(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *e, void *data)
+
+{
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct sk_buff *skb;
+ struct nlattr *phy_temp_data;
+ u32 version, temp, tempdelta;
+ struct brcmf_phy_temp_evt *phy_temp_evt;
+
+ phy_temp_evt = (struct brcmf_phy_temp_evt *)data;
+
+ version = le32_to_cpu(phy_temp_evt->version);
+ temp = le32_to_cpu(phy_temp_evt->temp);
+ tempdelta = le32_to_cpu(phy_temp_evt->tempdelta);
+
+ skb = cfg80211_vendor_event_alloc(wiphy, NULL,
+ sizeof(*phy_temp_evt),
+ BRCMF_VNDR_EVTS_PHY_TEMP,
+ GFP_KERNEL);
+
+ if (!skb) {
+ brcmf_dbg(EVENT, "NO MEM: can't allocate skb for vendor PHY_TEMP_EVENT\n");
+ return -ENOMEM;
+ }
+
+ phy_temp_data = nla_nest_start(skb, NL80211_ATTR_VENDOR_EVENTS);
+ if (!phy_temp_data) {
+ nla_nest_cancel(skb, phy_temp_data);
+ kfree_skb(skb);
+ brcmf_dbg(EVENT, "skb could not nest vendor attributes\n");
+ return -EMSGSIZE;
+ }
+
+ if (nla_put_u32(skb, BRCMF_NLATTR_VERS, version) ||
+ nla_put_u32(skb, BRCMF_NLATTR_PHY_TEMP, temp) ||
+ nla_put_u32(skb, BRCMF_NLATTR_PHY_TEMPDELTA, tempdelta)) {
+ kfree_skb(skb);
+ brcmf_dbg(EVENT, "NO ROOM in skb for vendor PHY_TEMP_EVENT\n");
+ return -EMSGSIZE;
+ }
+
+ nla_nest_end(skb, phy_temp_data);
+
+ cfg80211_vendor_event(skb, GFP_KERNEL);
+ return 0;
+}
+
const struct wiphy_vendor_command brcmf_vendor_cmds[] = {
{
{
@@ -116,3 +166,10 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = {
.doit = brcmf_cfg80211_vndr_cmds_dcmd_handler
},
};
+
+const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = {
+ {
+ .vendor_id = BROADCOM_OUI,
+ .subcmd = BRCMF_VNDR_EVTS_PHY_TEMP,
+ },
+};
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h
index 418f33ea6fd3..3bdf47369788 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h
@@ -14,6 +14,11 @@ enum brcmf_vndr_cmds {
BRCMF_VNDR_CMDS_LAST
};
+enum brcmf_vndr_evts {
+ BRCMF_VNDR_EVTS_PHY_TEMP,
+ BRCMF_VNDR_EVTS_LAST
+};
+
/**
* enum brcmf_nlattrs - nl80211 message attributes
*
@@ -25,11 +30,21 @@ enum brcmf_nlattrs {
BRCMF_NLATTR_LEN,
BRCMF_NLATTR_DATA,
+ BRCMF_NLATTR_VERS,
+ BRCMF_NLATTR_PHY_TEMP,
+ BRCMF_NLATTR_PHY_TEMPDELTA,
__BRCMF_NLATTR_AFTER_LAST,
BRCMF_NLATTR_MAX = __BRCMF_NLATTR_AFTER_LAST - 1
};
+/* structure of event sent up by firmware: is this the right place for it? */
+struct brcmf_phy_temp_evt {
+ __le32 version;
+ __le32 temp;
+ __le32 tempdelta;
+} __packed;
+
/**
* struct brcmf_vndr_dcmd_hdr - message header for cfg80211 vendor command dcmd
* support
@@ -49,5 +64,9 @@ struct brcmf_vndr_dcmd_hdr {
};
extern const struct wiphy_vendor_command brcmf_vendor_cmds[];
+extern const struct nl80211_vendor_cmd_info brcmf_vendor_events[];
+s32 brcmf_wiphy_phy_temp_evt_handler(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *e,
+ void *data);
#endif /* _vendor_h_ */
--
2.17.1

View File

@@ -0,0 +1,90 @@
From e93069267e235b26c023fbbc09218329e28ff382 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Wed, 27 Feb 2019 02:06:18 -0600
Subject: [PATCH 014/179] non-upstream: fix continuous 802.1x tx pending
timeout error
The race condition in brcmf_msgbuf_txflow and brcmf_msgbuf_delete_flowring
makes tx_msghdr writing after brcmf_msgbuf_remove_flowring. Host
driver should delete flowring after txflow complete and all txstatus back,
or pend_8021x_cnt will never be zero and cause every connection 950
milliseconds(MAX_WAIT_FOR_8021X_TX) delay.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/core.c | 4 +++-
.../broadcom/brcm80211/brcmfmac/msgbuf.c | 23 ++++++++++++++++++-
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index f4a7e23e5667..e2dfe888f1a9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1490,8 +1490,10 @@ int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)
!brcmf_get_pend_8021x_cnt(ifp),
MAX_WAIT_FOR_8021X_TX);
- if (!err)
+ if (!err) {
bphy_err(drvr, "Timed out waiting for no pending 802.1x packets\n");
+ atomic_set(&ifp->pend_8021x_cnt, 0);
+ }
return !err;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index 7c8e08ee8f0f..c1c43ef3039d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -71,6 +71,7 @@
#define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32
#define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS 48
+#define BRCMF_MAX_TXSTATUS_WAIT_RETRIES 10
struct msgbuf_common_hdr {
u8 msgtype;
@@ -807,8 +808,12 @@ static int brcmf_msgbuf_tx_queue_data(struct brcmf_pub *drvr, int ifidx,
flowid = brcmf_flowring_lookup(flow, eh->h_dest, skb->priority, ifidx);
if (flowid == BRCMF_FLOWRING_INVALID_ID) {
flowid = brcmf_msgbuf_flowring_create(msgbuf, ifidx, skb);
- if (flowid == BRCMF_FLOWRING_INVALID_ID)
+ if (flowid == BRCMF_FLOWRING_INVALID_ID) {
return -ENOMEM;
+ } else {
+ brcmf_flowring_enqueue(flow, flowid, skb);
+ return 0;
+ }
}
queue_count = brcmf_flowring_enqueue(flow, flowid, skb);
force = ((queue_count % BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) == 0);
@@ -1396,9 +1401,25 @@ void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid)
struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
struct msgbuf_tx_flowring_delete_req *delete;
struct brcmf_commonring *commonring;
+ struct brcmf_commonring *commonring_del;
+
void *ret_ptr;
u8 ifidx;
int err;
+ int retry = BRCMF_MAX_TXSTATUS_WAIT_RETRIES;
+
+ /* wait for commonring txflow finished */
+ commonring_del = msgbuf->flowrings[flowid];
+ brcmf_commonring_lock(commonring_del);
+ while (retry && atomic_read(&commonring_del->outstanding_tx)) {
+ usleep_range(5000, 10000);
+ retry--;
+ }
+ brcmf_commonring_unlock(commonring_del);
+ if (!retry && atomic_read(&commonring_del->outstanding_tx)) {
+ brcmf_err("timed out waiting for txstatus\n");
+ atomic_set(&commonring_del->outstanding_tx, 0);
+ }
/* no need to submit if firmware can not be reached */
if (drvr->bus_if->state != BRCMF_BUS_UP) {
--
2.17.1

View File

@@ -0,0 +1,262 @@
From cac47a7fb2ced35fd58ff3854a7559caf38aa434 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Thu, 7 Mar 2019 01:37:27 -0600
Subject: [PATCH 015/179] non-upstream: add sleep in bus suspend and cfg80211
resume functions
With asynchronous suspend/resume feature, suspend and resume callbacks to
be executed in parallel with each other. It makes bus changes the state to
BRCMF_BUS_DOWN before all brcmf_cfg80211_suspend IOVAR executions.
The same situation also happens in resume procedure and causes PM mode
keeps in PM_MAX after resume. In order to fix the race condition, We add
one second sleep in bus suspend and cfg80211 resume function.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/bcmsdh.c | 19 ++++++++++++--
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 25 ++++++++++++++++++-
.../broadcom/brcm80211/brcmfmac/cfg80211.h | 10 ++++++++
.../broadcom/brcm80211/brcmfmac/pcie.c | 12 +++++++++
.../broadcom/brcm80211/brcmfmac/usb.c | 15 +++++++++++
5 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index ac02244a6fdf..48f1198a617c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -36,6 +36,7 @@
#include "sdio.h"
#include "core.h"
#include "common.h"
+#include "cfg80211.h"
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
@@ -1061,6 +1062,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
dev_set_drvdata(&func->dev, bus_if);
dev_set_drvdata(&sdiodev->func1->dev, bus_if);
sdiodev->dev = &sdiodev->func1->dev;
+ dev_set_drvdata(&sdiodev->func2->dev, bus_if);
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
@@ -1077,6 +1079,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
fail:
dev_set_drvdata(&func->dev, NULL);
dev_set_drvdata(&sdiodev->func1->dev, NULL);
+ dev_set_drvdata(&sdiodev->func2->dev, NULL);
kfree(sdiodev);
kfree(bus_if);
return err;
@@ -1131,15 +1134,27 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
struct brcmf_bus *bus_if;
struct brcmf_sdio_dev *sdiodev;
mmc_pm_flag_t pm_caps, sdio_flags;
+ struct brcmf_cfg80211_info *config;
+ int retry = BRCMF_PM_WAIT_MAXRETRY;
int ret = 0;
func = container_of(dev, struct sdio_func, dev);
+ bus_if = dev_get_drvdata(dev);
+ config = bus_if->drvr->config;
+
brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
+
+ while (retry &&
+ config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING) {
+ usleep_range(10000, 20000);
+ retry--;
+ }
+ if (!retry && config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING)
+ brcmf_err("timed out wait for cfg80211 suspended\n");
+
if (func->num != 1)
return 0;
-
- bus_if = dev_get_drvdata(dev);
sdiodev = bus_if->bus_priv.sdio;
pm_caps = sdio_get_host_pm_caps(func);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 2ed7cf1c939d..0026040be597 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3822,10 +3822,24 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = cfg_to_ndev(cfg);
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_bus *bus_if = drvr->bus_if;
+ struct brcmf_cfg80211_info *config = drvr->config;
+ int retry = BRCMF_PM_WAIT_MAXRETRY;
brcmf_dbg(TRACE, "Enter\n");
+ config->pm_state = BRCMF_CFG80211_PM_STATE_RESUMING;
+
if (cfg->wowl.active) {
+ /* wait for bus resumed */
+ while (retry && bus_if->state != BRCMF_BUS_UP) {
+ usleep_range(10000, 20000);
+ retry--;
+ }
+ if (!retry && bus_if->state != BRCMF_BUS_UP)
+ brcmf_err("timed out wait for bus resume\n");
+
brcmf_report_wowl_wakeind(wiphy, ifp);
brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
@@ -3846,6 +3860,7 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
brcmf_pktfilter_enable(ifp->ndev, false);
}
+ config->pm_state = BRCMF_CFG80211_PM_STATE_RESUMED;
return 0;
}
@@ -3915,9 +3930,12 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
struct net_device *ndev = cfg_to_ndev(cfg);
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_vif *vif;
+ struct brcmf_cfg80211_info *config = ifp->drvr->config;
brcmf_dbg(TRACE, "Enter\n");
+ config->pm_state = BRCMF_CFG80211_PM_STATE_SUSPENDING;
+
/* if the primary net_device is not READY there is nothing
* we can do but pray resume goes smoothly.
*/
@@ -3959,9 +3977,13 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
}
exit:
- brcmf_dbg(TRACE, "Exit\n");
+ /* set cfg80211 pm state to cfg80211 suspended state */
+ config->pm_state = BRCMF_CFG80211_PM_STATE_SUSPENDED;
+
/* clear any scanning activity */
cfg->scan_status = 0;
+
+ brcmf_dbg(TRACE, "Exit\n");
return 0;
}
@@ -7661,6 +7683,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
cfg->wiphy = wiphy;
cfg->pub = drvr;
+ cfg->pm_state = BRCMF_CFG80211_PM_STATE_RESUMED;
init_vif_event(&cfg->vif_event);
INIT_LIST_HEAD(&cfg->vif_list);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 2bdefdaeca12..b9ee137bb3ad 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -92,6 +92,8 @@
#define BRCMF_VIF_EVENT_TIMEOUT msecs_to_jiffies(1500)
+#define BRCMF_PM_WAIT_MAXRETRY 100
+
/* cfg80211 wowlan definitions */
#define WL_WOWLAN_MAX_PATTERNS 8
#define WL_WOWLAN_MIN_PATTERN_LEN 1
@@ -185,6 +187,13 @@ enum brcmf_vif_status {
BRCMF_VIF_STATUS_ASSOC_SUCCESS,
};
+enum brcmf_cfg80211_pm_state {
+ BRCMF_CFG80211_PM_STATE_RESUMED,
+ BRCMF_CFG80211_PM_STATE_RESUMING,
+ BRCMF_CFG80211_PM_STATE_SUSPENDED,
+ BRCMF_CFG80211_PM_STATE_SUSPENDING,
+};
+
/**
* struct vif_saved_ie - holds saved IEs for a virtual interface.
*
@@ -378,6 +387,7 @@ struct brcmf_cfg80211_info {
struct brcmf_cfg80211_wowl wowl;
struct brcmf_pno_info *pno;
u8 ac_priority[MAX_8021D_PRIO];
+ u8 pm_state;
};
/**
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 3ff4997e1c97..a4826e53ac38 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -39,6 +39,7 @@
#include "chip.h"
#include "core.h"
#include "common.h"
+#include "cfg80211.h"
enum brcmf_pcie_state {
@@ -1995,11 +1996,22 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
{
struct brcmf_pciedev_info *devinfo;
struct brcmf_bus *bus;
+ struct brcmf_cfg80211_info *config;
+ int retry = BRCMF_PM_WAIT_MAXRETRY;
brcmf_dbg(PCIE, "Enter\n");
bus = dev_get_drvdata(dev);
devinfo = bus->bus_priv.pcie->devinfo;
+ config = bus->drvr->config;
+
+ while (retry &&
+ config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING) {
+ usleep_range(10000, 20000);
+ retry--;
+ }
+ if (!retry && config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING)
+ brcmf_err(bus, "timed out wait for cfg80211 suspended\n");
brcmf_bus_change_state(bus, BRCMF_BUS_DOWN);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 2e2280e76e70..d540f8664288 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -19,6 +19,7 @@
#include "core.h"
#include "common.h"
#include "bcdc.h"
+#include "cfg80211.h"
#define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000)
@@ -1481,8 +1482,22 @@ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
{
struct usb_device *usb = interface_to_usbdev(intf);
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
+ struct brcmf_bus *bus;
+ struct brcmf_cfg80211_info *config;
+ int retry = BRCMF_PM_WAIT_MAXRETRY;
brcmf_dbg(USB, "Enter\n");
+
+ bus = devinfo->bus_pub.bus;
+ config = bus->drvr->config;
+ while (retry &&
+ config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING) {
+ usleep_range(10000, 20000);
+ retry--;
+ }
+ if (!retry && config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING)
+ brcmf_err("timed out wait for cfg80211 suspended\n");
+
devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP;
brcmf_cancel_all_urbs(devinfo);
device_set_wakeup_enable(devinfo->dev, true);
--
2.17.1

View File

@@ -0,0 +1,42 @@
From b28085ad33e1a80db199e54b523f843fc5b5a822 Mon Sep 17 00:00:00 2001
From: Soontak Lee <soontak.lee@cypress.com>
Date: Mon, 4 Nov 2019 12:13:09 -0600
Subject: [PATCH 016/179] brcmfmac: add CYW43570 PCIE device
CYW43570 is a 3-antenna, 2x2 MIMO,802.11a/b/g/n/ac, PCIe 3.0 for WLAN.
It is BT/WIFI combo.
Signed-off-by: Soontak Lee <soontak.lee@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 +
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index a4826e53ac38..a1b0d59cbd26 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -2097,6 +2097,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_RAW_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4358_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4359_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID),
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 9d81320164ce..3bbe2388ec54 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -71,6 +71,7 @@
#define BRCM_PCIE_4356_DEVICE_ID 0x43ec
#define BRCM_PCIE_43567_DEVICE_ID 0x43d3
#define BRCM_PCIE_43570_DEVICE_ID 0x43d9
+#define BRCM_PCIE_43570_RAW_DEVICE_ID 0xaa31
#define BRCM_PCIE_4358_DEVICE_ID 0x43e9
#define BRCM_PCIE_4359_DEVICE_ID 0x43ef
#define BRCM_PCIE_43602_DEVICE_ID 0x43ba
--
2.17.1

View File

@@ -0,0 +1,80 @@
From 3d94471b71ece64a341b9a4b8b7b10c96699a982 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Tue, 5 Nov 2019 19:54:22 -0600
Subject: [PATCH 017/179] non-upstream: fix scheduling while atomic issue when
deleting flowring
We should not sleep while holding the spin lock. It makes
'scheduling while atomic' in brcmf_msgbuf_delete_flowring.
And to avoid race condition between deleting flowring and txflow,
we only hold spin lock when seting flowring status to RING_CLOSING.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/flowring.c | 5 +----
.../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 14 ++++++++------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
index 096f6b969dd8..e1127d7e086d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
@@ -419,7 +419,6 @@ void brcmf_flowring_configure_addr_mode(struct brcmf_flowring *flow, int ifidx,
flowid = flow->hash[i].flowid;
if (flow->rings[flowid]->status != RING_OPEN)
continue;
- flow->rings[flowid]->status = RING_CLOSING;
brcmf_msgbuf_delete_flowring(drvr, flowid);
}
}
@@ -458,10 +457,8 @@ void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx,
if ((sta || (memcmp(hash[i].mac, peer, ETH_ALEN) == 0)) &&
(hash[i].ifidx == ifidx)) {
flowid = flow->hash[i].flowid;
- if (flow->rings[flowid]->status == RING_OPEN) {
- flow->rings[flowid]->status = RING_CLOSING;
+ if (flow->rings[flowid]->status == RING_OPEN)
brcmf_msgbuf_delete_flowring(drvr, flowid);
- }
}
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index c1c43ef3039d..e856964cd048 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -1401,22 +1401,24 @@ void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid)
struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
struct msgbuf_tx_flowring_delete_req *delete;
struct brcmf_commonring *commonring;
- struct brcmf_commonring *commonring_del;
-
+ struct brcmf_commonring *commonring_del = msgbuf->flowrings[flowid];
+ struct brcmf_flowring *flow = msgbuf->flow;
void *ret_ptr;
u8 ifidx;
int err;
int retry = BRCMF_MAX_TXSTATUS_WAIT_RETRIES;
- /* wait for commonring txflow finished */
- commonring_del = msgbuf->flowrings[flowid];
+ /* make sure it is not in txflow */
brcmf_commonring_lock(commonring_del);
+ flow->rings[flowid]->status = RING_CLOSING;
+ brcmf_commonring_unlock(commonring_del);
+
+ /* wait for commonring txflow finished */
while (retry && atomic_read(&commonring_del->outstanding_tx)) {
usleep_range(5000, 10000);
retry--;
}
- brcmf_commonring_unlock(commonring_del);
- if (!retry && atomic_read(&commonring_del->outstanding_tx)) {
+ if (!retry) {
brcmf_err("timed out waiting for txstatus\n");
atomic_set(&commonring_del->outstanding_tx, 0);
}
--
2.17.1

View File

@@ -0,0 +1,91 @@
From 2a695534367cad12511f74f665a347cb410af9aa Mon Sep 17 00:00:00 2001
From: "alep@cypress.com" <alexander.prutskov@cypress.com>
Date: Fri, 26 Jul 2019 04:03:06 -0500
Subject: [PATCH 018/179] brcmfmac: Support 89459 pcie
Adds support of 89459 chip pcie device and save restore support.
Signed-off-by: alep@cypress.com <alexander.prutskov@cypress.com>
Signed-off-by: Joseph chuang <jiac@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 3 +++
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 4 ++++
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 4 +++-
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 1ee49f9e325d..9dff0dacd5e7 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -731,6 +731,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
return 0x160000;
case CY_CC_43752_CHIP_ID:
return 0x170000;
+ case CY_CC_89459_CHIP_ID:
+ return ((ci->pub.chiprev < 9) ? 0x180000 : 0x160000);
default:
brcmf_err("unknown chip: %s\n", ci->pub.name);
break;
@@ -1418,6 +1420,7 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
reg = chip->ops->read32(chip->ctx, addr);
return reg != 0;
case CY_CC_4373_CHIP_ID:
+ case CY_CC_89459_CHIP_ID:
/* explicitly check SR engine enable bit */
addr = CORE_CC_REG(base, sr_control0);
reg = chip->ops->read32(chip->ctx, addr);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index a1b0d59cbd26..53f3b83a25e6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -60,6 +60,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie");
BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
+BRCMF_FW_DEF(4355, "brcmfmac89459-pcie");
/* firmware config files */
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt");
@@ -88,6 +89,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
+ BRCMF_FW_ENTRY(CY_CC_89459_CHIP_ID, 0xFFFFFFFF, 4355),
};
#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
@@ -2113,6 +2115,8 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(CY_PCIE_89459_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(CY_PCIE_89459_RAW_DEVICE_ID),
{ /* end: all zeroes */ }
};
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 3bbe2388ec54..b553470b4997 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -53,6 +53,7 @@
#define CY_CC_4373_CHIP_ID 0x4373
#define CY_CC_43012_CHIP_ID 43012
#define CY_CC_43752_CHIP_ID 43752
+#define CY_CC_89459_CHIP_ID 0x4355
/* USB Device IDs */
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
@@ -86,7 +87,8 @@
#define BRCM_PCIE_4366_2G_DEVICE_ID 0x43c4
#define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5
#define BRCM_PCIE_4371_DEVICE_ID 0x440d
-
+#define CY_PCIE_89459_DEVICE_ID 0x4415
+#define CY_PCIE_89459_RAW_DEVICE_ID 0x4355
/* brcmsmac IDs */
#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
--
2.17.1

View File

@@ -0,0 +1,143 @@
From 7a3070f758e4b4c8bbea195c7ba2eef1b3a816df Mon Sep 17 00:00:00 2001
From: Soontak Lee <soontak.lee@cypress.com>
Date: Wed, 6 Nov 2019 17:36:25 -0600
Subject: [PATCH 019/179] brcmfmac: Support multiple AP interfaces and fix STA
disconnection issue
Support multiple AP interfaces for STA + AP + AP usecase.
And fix STA disconnection when deactivating AP interface.
Signed-off-by: Soontak Lee <soontak.lee@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 48 +++++++++++++++----
.../broadcom/brcm80211/brcmfmac/cfg80211.h | 1 +
.../broadcom/brcm80211/brcmfmac/common.c | 5 ++
3 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 0026040be597..c8581cbc0731 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -4756,6 +4756,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
settings->inactivity_timeout);
dev_role = ifp->vif->wdev.iftype;
mbss = ifp->vif->mbss;
+ brcmf_dbg(TRACE, "mbss %s\n", mbss ? "enabled" : "disabled");
/* store current 11d setting */
if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY,
@@ -4970,6 +4971,9 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
if ((err) && (!mbss)) {
brcmf_set_mpc(ifp, 1);
brcmf_configure_arp_nd_offload(ifp, true);
+ } else {
+ cfg->num_softap++;
+ brcmf_dbg(TRACE, "Num of SoftAP %u\n", cfg->num_softap);
}
return err;
}
@@ -4983,6 +4987,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
s32 err;
struct brcmf_fil_bss_enable_le bss_enable;
struct brcmf_join_params join_params;
+ s32 apsta = 0;
brcmf_dbg(TRACE, "Enter\n");
@@ -4999,6 +5004,27 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
}
+ cfg->num_softap--;
+
+ /* Clear bss configuration and SSID */
+ bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
+ bss_enable.enable = cpu_to_le32(0);
+ err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
+ sizeof(bss_enable));
+ if (err < 0)
+ brcmf_err("bss_enable config failed %d\n", err);
+
+ memset(&join_params, 0, sizeof(join_params));
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
+ &join_params, sizeof(join_params));
+ if (err < 0)
+ bphy_err(drvr, "SET SSID error (%d)\n", err);
+
+ if (cfg->num_softap) {
+ brcmf_dbg(TRACE, "Num of SoftAP %u\n", cfg->num_softap);
+ return 0;
+ }
+
if (ifp->vif->mbss) {
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
return err;
@@ -5008,17 +5034,18 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
if (ifp->bsscfgidx == 0)
brcmf_fil_iovar_int_set(ifp, "closednet", 0);
- memset(&join_params, 0, sizeof(join_params));
- err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
- &join_params, sizeof(join_params));
- if (err < 0)
- bphy_err(drvr, "SET SSID error (%d)\n", err);
- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
- if (err < 0)
- bphy_err(drvr, "BRCMF_C_DOWN error %d\n", err);
- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
+ err = brcmf_fil_iovar_int_get(ifp, "apsta", &apsta);
if (err < 0)
- bphy_err(drvr, "setting AP mode failed %d\n", err);
+ brcmf_err("wl apsta failed (%d)\n", err);
+
+ if (!apsta) {
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
+ if (err < 0)
+ bphy_err(drvr, "BRCMF_C_DOWN error %d\n", err);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
+ if (err < 0)
+ bphy_err(drvr, "Set AP mode error %d\n", err);
+ }
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
brcmf_fil_iovar_int_set(ifp, "mbss", 0);
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
@@ -7684,6 +7711,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
cfg->wiphy = wiphy;
cfg->pub = drvr;
cfg->pm_state = BRCMF_CFG80211_PM_STATE_RESUMED;
+ cfg->num_softap = 0;
init_vif_event(&cfg->vif_event);
INIT_LIST_HEAD(&cfg->vif_list);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index b9ee137bb3ad..917a1a6bb318 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -388,6 +388,7 @@ struct brcmf_cfg80211_info {
struct brcmf_pno_info *pno;
u8 ac_priority[MAX_8021D_PRIO];
u8 pm_state;
+ u8 num_softap;
};
/**
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index ae16781dd527..2a8cb5c958cf 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -305,6 +305,11 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
brcmf_dbg(INFO, "CLM version = %s\n", clmver);
}
+ /* set apsta */
+ err = brcmf_fil_iovar_int_set(ifp, "apsta", 1);
+ if (err)
+ brcmf_info("failed setting apsta, %d\n", err);
+
/* set mpc */
err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
if (err) {
--
2.17.1

View File

@@ -0,0 +1,465 @@
From f96ddedb3ec68bb591db842dfeffca698a5f2eba Mon Sep 17 00:00:00 2001
From: Soontak Lee <soontak.lee@cypress.com>
Date: Mon, 4 Nov 2019 18:33:29 -0600
Subject: [PATCH 020/179] non-upstream: Support custom PCIE BAR window size
Certain host processors cannot support 4MB PCIE BAR window size.
For example, AMLogic A113D can support 2MB size only.
This patch is for host processor which support lower than 4MB
PCIE BAR window size.
Signed-off-by: Soontak Lee <soontak.lee@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
---
.../net/wireless/broadcom/brcm80211/Kconfig | 11 +
.../broadcom/brcm80211/brcmfmac/pcie.c | 283 +++++++++++++++++-
2 files changed, 288 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/Kconfig b/drivers/net/wireless/broadcom/brcm80211/Kconfig
index 5bf2318763c5..ee17eb21a084 100644
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
@@ -37,3 +37,14 @@ config BRCMDBG
select WANT_DEV_COREDUMP if BRCMFMAC
help
Selecting this enables additional code for debug purposes.
+
+config BRCMFMAC_PCIE_BARWIN_SZ
+ bool "Custom PCIE BAR window size support for FullMAC driver"
+ depends on BRCMFMAC
+ depends on PCI
+ default n
+ ---help---
+ If you say Y here, the FMAC driver will use custom PCIE BAR
+ window size. Say Y to allow developers to use custom PCIE
+ BAR window size when HOST PCIE IP can support less then 4MB
+ BAR window.
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 53f3b83a25e6..bba41b191865 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -283,6 +283,9 @@ struct brcmf_pciedev_info {
void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
u16 value);
struct brcmf_mp_device *settings;
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ ulong bar1_size;
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
};
struct brcmf_pcie_ringbuf {
@@ -354,6 +357,10 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
static struct brcmf_fw_request *
brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo);
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+DEFINE_RAW_SPINLOCK(pcie_lock);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+
static u32
brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
{
@@ -377,8 +384,24 @@ static u8
brcmf_pcie_read_tcm8(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
{
void __iomem *address = devinfo->tcm + mem_offset;
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ unsigned long flags;
+ u8 value;
+
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >= devinfo->bar1_size) {
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address - devinfo->bar1_size;
+ }
+ value = ioread8(address);
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN, 0x0);
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+ return value;
+#else
return (ioread8(address));
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
}
@@ -386,8 +409,24 @@ static u16
brcmf_pcie_read_tcm16(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
{
void __iomem *address = devinfo->tcm + mem_offset;
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ u16 value;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >= devinfo->bar1_size) {
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address - devinfo->bar1_size;
+ }
+ value = ioread16(address);
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN, 0x0);
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+ return value;
+#else
return (ioread16(address));
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
}
@@ -396,8 +435,22 @@ brcmf_pcie_write_tcm16(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
u16 value)
{
void __iomem *address = devinfo->tcm + mem_offset;
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >= devinfo->bar1_size) {
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address - devinfo->bar1_size;
+ }
iowrite16(value, address);
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN, 0x0);
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+#else
+ iowrite16(value, address);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
}
@@ -424,8 +477,24 @@ static u32
brcmf_pcie_read_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
{
void __iomem *address = devinfo->tcm + mem_offset;
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ u32 value;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >= devinfo->bar1_size) {
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address - devinfo->bar1_size;
+ }
+ value = ioread32(address);
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN, 0x0);
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+ return value;
+#else
return (ioread32(address));
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
}
@@ -434,17 +503,47 @@ brcmf_pcie_write_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
u32 value)
{
void __iomem *address = devinfo->tcm + mem_offset;
-
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >= devinfo->bar1_size) {
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address - devinfo->bar1_size;
+ }
iowrite32(value, address);
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN, 0x0);
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+#else
+ iowrite32(value, address);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
}
static u32
brcmf_pcie_read_ram32(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
{
- void __iomem *addr = devinfo->tcm + devinfo->ci->rambase + mem_offset;
+ void __iomem *address = devinfo->tcm + devinfo->ci->rambase
+ + mem_offset;
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ u32 value;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >= devinfo->bar1_size) {
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address - devinfo->bar1_size;
+ }
+ value = ioread32(address);
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN, 0x0);
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
- return (ioread32(addr));
+ return value;
+#else
+ return (ioread32(address));
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
}
@@ -452,9 +551,114 @@ static void
brcmf_pcie_write_ram32(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
u32 value)
{
- void __iomem *addr = devinfo->tcm + devinfo->ci->rambase + mem_offset;
+ void __iomem *address = devinfo->tcm + devinfo->ci->rambase
+ + mem_offset;
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ unsigned long flags;
- iowrite32(value, addr);
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >= devinfo->bar1_size) {
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address - devinfo->bar1_size;
+ }
+ iowrite32(value, address);
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN, 0x0);
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+#else
+ iowrite32(value, address);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+}
+
+
+static void
+brcmf_pcie_copy_mem_todev(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
+ void *srcaddr, u32 len)
+{
+ void __iomem *address = devinfo->tcm + mem_offset;
+ __le32 *src32;
+ __le16 *src16;
+ u8 *src8;
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ unsigned long flags;
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+
+ if (((ulong)address & 4) || ((ulong)srcaddr & 4) || (len & 4)) {
+ if (((ulong)address & 2) || ((ulong)srcaddr & 2) || (len & 2)) {
+ src8 = (u8 *)srcaddr;
+ while (len) {
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >=
+ devinfo->bar1_size) {
+ pci_write_config_dword
+ (devinfo->pdev,
+ BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address -
+ devinfo->bar1_size;
+ }
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+ iowrite8(*src8, address);
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+ address++;
+ src8++;
+ len--;
+ }
+ } else {
+ len = len / 2;
+ src16 = (__le16 *)srcaddr;
+ while (len) {
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >=
+ devinfo->bar1_size) {
+ pci_write_config_dword
+ (devinfo->pdev,
+ BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address -
+ devinfo->bar1_size;
+ }
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+ iowrite16(le16_to_cpu(*src16), address);
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+ address += 2;
+ src16++;
+ len--;
+ }
+ }
+ } else {
+ len = len / 4;
+ src32 = (__le32 *)srcaddr;
+ while (len) {
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >=
+ devinfo->bar1_size) {
+ pci_write_config_dword
+ (devinfo->pdev,
+ BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address - devinfo->bar1_size;
+ }
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+ iowrite32(le32_to_cpu(*src32), address);
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+ address += 4;
+ src32++;
+ len--;
+ }
+ }
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN, 0x0);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
}
@@ -466,12 +670,30 @@ brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
__le32 *dst32;
__le16 *dst16;
u8 *dst8;
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ unsigned long flags;
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
if (((ulong)address & 4) || ((ulong)dstaddr & 4) || (len & 4)) {
if (((ulong)address & 2) || ((ulong)dstaddr & 2) || (len & 2)) {
dst8 = (u8 *)dstaddr;
while (len) {
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >=
+ devinfo->bar1_size) {
+ pci_write_config_dword
+ (devinfo->pdev,
+ BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address -
+ devinfo->bar1_size;
+ }
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
*dst8 = ioread8(address);
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
address++;
dst8++;
len--;
@@ -480,7 +702,22 @@ brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
len = len / 2;
dst16 = (__le16 *)dstaddr;
while (len) {
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >=
+ devinfo->bar1_size) {
+ pci_write_config_dword
+ (devinfo->pdev,
+ BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address -
+ devinfo->bar1_size;
+ }
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
*dst16 = cpu_to_le16(ioread16(address));
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
address += 2;
dst16++;
len--;
@@ -490,12 +727,29 @@ brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
len = len / 4;
dst32 = (__le32 *)dstaddr;
while (len) {
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_lock_irqsave(&pcie_lock, flags);
+ if ((address - devinfo->tcm) >=
+ devinfo->bar1_size) {
+ pci_write_config_dword
+ (devinfo->pdev,
+ BCMA_PCI_BAR1_WIN,
+ devinfo->bar1_size);
+ address = address - devinfo->bar1_size;
+ }
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
*dst32 = cpu_to_le32(ioread32(address));
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ raw_spin_unlock_irqrestore(&pcie_lock, flags);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
address += 4;
dst32++;
len--;
}
}
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ pci_write_config_dword(devinfo->pdev, BCMA_PCI_BAR1_WIN, 0x0);
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
}
@@ -539,6 +793,9 @@ static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo)
BRCMF_PCIE_CFGREG_MSI_ADDR_L,
BRCMF_PCIE_CFGREG_MSI_ADDR_H,
BRCMF_PCIE_CFGREG_MSI_DATA,
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ BCMA_PCI_BAR1_WIN,
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL2,
BRCMF_PCIE_CFGREG_RBAR_CTRL,
BRCMF_PCIE_CFGREG_PML1_SUB_CTRL1,
@@ -1108,9 +1365,14 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
u16 max_flowrings;
u16 max_submissionrings;
u16 max_completionrings;
-
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ brcmf_pcie_copy_dev_tomem(devinfo, devinfo->shared.ring_info_addr,
+ &ringinfo, sizeof(ringinfo));
+#else
memcpy_fromio(&ringinfo, devinfo->tcm + devinfo->shared.ring_info_addr,
sizeof(ringinfo));
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+
if (devinfo->shared.version >= 6) {
max_submissionrings = le16_to_cpu(ringinfo.max_submissionrings);
max_flowrings = le16_to_cpu(ringinfo.max_flowrings);
@@ -1179,8 +1441,14 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
ringinfo.d2h_r_idx_hostaddr.high_addr =
cpu_to_le32(address >> 32);
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ brcmf_pcie_copy_mem_todev(devinfo,
+ devinfo->shared.ring_info_addr,
+ &ringinfo, sizeof(ringinfo));
+#else
memcpy_toio(devinfo->tcm + devinfo->shared.ring_info_addr,
&ringinfo, sizeof(ringinfo));
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
brcmf_dbg(PCIE, "Using host memory indices\n");
}
@@ -1632,6 +1900,9 @@ static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo)
devinfo->regs = ioremap(bar0_addr, BRCMF_PCIE_REG_MAP_SIZE);
devinfo->tcm = ioremap(bar1_addr, bar1_size);
+#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
+ devinfo->bar1_size = bar1_size;
+#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
if (!devinfo->regs || !devinfo->tcm) {
brcmf_err(bus, "ioremap() failed (%p,%p)\n", devinfo->regs,
--
2.17.1

View File

@@ -0,0 +1,104 @@
From da21f93450c9ece85bed6eac4df041756d786cc1 Mon Sep 17 00:00:00 2001
From: "Lo(Double)Hsiang Lo" <double.lo@cypress.com>
Date: Mon, 9 Dec 2019 20:49:17 -0600
Subject: [PATCH 021/179] brcmfmac: support for virtual interface creation from
firmware
Allow interface creation via IF_ADD event from firmware.
Signed-off-by: Lo(Double)Hsiang Lo <double.lo@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
SWLINUX-1291
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 45 +++++++++++++++++--
1 file changed, 42 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index c8581cbc0731..748c2078b7e3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -233,6 +233,9 @@ struct parsed_vndr_ies {
struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
};
+#define WLC_E_IF_ROLE_STA 0 /* Infra STA */
+#define WLC_E_IF_ROLE_AP 1 /* Access Point */
+
static u8 nl80211_band_to_fwil(enum nl80211_band band)
{
switch (band) {
@@ -5715,8 +5718,10 @@ void brcmf_cfg80211_free_netdev(struct net_device *ndev)
ifp = netdev_priv(ndev);
vif = ifp->vif;
- if (vif)
+ if (vif) {
brcmf_free_vif(vif);
+ ifp->vif = NULL;
+ }
}
static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif,
@@ -6326,6 +6331,9 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
struct brcmf_cfg80211_vif *vif;
+ enum nl80211_iftype iftype = NL80211_IFTYPE_UNSPECIFIED;
+ bool vif_pend = false;
+ int err;
brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
ifevent->action, ifevent->flags, ifevent->ifidx,
@@ -6338,9 +6346,28 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
switch (ifevent->action) {
case BRCMF_E_IF_ADD:
/* waiting process may have timed out */
- if (!cfg->vif_event.vif) {
+ if (!vif) {
+ /* handle IF_ADD event from firmware */
spin_unlock(&event->vif_event_lock);
- return -EBADF;
+ vif_pend = true;
+ if (ifevent->role == WLC_E_IF_ROLE_STA)
+ iftype = NL80211_IFTYPE_STATION;
+ else if (ifevent->role == WLC_E_IF_ROLE_AP)
+ iftype = NL80211_IFTYPE_AP;
+ else
+ vif_pend = false;
+
+ if (vif_pend) {
+ vif = brcmf_alloc_vif(cfg, iftype);
+ if (IS_ERR(vif)) {
+ brcmf_err("Role:%d failed to alloc vif\n",
+ ifevent->role);
+ return PTR_ERR(vif);
+ }
+ } else {
+ brcmf_err("Invalid Role:%d\n", ifevent->role);
+ return -EBADF;
+ }
}
ifp->vif = vif;
@@ -6350,6 +6377,18 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
ifp->ndev->ieee80211_ptr = &vif->wdev;
SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
}
+
+ if (vif_pend) {
+ err = brcmf_net_attach(ifp, false);
+ if (err) {
+ brcmf_err("netdevice register failed with err:%d\n",
+ err);
+ brcmf_free_vif(vif);
+ free_netdev(ifp->ndev);
+ }
+ return err;
+ }
+
spin_unlock(&event->vif_event_lock);
wake_up(&event->vif_wq);
return 0;
--
2.17.1

View File

@@ -0,0 +1,40 @@
From 67a30ebf25d750d9b58c876928a828fe17c3fd53 Mon Sep 17 00:00:00 2001
From: "Lo(Double)Hsiang Lo" <double.lo@cypress.com>
Date: Mon, 16 Dec 2019 03:41:09 -0600
Subject: [PATCH 022/179] brcmfmac: increase dcmd maximum buffer size
Increase dcmd maximum buffer size to match firmware
configuration for new chips.
Signed-off-by: Lo(Double)Hsiang Lo <double.lo@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
SWLINUX-1273
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
index 3984fd7d918e..a04c29016d4b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
@@ -87,6 +87,8 @@ struct brcmf_proto_bcdc_header {
* plus any space that might be needed
* for bus alignment padding.
*/
+#define ROUND_UP_MARGIN 2048
+
struct brcmf_bcdc {
u16 reqid;
u8 bus_header[BUS_HEADER_LEN];
@@ -471,7 +473,7 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
- sizeof(struct brcmf_proto_bcdc_dcmd);
+ sizeof(struct brcmf_proto_bcdc_dcmd) + ROUND_UP_MARGIN;
return 0;
fail:
--
2.17.1

View File

@@ -0,0 +1,39 @@
From 8bb3f53dd00b7d2f2d443a751f7af60ceae18ae5 Mon Sep 17 00:00:00 2001
From: Kurt Lee/TAIPEI <kurl@cypress.com>
Date: Tue, 31 Dec 2019 03:47:08 -0600
Subject: [PATCH 023/179] brcmfmac: set net carrier on via test tool for AP
mode
Host parses ioctl cmd via test tool, then set itself iftype to ap
mode and report netif_carrier_on to upper layer
Signed-off-by: Kurt Lee <kurt.lee@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
SWLINUX-1322
---
.../net/wireless/broadcom/brcm80211/brcmfmac/vendor.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
index 4ed3287522cb..0bad78d5f5c9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
@@ -64,6 +64,15 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
*(char *)(dcmd_buf + len) = '\0';
}
+ if (cmdhdr->cmd == BRCMF_C_SET_AP) {
+ if (*(int *)(dcmd_buf) == 1) {
+ ifp->vif->wdev.iftype = NL80211_IFTYPE_AP;
+ brcmf_net_setcarrier(ifp, true);
+ } else {
+ ifp->vif->wdev.iftype = NL80211_IFTYPE_STATION;
+ }
+ }
+
if (cmdhdr->set)
ret = brcmf_fil_cmd_data_set(ifp, cmdhdr->cmd, dcmd_buf,
ret_len);
--
2.17.1

View File

@@ -0,0 +1,93 @@
From 1bc5a46ef669755e9437abd6bf9e1e8213cdbd15 Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Date: Thu, 14 Feb 2019 16:33:53 +0800
Subject: [PATCH 024/179] nl80211: add authorized flag back to ROAM event
Commit 503c1fb98ba3 ("cfg80211/nl80211: add a port authorized event")
added the NL80211_CMD_PORT_AUTHORIZED event to indicate that a
connection is authorized. It replaced the PORT_AUTHORIZED attribute and
the authorized flag added in commit f45cbe6e691f
("nl80211: add authorized flag to ROAM event").
However, for offload FT, using PORT_AUTHORIZED event mechanism induces
wpa_supplicant to start a full EAP exchange after a successful roaming.
This patch adds the flag mechanism back to the ROAM event for drivers
to fix the offload FT roaming issue.
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
include/net/cfg80211.h | 4 ++++
include/uapi/linux/nl80211.h | 5 ++++-
net/wireless/nl80211.c | 4 +++-
net/wireless/sme.c | 1 +
4 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 27336fc70467..125918d90397 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -7190,6 +7190,9 @@ cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
* @resp_ie: association response IEs (may be %NULL)
* @resp_ie_len: assoc response IEs length
* @fils: FILS related roaming information.
+ * @authorized: true if the 802.1X authentication was done by the driver or is
+ * not needed (e.g., when Fast Transition protocol was used), false
+ * otherwise. Ignored for networks that don't use 802.1X authentication.
*/
struct cfg80211_roam_info {
struct ieee80211_channel *channel;
@@ -7200,6 +7203,7 @@ struct cfg80211_roam_info {
const u8 *resp_ie;
size_t resp_ie_len;
struct cfg80211_fils_resp_params fils;
+ bool authorized;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c2efea98e060..560f54bb492c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2426,7 +2426,10 @@ enum nl80211_commands {
* in %NL80211_CMD_CONNECT to indicate that for 802.1X authentication it
* wants to use the supported offload of the 4-way handshake.
* @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
- * @NL80211_ATTR_PORT_AUTHORIZED: (reserved)
+ * @NL80211_ATTR_PORT_AUTHORIZED: flag attribute used in %NL80211_CMD_ROAMED
+ * notification indicating that that 802.1X authentication was done by
+ * the driver or is not needed (because roaming used the Fast Transition
+ * protocol).
*
* @NL80211_ATTR_EXTERNAL_AUTH_ACTION: Identify the requested external
* authentication operation (u32 attribute with an
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index bb46a6a34614..074518840d31 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -16536,7 +16536,9 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
(info->fils.pmk &&
nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
(info->fils.pmkid &&
- nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
+ nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)) ||
+ (info->authorized &&
+ nla_put_flag(msg, NL80211_ATTR_PORT_AUTHORIZED)))
goto nla_put_failure;
genlmsg_end(msg, hdr);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 08a70b4f090c..9f821cb2c05f 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -1021,6 +1021,7 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
if (info->fils.update_erp_next_seq_num)
ev->rm.fils.erp_next_seq_num = info->fils.erp_next_seq_num;
ev->rm.bss = info->bss;
+ ev->rm.authorized = info->authorized;
spin_lock_irqsave(&wdev->event_lock, flags);
list_add_tail(&ev->list, &wdev->event_list);
--
2.17.1

View File

@@ -0,0 +1,48 @@
From 22596bdaa5055c5637a8e738f0d613f8072b25fd Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Date: Thu, 14 Feb 2019 17:28:22 +0800
Subject: [PATCH 025/179] brcmfmac: set authorized flag in ROAM event for
offload FT roaming
When using PORT_AUTHORIZED event mechanism for offload FT,
wpa_supplicant started a full EAP exchange after a successful roaming.
It was caused by setting portEnabled to FALSE to get EAP state machine
out of the SUCCESS state and eapSuccess cleared when handling ROAM
event in wap_supplicant.
With this patch, the authorized flag in the ROAM event is used to
indicate the connection is authorized. Wpa_supplicant sets portEnabled
according to the flag and no full EAP exchange is performed after the
roaming.
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 748c2078b7e3..35cbee081322 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6084,14 +6084,12 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
roam_info.resp_ie = conn_info->resp_ie;
roam_info.resp_ie_len = conn_info->resp_ie_len;
+ if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft)
+ roam_info.authorized = true;
+
cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
brcmf_dbg(CONN, "Report roaming result\n");
- if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) {
- cfg80211_port_authorized(ndev, profile->bssid, GFP_KERNEL);
- brcmf_dbg(CONN, "Report port authorized\n");
- }
-
set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
brcmf_dbg(TRACE, "Exit\n");
return err;
--
2.17.1

View File

@@ -0,0 +1,83 @@
From 2b58c732ab3d125c6f15d235aea37e9a3a4c9707 Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Date: Sun, 3 Mar 2019 20:30:32 -0600
Subject: [PATCH 026/179] brcmfmac: set authorized flag in ROAM event for PMK
caching
With 4-way handshake offload for 802.1X authentication, the authorized
flag in ROAM event should be set for a successful roaming with PMK
caching. The roaming is identified by checking the existence of PMKID
within the (Re)Association Request frame with this patch.
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 45 ++++++++++++++++++-
1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 35cbee081322..e85f7e138fb4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6024,6 +6024,47 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
return err;
}
+static bool
+brcmf_has_pmkid(const u8 *parse, u32 len)
+{
+ const struct brcmf_tlv *rsn_ie;
+ const u8 *ie;
+ u32 ie_len;
+ u32 offset;
+ u16 count;
+
+ rsn_ie = brcmf_parse_tlvs(parse, len, WLAN_EID_RSN);
+ if (!rsn_ie)
+ goto done;
+ ie = (const u8 *)rsn_ie;
+ ie_len = rsn_ie->len + TLV_HDR_LEN;
+ /* Skip group data cipher suite */
+ offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
+ goto done;
+ /* Skip pairwise cipher suite(s) */
+ count = ie[offset] + (ie[offset + 1] << 8);
+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
+ goto done;
+ /* Skip auth key management suite(s) */
+ count = ie[offset] + (ie[offset + 1] << 8);
+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
+ if (offset + RSN_CAP_LEN >= ie_len)
+ goto done;
+ /* Skip rsn capabilities */
+ offset += RSN_CAP_LEN;
+ if (offset + RSN_PMKID_COUNT_LEN > ie_len)
+ goto done;
+ /* Extract PMKID count */
+ count = ie[offset] + (ie[offset + 1] << 8);
+ if (count)
+ return true;
+
+done:
+ return false;
+}
+
static s32
brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev,
@@ -6084,7 +6125,9 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
roam_info.resp_ie = conn_info->resp_ie;
roam_info.resp_ie_len = conn_info->resp_ie_len;
- if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft)
+ if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X &&
+ (brcmf_has_pmkid(roam_info.req_ie, roam_info.req_ie_len) ||
+ profile->is_ft))
roam_info.authorized = true;
cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
--
2.17.1

View File

@@ -0,0 +1,65 @@
From 4d5061baaed43b218abff4cb6601c67c9f334ac7 Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Date: Tue, 30 Apr 2019 17:52:41 -0500
Subject: [PATCH 027/179] nl80211: add authorized flag to CONNECT event
Add authorized flag to CONNECT event. It is used for 802.1X 4-way
handshake offload with PMK caching.
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
include/net/cfg80211.h | 3 +++
net/wireless/nl80211.c | 2 ++
net/wireless/sme.c | 1 +
3 files changed, 6 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 125918d90397..afc4a4a17a10 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -7030,6 +7030,8 @@ struct cfg80211_fils_resp_params {
* not known. This value is used only if @status < 0 to indicate that the
* failure is due to a timeout and not due to explicit rejection by the AP.
* This value is ignored in other cases (@status >= 0).
+ * @authorized: Indicates whether the connection is ready to transport
+ * data packets.
*/
struct cfg80211_connect_resp_params {
int status;
@@ -7041,6 +7043,7 @@ struct cfg80211_connect_resp_params {
size_t resp_ie_len;
struct cfg80211_fils_resp_params fils;
enum nl80211_timeout_reason timeout_reason;
+ bool authorized;
};
/**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 074518840d31..4e200f640a3b 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -16470,6 +16470,8 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
(nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
cr->timeout_reason))) ||
+ (cr->authorized &&
+ nla_put_flag(msg, NL80211_ATTR_PORT_AUTHORIZED)) ||
(cr->req_ie &&
nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
(cr->resp_ie &&
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 9f821cb2c05f..8e60f879da95 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -887,6 +887,7 @@ void cfg80211_connect_done(struct net_device *dev,
ev->cr.bss = params->bss;
ev->cr.status = params->status;
ev->cr.timeout_reason = params->timeout_reason;
+ ev->cr.authorized = params->authorized;
spin_lock_irqsave(&wdev->event_lock, flags);
list_add_tail(&ev->list, &wdev->event_list);
--
2.17.1

View File

@@ -0,0 +1,36 @@
From 3133cf33a6b350fe50f65759d364b865352975ed Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Date: Tue, 30 Apr 2019 17:55:02 -0500
Subject: [PATCH 028/179] brcmfmac: set authorized flag in CONNECT event for
PMK caching
With 4-way handshake offload for 802.1X authentication, the authorized
flag in CONNECT event should be set for a successful connection with
PMK caching. The connection is identified by checking the existence of
PMKID within the Association Request frame with this patch.
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index e85f7e138fb4..274d7e982b2a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6167,6 +6167,11 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
conn_params.req_ie_len = conn_info->req_ie_len;
conn_params.resp_ie = conn_info->resp_ie;
conn_params.resp_ie_len = conn_info->resp_ie_len;
+
+ if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X &&
+ brcmf_has_pmkid(conn_params.req_ie, conn_params.req_ie_len))
+ conn_params.authorized = true;
+
cfg80211_connect_done(ndev, &conn_params, GFP_KERNEL);
brcmf_dbg(CONN, "Report connect result - connection %s\n",
completed ? "succeeded" : "failed");
--
2.17.1

View File

@@ -0,0 +1,108 @@
From d0771ea001c37e2b4a3c490b0b93cfcdb8802646 Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Date: Tue, 28 May 2019 04:20:20 -0500
Subject: [PATCH 029/179] brcmfmac: add support for Opportunistic Key Caching
The firmware may have OKC management. This is detected by the driver and
supported via providing the PMK. The authorized flag in ROAM event
should be set for a successful roaming with OKC.
Signed-off-by: Darren Li <hsin-hung.li@cypress.com>
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 25 +++++++++++++++++--
.../broadcom/brcm80211/brcmfmac/cfg80211.h | 1 +
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 274d7e982b2a..afb936150eaa 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -1756,6 +1756,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
struct brcmf_pub *drvr = ifp->drvr;
s32 val;
s32 err;
+ s32 okc_enable;
const struct brcmf_tlv *rsn_ie;
const u8 *ie;
u32 ie_len;
@@ -1766,6 +1767,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
profile->is_ft = false;
+ profile->is_okc = false;
if (!sme->crypto.n_akm_suites)
return 0;
@@ -1847,8 +1849,17 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
}
}
- if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X)
+ if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X) {
brcmf_dbg(INFO, "using 1X offload\n");
+ err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "okc_enable",
+ &okc_enable);
+ if (err) {
+ bphy_err(drvr, "get okc_enable failed (%d)\n", err);
+ } else {
+ brcmf_dbg(INFO, "get okc_enable (%d)\n", okc_enable);
+ profile->is_okc = okc_enable;
+ }
+ }
if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
goto skip_mfp_config;
@@ -5559,17 +5570,27 @@ static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
const struct cfg80211_pmk_conf *conf)
{
struct brcmf_if *ifp;
+ struct brcmf_pub *drvr;
+ int ret;
brcmf_dbg(TRACE, "enter\n");
/* expect using firmware supplicant for 1X */
ifp = netdev_priv(dev);
+ drvr = ifp->drvr;
if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
return -EINVAL;
if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN)
return -ERANGE;
+ if (ifp->vif->profile.is_okc) {
+ ret = brcmf_fil_iovar_data_set(ifp, "okc_info_pmk", conf->pmk,
+ conf->pmk_len);
+ if (ret < 0)
+ bphy_err(drvr, "okc_info_pmk iovar failed: ret=%d\n", ret);
+ }
+
return brcmf_set_pmk(ifp, conf->pmk, conf->pmk_len);
}
@@ -6127,7 +6148,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X &&
(brcmf_has_pmkid(roam_info.req_ie, roam_info.req_ie_len) ||
- profile->is_ft))
+ profile->is_ft || profile->is_okc))
roam_info.authorized = true;
cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 917a1a6bb318..118a47e1dd7f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -164,6 +164,7 @@ struct brcmf_cfg80211_profile {
enum brcmf_profile_fwsup use_fwsup;
u16 use_fwauth;
bool is_ft;
+ bool is_okc;
};
/**
--
2.17.1

View File

@@ -0,0 +1,241 @@
From 6b4c0c369438ca0dac0c68611f69d84984c9f704 Mon Sep 17 00:00:00 2001
From: Raveendran Somu <raveendran.somu@cypress.com>
Date: Wed, 7 Nov 2018 16:59:03 -0600
Subject: [PATCH 030/179] brcmfmac: To support printing USB console messages
This change is to add support for printing the firmware
console messges of a USB interface chip to the host.
To enable this feature, build option '-msgtrace' should be
enabled in the firmware. And in the host, debug=0x100000
should be provided as a module parameter.
Signed-off-by: Raveendran Somu <raveendran.somu@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/bus.h | 1 +
.../broadcom/brcm80211/brcmfmac/core.c | 9 ++
.../broadcom/brcm80211/brcmfmac/debug.c | 83 +++++++++++++++++++
.../broadcom/brcm80211/brcmfmac/debug.h | 24 ++++++
.../broadcom/brcm80211/brcmfmac/usb.c | 14 ++++
5 files changed, 131 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index 3f5da3bb6aa5..968d3e75147d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -272,6 +272,7 @@ void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);
s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len);
void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
+int brcmf_fwlog_attach(struct device *dev);
#ifdef CONFIG_BRCMFMAC_SDIO
void brcmf_sdio_exit(void);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index e2dfe888f1a9..ff47d393fa4e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1135,6 +1135,15 @@ static int brcmf_inet6addr_changed(struct notifier_block *nb,
}
#endif
+
+int brcmf_fwlog_attach(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pub *drvr = bus_if->drvr;
+
+ return brcmf_debug_fwlog_init(drvr);
+}
+
static int brcmf_revinfo_read(struct seq_file *s, void *data)
{
struct brcmf_bus *bus_if = dev_get_drvdata(s->private);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
index eecf8a38d94a..f5da560bfc12 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
@@ -14,6 +14,82 @@
#include "fweh.h"
#include "debug.h"
+static int
+brcmf_debug_msgtrace_seqchk(u32 *prev, u32 cur)
+{
+ if ((cur == 0 && *prev == 0xFFFFFFFF) || ((cur - *prev) == 1)) {
+ goto done;
+ } else if (cur == *prev) {
+ brcmf_dbg(FWCON, "duplicate trace\n");
+ return -1;
+ } else if (cur > *prev) {
+ brcmf_dbg(FWCON, "lost %d packets\n", cur - *prev);
+ } else {
+ brcmf_dbg(FWCON, "seq out of order, host %d, dongle %d\n",
+ *prev, cur);
+ }
+done:
+ *prev = cur;
+ return 0;
+}
+
+static int
+brcmf_debug_msg_parser(void *event_data)
+{
+ int err = 0;
+ struct msgtrace_hdr *hdr;
+ char *data, *s;
+ static u32 seqnum_prev;
+
+ hdr = (struct msgtrace_hdr *)event_data;
+ data = (char *)event_data + MSGTRACE_HDRLEN;
+
+ /* There are 2 bytes available at the end of data */
+ data[ntohs(hdr->len)] = '\0';
+
+ if (ntohl(hdr->discarded_bytes) || ntohl(hdr->discarded_printf)) {
+ brcmf_dbg(FWCON, "Discarded_bytes %d discarded_printf %d\n",
+ ntohl(hdr->discarded_bytes),
+ ntohl(hdr->discarded_printf));
+ }
+
+ err = brcmf_debug_msgtrace_seqchk(&seqnum_prev, ntohl(hdr->seqnum));
+ if (err)
+ return err;
+
+ while (*data != '\0' && (s = strstr(data, "\n")) != NULL) {
+ *s = '\0';
+ brcmf_dbg(FWCON, "CONSOLE: %s\n", data);
+ data = s + 1;
+ }
+ if (*data)
+ brcmf_dbg(FWCON, "CONSOLE: %s", data);
+
+ return err;
+}
+
+static int
+brcmf_debug_trace_parser(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *evtmsg,
+ void *event_data)
+{
+ int err = 0;
+ struct msgtrace_hdr *hdr;
+
+ hdr = (struct msgtrace_hdr *)event_data;
+ if (hdr->version != MSGTRACE_VERSION) {
+ brcmf_dbg(FWCON, "trace version mismatch host %d dngl %d\n",
+ MSGTRACE_VERSION, hdr->version);
+ err = -EPROTO;
+ return err;
+ }
+
+ if (hdr->trace_type == MSGTRACE_HDR_TYPE_MSG)
+ err = brcmf_debug_msg_parser(event_data);
+
+ return err;
+}
+
int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
size_t len)
{
@@ -42,6 +118,13 @@ int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
return 0;
}
+
+int brcmf_debug_fwlog_init(struct brcmf_pub *drvr)
+{
+ return brcmf_fweh_register(drvr, BRCMF_E_TRACE,
+ brcmf_debug_trace_parser);
+}
+
struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
{
return drvr->wiphy->debugfsdir;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
index 9bb5f709d41a..169222d52fa0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
@@ -107,6 +107,10 @@ do { \
#endif /* defined(DEBUG) || defined(CONFIG_BRCM_TRACING) */
+#define MSGTRACE_VERSION 1
+#define MSGTRACE_HDR_TYPE_MSG 0
+#define MSGTRACE_HDR_TYPE_LOG 1
+
#define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \
do { \
trace_brcmf_hexdump((void *)data, len); \
@@ -123,6 +127,7 @@ void brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
int (*read_fn)(struct seq_file *seq, void *data));
int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
size_t len);
+int brcmf_debug_fwlog_init(struct brcmf_pub *drvr);
#else
static inline struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
{
@@ -138,6 +143,25 @@ int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
{
return 0;
}
+
+static inline
+int brcmf_debug_fwlog_init(struct brcmf_pub *drvr)
+{
+ return 0;
+}
#endif
+/* Message trace header */
+struct msgtrace_hdr {
+ u8 version;
+ u8 trace_type;
+ u16 len; /* Len of the trace */
+ u32 seqnum; /* Sequence number of message */
+ /* Number of discarded bytes because of trace overflow */
+ u32 discarded_bytes;
+ /* Number of discarded printf because of trace overflow */
+ u32 discarded_printf;
+};
+
+#define MSGTRACE_HDRLEN sizeof(struct msgtrace_hdr)
#endif /* BRCMFMAC_DEBUG_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index d540f8664288..5aa6b43f0c53 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -1221,6 +1221,12 @@ static void brcmf_usb_probe_phase2(struct device *dev, int ret,
if (ret)
goto error;
+ if (BRCMF_FWCON_ON()) {
+ ret = brcmf_fwlog_attach(devinfo->dev);
+ if (ret)
+ goto error;
+ }
+
/* Attach to the common driver interface */
ret = brcmf_attach(devinfo->dev);
if (ret)
@@ -1297,9 +1303,17 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
ret = brcmf_alloc(devinfo->dev, devinfo->settings);
if (ret)
goto fail;
+
+ if (BRCMF_FWCON_ON()) {
+ ret = brcmf_fwlog_attach(devinfo->dev);
+ if (ret)
+ goto fail;
+ }
+
ret = brcmf_attach(devinfo->dev);
if (ret)
goto fail;
+
/* we are done */
complete(&devinfo->dev_init_done);
return 0;
--
2.17.1

View File

@@ -0,0 +1,61 @@
From 4aa36126c355bcae29e168f583546bc65057d065 Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Fri, 21 Feb 2020 04:02:25 -0600
Subject: [PATCH 031/179] non-upstream: Fix no P2P IE in probe requests issue
This reverts commit bd99a3013bdc00f8fc7534c657b39616792b4467.
The original parameter "vif" is updated in brcmf_p2p_scan_prep()
but the new code does not get the same vif.
Fixes: bd99a30 ("brcmfmac: move configuration of probe request IEs")
Signed-off-by: Ting-Ying Li <tingying.li@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 -----
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 6 ++++--
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index afb936150eaa..094a2e49d646 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -1214,11 +1214,6 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
if (err)
goto scan_out;
- err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
- request->ie, request->ie_len);
- if (err)
- goto scan_out;
-
err = brcmf_do_escan(vif->ifp, request);
if (err)
goto scan_out;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 9ac0d8c73d5a..9ec232e3dfe8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -894,7 +894,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wiphy,
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_p2p_info *p2p = &cfg->p2p;
- int err;
+ int err = 0;
if (brcmf_p2p_scan_is_p2p_request(request)) {
/* find my listen channel */
@@ -915,7 +915,9 @@ int brcmf_p2p_scan_prep(struct wiphy *wiphy,
/* override .run_escan() callback. */
cfg->escan_info.run = brcmf_p2p_run_escan;
}
- return 0;
+ err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
+ request->ie, request->ie_len);
+ return err;
}
--
2.17.1

View File

@@ -0,0 +1,104 @@
From c645a63417f552da7d1148a8677a1ed3a266bc91 Mon Sep 17 00:00:00 2001
From: Double Lo <double.lo@cypress.com>
Date: Wed, 26 Feb 2020 04:21:22 -0600
Subject: [PATCH 032/179] brcmfmac: add 54591 PCIE device
Support 54591 PCIE device.
Signed-off-by: Double Lo <double.lo@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/pcie.c | 22 +++++++++++++++++--
.../broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index bba41b191865..1df58eb9d83e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -61,6 +61,7 @@ BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
BRCMF_FW_DEF(4355, "brcmfmac89459-pcie");
+BRCMF_FW_DEF(54591, "brcmfmac54591-pcie");
/* firmware config files */
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt");
@@ -90,6 +91,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
BRCMF_FW_ENTRY(CY_CC_89459_CHIP_ID, 0xFFFFFFFF, 4355),
+ BRCMF_FW_ENTRY(CY_CC_54591_CHIP_ID, 0xFFFFFFFF, 54591),
};
#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
@@ -1655,12 +1657,21 @@ static
int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
struct brcmf_fw_request *fwreq;
struct brcmf_fw_name fwnames[] = {
{ ext, fw_name },
};
+ u32 chip;
- fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev,
+ if (devinfo->ci->chip == CY_CC_89459_CHIP_ID &&
+ devinfo->pdev->device == CY_PCIE_54591_DEVICE_ID)
+ chip = CY_CC_54591_CHIP_ID;
+ else
+ chip = bus_if->chip;
+
+ fwreq = brcmf_fw_alloc_request(chip, bus_if->chiprev,
brcmf_pcie_fwnames,
ARRAY_SIZE(brcmf_pcie_fwnames),
fwnames, ARRAY_SIZE(fwnames));
@@ -2102,8 +2113,14 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
{ ".bin", devinfo->fw_name },
{ ".txt", devinfo->nvram_name },
};
+ u32 chip;
- fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev,
+ if (devinfo->ci->chip == CY_CC_89459_CHIP_ID &&
+ devinfo->pdev->device == CY_PCIE_54591_DEVICE_ID)
+ chip = CY_CC_54591_CHIP_ID;
+ else
+ chip = devinfo->ci->chip;
+ fwreq = brcmf_fw_alloc_request(chip, devinfo->ci->chiprev,
brcmf_pcie_fwnames,
ARRAY_SIZE(brcmf_pcie_fwnames),
fwnames, ARRAY_SIZE(fwnames));
@@ -2388,6 +2405,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4371_DEVICE_ID),
BRCMF_PCIE_DEVICE(CY_PCIE_89459_DEVICE_ID),
BRCMF_PCIE_DEVICE(CY_PCIE_89459_RAW_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(CY_PCIE_54591_DEVICE_ID),
{ /* end: all zeroes */ }
};
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index b553470b4997..6f35cfd7b16c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -54,6 +54,7 @@
#define CY_CC_43012_CHIP_ID 43012
#define CY_CC_43752_CHIP_ID 43752
#define CY_CC_89459_CHIP_ID 0x4355
+#define CY_CC_54591_CHIP_ID 0x54591
/* USB Device IDs */
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
@@ -89,6 +90,7 @@
#define BRCM_PCIE_4371_DEVICE_ID 0x440d
#define CY_PCIE_89459_DEVICE_ID 0x4415
#define CY_PCIE_89459_RAW_DEVICE_ID 0x4355
+#define CY_PCIE_54591_DEVICE_ID 0x4417
/* brcmsmac IDs */
#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
--
2.17.1

View File

@@ -0,0 +1,737 @@
From 51033313d8c04180fd7260d95a9d61d7eadd5f52 Mon Sep 17 00:00:00 2001
From: Praveen Babu C <pucn@cypress.com>
Date: Tue, 9 Jan 2018 11:33:10 +0530
Subject: [PATCH 033/179] non-upstream: support DS1 exit firmware re-download
In deep sleep mode (DS1) ARM is off and once exit trigger comes than
mailbox Interrupt comes to host and whole reinitiation should be done
in the ARM to start TX/RX.
Also fix below issus for DS1 exit:
1. Sent Tx Control frame only after firmware redownload complete (check
F2 Ready before sending Tx Control frame to Firmware)
2. intermittent High DS1 TX Exit latency time (almost 3sec) ==> This is
fixed by skipping host Mailbox interrupt Multiple times (ulp state
mechanism)
3. RX GlOM save/restore in Firmware
4. Add ULP event enable & event_msgs_ext iovar configuration in FMAC
5. Add ULP_EVENT_RECV state machine for sbwad support
6. Support 2 Byte Shared memory read for DS1 Exit HUDI implementation
Signed-off-by: Praveen Babu C <pucn@cypress.com>
Signed-off-by: Naveen Gupta <nagu@cypress.com>
[Merge from 4.14.77 to 5.4.18; set BRCMF_SDIO_MAX_ACCESS_ERRORS to 20]
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/bus.h | 2 +-
.../broadcom/brcm80211/brcmfmac/common.c | 39 +++
.../broadcom/brcm80211/brcmfmac/core.c | 13 +-
.../broadcom/brcm80211/brcmfmac/debug.h | 1 +
.../broadcom/brcm80211/brcmfmac/fweh.h | 27 +-
.../broadcom/brcm80211/brcmfmac/pcie.c | 2 +-
.../broadcom/brcm80211/brcmfmac/sdio.c | 259 +++++++++++++++++-
.../broadcom/brcm80211/brcmfmac/sdio.h | 110 ++++++++
.../broadcom/brcm80211/brcmfmac/usb.c | 4 +-
.../broadcom/brcm80211/include/chipcommon.h | 2 +
10 files changed, 442 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index 968d3e75147d..d2863bcf7f94 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -256,7 +256,7 @@ void brcmf_rx_event(struct device *dev, struct sk_buff *rxp);
int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings);
/* Indication from bus module regarding presence/insertion of dongle. */
-int brcmf_attach(struct device *dev);
+int brcmf_attach(struct device *dev, bool start_bus);
/* Indication from bus module regarding removal/absence of dongle */
void brcmf_detach(struct device *dev);
void brcmf_free(struct device *dev);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 2a8cb5c958cf..6f12d03fb62c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -21,6 +21,8 @@
#include "firmware.h"
#include "chip.h"
#include "defs.h"
+#include "fweh.h"
+#include <brcm_hw_ids.h>
MODULE_AUTHOR("Broadcom Corporation");
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -214,6 +216,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
char *clmver;
char *ptr;
s32 err;
+ struct eventmsgs_ext *eventmask_msg = NULL;
+ u8 msglen;
/* retrieve mac addresses */
err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
@@ -334,6 +338,41 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
goto done;
}
+ /* Enable event_msg_ext specific to 43012 chip */
+ if (bus->chip == CY_CC_43012_CHIP_ID) {
+ /* Program event_msg_ext to support event larger than 128 */
+ msglen = (roundup(BRCMF_E_LAST, NBBY) / NBBY) +
+ EVENTMSGS_EXT_STRUCT_SIZE;
+ /* Allocate buffer for eventmask_msg */
+ eventmask_msg = kzalloc(msglen, GFP_KERNEL);
+ if (!eventmask_msg) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ /* Read the current programmed event_msgs_ext */
+ eventmask_msg->ver = EVENTMSGS_VER;
+ eventmask_msg->len = roundup(BRCMF_E_LAST, NBBY) / NBBY;
+ err = brcmf_fil_iovar_data_get(ifp, "event_msgs_ext",
+ eventmask_msg,
+ msglen);
+
+ /* Enable ULP event */
+ brcmf_dbg(EVENT, "enable event ULP\n");
+ setbit(eventmask_msg->mask, BRCMF_E_ULP);
+
+ /* Write updated Event mask */
+ eventmask_msg->ver = EVENTMSGS_VER;
+ eventmask_msg->command = EVENTMSGS_SET_MASK;
+ eventmask_msg->len = (roundup(BRCMF_E_LAST, NBBY) / NBBY);
+
+ err = brcmf_fil_iovar_data_set(ifp, "event_msgs_ext",
+ eventmask_msg, msglen);
+ if (err) {
+ brcmf_err("Set event_msgs_ext error (%d)\n", err);
+ goto done;
+ }
+ }
/* Setup default scan channel time */
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
BRCMF_DEFAULT_SCAN_CHANNEL_TIME);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index ff47d393fa4e..e2427d140b20 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1333,7 +1333,7 @@ int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings)
return 0;
}
-int brcmf_attach(struct device *dev)
+int brcmf_attach(struct device *dev, bool start_bus)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
@@ -1364,10 +1364,13 @@ int brcmf_attach(struct device *dev)
/* attach firmware event handler */
brcmf_fweh_attach(drvr);
- ret = brcmf_bus_started(drvr, drvr->ops);
- if (ret != 0) {
- bphy_err(drvr, "dongle is not responding: err=%d\n", ret);
- goto fail;
+ if (start_bus) {
+ ret = brcmf_bus_started(drvr, drvr->ops);
+ if (ret != 0) {
+ bphy_err(drvr, "dongle is not responding: err=%d\n",
+ ret);
+ goto fail;
+ }
}
return 0;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
index 169222d52fa0..d536bb99acc2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
@@ -29,6 +29,7 @@
#define BRCMF_MSGBUF_VAL 0x00040000
#define BRCMF_PCIE_VAL 0x00080000
#define BRCMF_FWCON_VAL 0x00100000
+#define BRCMF_ULP_VAL 0x00200000
/* set default print format */
#undef pr_fmt
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
index f692933e2348..09cca13b860f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
@@ -91,7 +91,8 @@ struct brcmf_cfg80211_info;
BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
BRCMF_ENUM_DEF(PHY_TEMP, 111) \
- BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
+ BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \
+ BRCMF_ENUM_DEF(ULP, 146)
#define BRCMF_ENUM_DEF(id, val) \
BRCMF_E_##id = (val),
@@ -103,7 +104,7 @@ enum brcmf_fweh_event_code {
* minimum length check in device firmware so it is
* hard-coded here.
*/
- BRCMF_E_LAST = 139
+ BRCMF_E_LAST = 147
};
#undef BRCMF_ENUM_DEF
@@ -284,6 +285,28 @@ struct brcmf_if_event {
u8 role;
};
+enum event_msgs_ext_command {
+ EVENTMSGS_NONE = 0,
+ EVENTMSGS_SET_BIT = 1,
+ EVENTMSGS_RESET_BIT = 2,
+ EVENTMSGS_SET_MASK = 3
+};
+
+#define EVENTMSGS_VER 1
+#define EVENTMSGS_EXT_STRUCT_SIZE offsetof(struct eventmsgs_ext, mask[0])
+
+/* len- for SET it would be mask size from the application to the firmware */
+/* for GET it would be actual firmware mask size */
+/* maxgetsize - is only used for GET. indicate max mask size that the */
+/* application can read from the firmware */
+struct eventmsgs_ext {
+ u8 ver;
+ u8 command;
+ u8 len;
+ u8 maxgetsize;
+ u8 mask[1];
+};
+
typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
const struct brcmf_event_msg *evtmsg,
void *data);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 1df58eb9d83e..f793fce879d2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -2093,7 +2093,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
init_waitqueue_head(&devinfo->mbdata_resp_wait);
- ret = brcmf_attach(&devinfo->pdev->dev);
+ ret = brcmf_attach(&devinfo->pdev->dev, true);
if (ret)
goto fail;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 77cc05d9a33d..cdbb2fdb8a9b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -35,9 +35,11 @@
#include "core.h"
#include "common.h"
#include "bcdc.h"
+#include "fwil.h"
#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
+#define ULP_HUDI_PROC_DONE_TIME msecs_to_jiffies(2500)
/* watermark expressed in number of words */
#define DEFAULT_F2_WATERMARK 0x8
@@ -327,7 +329,16 @@ struct rte_console {
#define KSO_WAIT_US 50
#define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US)
-#define BRCMF_SDIO_MAX_ACCESS_ERRORS 5
+#define BRCMF_SDIO_MAX_ACCESS_ERRORS 20
+
+static void brcmf_sdio_firmware_callback(struct device *dev, int err,
+ struct brcmf_fw_request *fwreq);
+static struct brcmf_fw_request *
+ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus);
+static int brcmf_sdio_f2_ready(struct brcmf_sdio *bus);
+static int brcmf_ulp_event_notify(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *evtmsg,
+ void *data);
#ifdef DEBUG
/* Device console log buffer state */
@@ -1103,7 +1114,7 @@ static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
}
#endif /* DEBUG */
-static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
+static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus, u32 *hmbd)
{
struct brcmf_sdio_dev *sdiod = bus->sdiodev;
struct brcmf_core *core = bus->sdio_core;
@@ -1192,6 +1203,9 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK))
brcmf_err("Unknown mailbox data content: 0x%02x\n",
hmb_data);
+ /* Populate hmb_data if argument is passed for DS1 check later */
+ if (hmbd)
+ *hmbd = hmb_data;
return intstatus;
}
@@ -2578,6 +2592,182 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
return ret;
}
+/* This Function is used to retrieve important
+ * details from dongle related to ULP mode Mostly
+ * values/SHM details that will be vary depending
+ * on the firmware branches
+ */
+static void
+brcmf_sdio_ulp_preinit(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+ struct brcmf_if *ifp = bus_if->drvr->iflist[0];
+
+ brcmf_dbg(ULP, "Enter\n");
+
+ /* Query ulp_sdioctrl iovar to get the ULP related SHM offsets */
+ brcmf_fil_iovar_data_get(ifp, "ulp_sdioctrl",
+ &sdiodev->fmac_ulp.ulp_shm_offset,
+ sizeof(sdiodev->fmac_ulp.ulp_shm_offset));
+
+ sdiodev->ulp = false;
+
+ brcmf_dbg(ULP, "m_ulp_ctrl_sdio[%x] m_ulp_wakeevt_ind [%x]\n",
+ M_DS1_CTRL_SDIO(sdiodev->fmac_ulp),
+ M_WAKEEVENT_IND(sdiodev->fmac_ulp));
+ brcmf_dbg(ULP, "m_ulp_wakeind [%x]\n",
+ M_ULP_WAKE_IND(sdiodev->fmac_ulp));
+}
+
+/* Reinitialize ARM because In DS1 mode ARM got off */
+static int
+brcmf_sdio_ulp_reinit_fw(struct brcmf_sdio *bus)
+{
+ struct brcmf_sdio_dev *sdiodev = bus->sdiodev;
+ struct brcmf_fw_request *fwreq;
+ int err = 0;
+
+ /* After firmware redownload tx/rx seq are reset accordingly
+ * these values are reset on FMAC side tx_max is initially set to 4,
+ * which later is updated by FW.
+ */
+ bus->tx_seq = 0;
+ bus->rx_seq = 0;
+ bus->tx_max = 4;
+
+ fwreq = brcmf_sdio_prepare_fw_request(bus);
+ if (!fwreq)
+ return -ENOMEM;
+
+ err = brcmf_fw_get_firmwares(sdiodev->dev, fwreq,
+ brcmf_sdio_firmware_callback);
+ if (err != 0) {
+ brcmf_err("async firmware request failed: %d\n", err);
+ kfree(fwreq);
+ }
+
+ return err;
+}
+
+/* Check if device is in DS1 mode and handshake with ULP UCODE */
+static bool
+brcmf_sdio_ulp_pre_redownload_check(struct brcmf_sdio *bus, u32 hmb_data)
+{
+ struct brcmf_sdio_dev *sdiod = bus->sdiodev;
+ int err = 0;
+ u32 value = 0;
+ u32 val32, ulp_wake_ind, wowl_wake_ind;
+ int reg_addr;
+ unsigned long timeout;
+ struct brcmf_ulp *fmac_ulp = &bus->sdiodev->fmac_ulp;
+ int i = 0;
+
+ /* If any host mail box data is present, ignore DS1 exit sequence */
+ if (hmb_data)
+ return false;
+ /* Skip if DS1 Exit is already in progress
+ * This can happen if firmware download is taking more time
+ */
+ if (fmac_ulp->ulp_state == FMAC_ULP_TRIGGERED)
+ return false;
+
+ value = brcmf_sdiod_func0_rb(sdiod, SDIO_CCCR_IOEx, &err);
+
+ if (value == SDIO_FUNC_ENABLE_1) {
+ brcmf_dbg(ULP, "GOT THE INTERRUPT FROM UCODE\n");
+ sdiod->ulp = true;
+ fmac_ulp->ulp_state = FMAC_ULP_TRIGGERED;
+ ulp_wake_ind = D11SHM_RDW(sdiod,
+ M_ULP_WAKE_IND(sdiod->fmac_ulp),
+ &err);
+ wowl_wake_ind = D11SHM_RDW(sdiod,
+ M_WAKEEVENT_IND(sdiod->fmac_ulp),
+ &err);
+
+ brcmf_dbg(ULP, "wowl_wake_ind: 0x%08x, ulp_wake_ind: 0x%08x state %s\n",
+ wowl_wake_ind, ulp_wake_ind, (fmac_ulp->ulp_state) ?
+ "DS1 Exit Triggered" : "IDLE State");
+
+ if (wowl_wake_ind || ulp_wake_ind) {
+ /* RX wake Don't do anything.
+ * Just bail out and re-download firmware.
+ */
+ /* Print out PHY TX error block when bit 9 set */
+ if ((ulp_wake_ind & C_DS1_PHY_TXERR) &&
+ M_DS1_PHYTX_ERR_BLK(sdiod->fmac_ulp)) {
+ brcmf_err("Dump PHY TX Error SHM Locations\n");
+ for (i = 0; i < PHYTX_ERR_BLK_SIZE; i++) {
+ pr_err("0x%x",
+ D11SHM_RDW(sdiod,
+ (M_DS1_PHYTX_ERR_BLK(sdiod->fmac_ulp) +
+ (i * 2)), &err));
+ }
+ brcmf_err("\n");
+ }
+ } else {
+ /* TX wake negotiate with MAC */
+ brcmf_dbg(ULP, "M_DS1_CTRL_SDIO: 0x%08x\n",
+ (u32)D11SHM_RDW(sdiod,
+ M_DS1_CTRL_SDIO(sdiod->fmac_ulp),
+ &err));
+ val32 = D11SHM_RD(sdiod,
+ M_DS1_CTRL_SDIO(sdiod->fmac_ulp),
+ &err);
+ D11SHM_WR(sdiod, M_DS1_CTRL_SDIO(sdiod->fmac_ulp),
+ val32, (C_DS1_CTRL_SDIO_DS1_EXIT |
+ C_DS1_CTRL_REQ_VALID), &err);
+ val32 = D11REG_RD(sdiod, D11_MACCONTROL_REG, &err);
+ val32 = val32 | D11_MACCONTROL_REG_WAKE;
+ D11REG_WR(sdiod, D11_MACCONTROL_REG, val32, &err);
+
+ /* Poll for PROC_DONE to be set by ucode */
+ value = D11SHM_RDW(sdiod,
+ M_DS1_CTRL_SDIO(sdiod->fmac_ulp),
+ &err);
+ /* Wait here (polling) for C_DS1_CTRL_PROC_DONE */
+ timeout = jiffies + ULP_HUDI_PROC_DONE_TIME;
+ while (!(value & C_DS1_CTRL_PROC_DONE)) {
+ value = D11SHM_RDW(sdiod,
+ M_DS1_CTRL_SDIO(sdiod->fmac_ulp),
+ &err);
+ if (time_after(jiffies, timeout))
+ break;
+ usleep_range(1000, 2000);
+ }
+ brcmf_dbg(ULP, "M_DS1_CTRL_SDIO: 0x%08x\n",
+ (u32)D11SHM_RDW(sdiod,
+ M_DS1_CTRL_SDIO(sdiod->fmac_ulp), &err));
+ value = D11SHM_RDW(sdiod,
+ M_DS1_CTRL_SDIO(sdiod->fmac_ulp),
+ &err);
+ if (!(value & C_DS1_CTRL_PROC_DONE)) {
+ brcmf_err("Timeout Failed to enter DS1 Exit state!\n");
+ return false;
+ }
+ }
+
+ ulp_wake_ind = D11SHM_RDW(sdiod,
+ M_ULP_WAKE_IND(sdiod->fmac_ulp),
+ &err);
+ wowl_wake_ind = D11SHM_RDW(sdiod,
+ M_WAKEEVENT_IND(sdiod->fmac_ulp),
+ &err);
+ brcmf_dbg(ULP, "wowl_wake_ind: 0x%08x, ulp_wake_ind: 0x%08x\n",
+ wowl_wake_ind, ulp_wake_ind);
+ reg_addr = CORE_CC_REG(
+ brcmf_chip_get_pmu(bus->ci)->base, min_res_mask);
+ brcmf_sdiod_writel(sdiod, reg_addr,
+ DEFAULT_43012_MIN_RES_MASK, &err);
+ if (err)
+ brcmf_err("min_res_mask failed\n");
+
+ return true;
+ }
+
+ return false;
+}
+
static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
{
struct brcmf_sdio_dev *sdiod = bus->sdiodev;
@@ -2649,8 +2839,11 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
/* Handle host mailbox indication */
if (intstatus & I_HMB_HOST_INT) {
+ u32 hmb_data = 0;
intstatus &= ~I_HMB_HOST_INT;
- intstatus |= brcmf_sdio_hostmail(bus);
+ intstatus |= brcmf_sdio_hostmail(bus, &hmb_data);
+ if (brcmf_sdio_ulp_pre_redownload_check(bus, hmb_data))
+ brcmf_sdio_ulp_reinit_fw(bus);
}
sdio_release_host(bus->sdiodev->func1);
@@ -2695,7 +2888,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
brcmf_sdio_clrintr(bus);
if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
- txctl_ok(bus)) {
+ txctl_ok(bus) && brcmf_sdio_f2_ready(bus)) {
sdio_claim_host(bus->sdiodev->func1);
if (bus->ctrl_frame_stat) {
err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
@@ -3566,6 +3759,10 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
if (err < 0)
goto done;
+ /* initialize SHM address from firmware for DS1 */
+ if (!bus->sdiodev->ulp)
+ brcmf_sdio_ulp_preinit(dev);
+
bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
if (sdiodev->sg_support) {
bus->txglom = false;
@@ -4211,7 +4408,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
u8 saveclk, bpreq;
u8 devctl;
- brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
+ brcmf_dbg(ULP, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
if (err)
goto fail;
@@ -4387,12 +4584,25 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
}
/* Attach to the common layer, reserve hdr space */
- err = brcmf_attach(sdiod->dev);
+ err = brcmf_attach(sdiod->dev, !bus->sdiodev->ulp);
if (err != 0) {
brcmf_err("brcmf_attach failed\n");
goto free;
}
+ /* Register for ULP events */
+ if (sdiod->func1->device == SDIO_DEVICE_ID_BROADCOM_CYPRESS_43012)
+ brcmf_fweh_register(bus_if->drvr, BRCMF_E_ULP,
+ brcmf_ulp_event_notify);
+
+ if (bus->sdiodev->ulp) {
+ /* For ULP, after firmware redownload complete
+ * set ULP state to IDLE
+ */
+ if (bus->sdiodev->fmac_ulp.ulp_state == FMAC_ULP_TRIGGERED)
+ bus->sdiodev->fmac_ulp.ulp_state = FMAC_ULP_IDLE;
+ }
+
/* ready */
return;
@@ -4636,3 +4846,40 @@ int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep)
return ret;
}
+
+/* Check F2 Ready bit before sending data to Firmware */
+static int
+brcmf_sdio_f2_ready(struct brcmf_sdio *bus)
+{
+ int ret = -1;
+ int iordy_status = 0;
+
+ sdio_claim_host(bus->sdiodev->func1);
+ /* Read the status of IOR2 */
+ iordy_status = brcmf_sdiod_func0_rb(bus->sdiodev, SDIO_CCCR_IORx, NULL);
+
+ sdio_release_host(bus->sdiodev->func1);
+ ret = iordy_status & SDIO_FUNC_ENABLE_2;
+ return ret;
+}
+
+static int brcmf_ulp_event_notify(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *evtmsg,
+ void *data)
+{
+ int err = 0;
+ struct brcmf_bus *bus_if = ifp->drvr->bus_if;
+ struct brcmf_sdio_dev *sdiodev;
+ struct brcmf_sdio *bus;
+ struct brcmf_ulp_event *ulp_event = (struct brcmf_ulp_event *)data;
+
+ sdiodev = bus_if->bus_priv.sdio;
+ bus = sdiodev->bus;
+
+ brcmf_dbg(ULP, "Chip went to DS1 state : action %d\n",
+ ulp_event->ulp_dongle_action);
+ if (ulp_event->ulp_dongle_action == FMAC_ULP_ENTRY)
+ bus->sdiodev->fmac_ulp.ulp_state = FMAC_ULP_ENTRY_RECV;
+
+ return err;
+}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 15d2c02fa3ec..ce52692adbc9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -165,6 +165,35 @@ struct brcmf_sdreg {
struct brcmf_sdio;
struct brcmf_sdiod_freezer;
+/* ULP SHM Offsets info */
+struct ulp_shm_info {
+ u32 m_ulp_ctrl_sdio;
+ u32 m_ulp_wakeevt_ind;
+ u32 m_ulp_wakeind;
+ u32 m_ulp_phytxblk;
+};
+
+/* FMAC ULP state machine */
+#define FMAC_ULP_IDLE (0)
+#define FMAC_ULP_ENTRY_RECV (1)
+#define FMAC_ULP_TRIGGERED (2)
+
+/* BRCMF_E_ULP event data */
+#define FMAC_ULP_EVENT_VERSION 1
+#define FMAC_ULP_DISABLE_CONSOLE 1 /* Disable console */
+#define FMAC_ULP_UCODE_DOWNLOAD 2 /* Download ULP ucode file */
+#define FMAC_ULP_ENTRY 3 /* Inform ulp entry to Host */
+
+struct brcmf_ulp {
+ uint ulp_state;
+ struct ulp_shm_info ulp_shm_offset;
+};
+
+struct brcmf_ulp_event {
+ u16 version;
+ u16 ulp_dongle_action;
+};
+
struct brcmf_sdio_dev {
struct sdio_func *func1;
struct sdio_func *func2;
@@ -189,6 +218,8 @@ struct brcmf_sdio_dev {
bool wowl_enabled;
enum brcmf_sdiod_state state;
struct brcmf_sdiod_freezer *freezer;
+ struct brcmf_ulp fmac_ulp;
+ bool ulp;
};
/* sdio core registers */
@@ -379,4 +410,83 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled);
int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep);
void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus);
+/* SHM offsets */
+#define M_DS1_CTRL_SDIO(ptr) ((ptr).ulp_shm_offset.m_ulp_ctrl_sdio)
+#define M_WAKEEVENT_IND(ptr) ((ptr).ulp_shm_offset.m_ulp_wakeevt_ind)
+#define M_ULP_WAKE_IND(ptr) ((ptr).ulp_shm_offset.m_ulp_wakeind)
+#define M_DS1_PHYTX_ERR_BLK(ptr) ((ptr).ulp_shm_offset.m_ulp_phytxblk)
+
+#define D11_BASE_ADDR 0x18001000
+#define D11_AXI_BASE_ADDR 0xE8000000
+#define D11_SHM_BASE_ADDR (D11_AXI_BASE_ADDR + 0x4000)
+
+#define D11REG_ADDR(offset) (D11_BASE_ADDR + (offset))
+#define D11IHR_ADDR(offset) (D11_AXI_BASE_ADDR + 0x400 + (2 * (offset)))
+#define D11SHM_ADDR(offset) (D11_SHM_BASE_ADDR + (offset))
+
+/* MacControl register */
+#define D11_MACCONTROL_REG D11REG_ADDR(0x120)
+#define D11_MACCONTROL_REG_WAKE 0x4000000
+
+/* HUDI Sequence SHM bits */
+#define C_DS1_CTRL_SDIO_DS1_SLEEP 0x1
+#define C_DS1_CTRL_SDIO_MAC_ON 0x2
+#define C_DS1_CTRL_SDIO_RADIO_PHY_ON 0x4
+#define C_DS1_CTRL_SDIO_DS1_EXIT 0x8
+#define C_DS1_CTRL_PROC_DONE 0x100
+#define C_DS1_CTRL_REQ_VALID 0x200
+
+/* M_ULP_WAKEIND bits */
+#define C_WATCHDOG_EXPIRY BIT(0)
+#define C_FCBS_ERROR BIT(1)
+#define C_RETX_FAILURE BIT(2)
+#define C_HOST_WAKEUP BIT(3)
+#define C_INVALID_FCBS_BLOCK BIT(4)
+#define C_HUDI_DS1_EXIT BIT(5)
+#define C_LOB_SLEEP BIT(6)
+#define C_DS1_PHY_TXERR BIT(9)
+#define C_DS1_WAKE_TIMER BIT(10)
+
+#define PHYTX_ERR_BLK_SIZE 18
+#define D11SHM_FIRST2BYTE_MASK 0xFFFF0000
+#define D11SHM_SECOND2BYTE_MASK 0x0000FFFF
+#define D11SHM_2BYTE_SHIFT 16
+
+#define D11SHM_RD(sdh, offset, ret) \
+ brcmf_sdiod_readl(sdh, D11SHM_ADDR(offset), ret)
+
+/* SHM Read is motified based on SHM 4 byte alignment as SHM size is 2 bytes and
+ * 2 byte is currently not working on FMAC
+ * If SHM address is not 4 byte aligned, then right shift by 16
+ * otherwise, mask the first two MSB bytes
+ * Suppose data in address 7260 is 0x440002 and it is 4 byte aligned
+ * Correct SHM value is 0x2 for this SHM offset and next SHM value is 0x44
+ */
+#define D11SHM_RDW(sdh, offset, ret) \
+ ((offset % 4) ? \
+ (brcmf_sdiod_readl(sdh, D11SHM_ADDR(offset), ret) \
+ >> D11SHM_2BYTE_SHIFT) : \
+ (brcmf_sdiod_readl(sdh, D11SHM_ADDR(offset), ret) \
+ & D11SHM_SECOND2BYTE_MASK))
+
+/* SHM is of size 2 bytes, 4 bytes write will overwrite other SHM's
+ * First read 4 bytes and then clear the required two bytes based on
+ * 4 byte alignment, then update the required value and write the
+ * 4 byte value now
+ */
+#define D11SHM_WR(sdh, offset, val, mask, ret) \
+ do { \
+ if ((offset) % 4) \
+ val = (val & D11SHM_SECOND2BYTE_MASK) | \
+ ((mask) << D11SHM_2BYTE_SHIFT); \
+ else \
+ val = (mask) | (val & D11SHM_FIRST2BYTE_MASK); \
+ brcmf_sdiod_writel(sdh, D11SHM_ADDR(offset), val, ret); \
+ } while (0)
+#define D11REG_WR(sdh, addr, val, ret) \
+ brcmf_sdiod_writel(sdh, addr, val, ret)
+
+#define D11REG_RD(sdh, addr, ret) \
+ brcmf_sdiod_readl(sdh, addr, ret)
+
#endif /* BRCMFMAC_SDIO_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 5aa6b43f0c53..9b592094609c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -1228,7 +1228,7 @@ static void brcmf_usb_probe_phase2(struct device *dev, int ret,
}
/* Attach to the common driver interface */
- ret = brcmf_attach(devinfo->dev);
+ ret = brcmf_attach(devinfo->dev, true);
if (ret)
goto error;
@@ -1310,7 +1310,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
goto fail;
}
- ret = brcmf_attach(devinfo->dev);
+ ret = brcmf_attach(devinfo->dev, true);
if (ret)
goto fail;
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h b/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
index 0340bba96868..090a75bcd728 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
@@ -308,4 +308,6 @@ struct chipcregs {
*/
#define PMU_MAX_TRANSITION_DLY 15000
+#define DEFAULT_43012_MIN_RES_MASK 0x0f8bfe77
+
#endif /* _SBCHIPC_H */
--
2.17.1

View File

@@ -0,0 +1,455 @@
From dee67966f2eda27fa16f3e991b402a511c1845ed Mon Sep 17 00:00:00 2001
From: Nitin Bhaskar <niti@cypress.com>
Date: Tue, 21 Aug 2018 16:03:10 +0530
Subject: [PATCH 034/179] non-upstream: fix 43012 insmod-after-rmmod in DS1
failure
After entering ULP, issuing rmmod does not put chip in
sane state because of which next insmod fails.
Fix includes writing into few LHL, PMU registers.
Signed-off-by: Nitin Bhaskar <niti@cypress.com>
[Merge from 4.14.77 to 5.4.18]
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/chip.c | 155 ++++++++++++++
.../broadcom/brcm80211/brcmfmac/chip.h | 9 +-
.../broadcom/brcm80211/brcmfmac/sdio.c | 14 +-
.../broadcom/brcm80211/include/chipcommon.h | 193 +++++++++++++++++-
4 files changed, 367 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 9dff0dacd5e7..d9b6b116a78d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -215,6 +215,18 @@ struct sbsocramregs {
#define ARMCR4_BSZ_MASK 0x3f
#define ARMCR4_BSZ_MULT 8192
+/* Minimum PMU resource mask for 43012C0 */
+#define CY_43012_PMU_MIN_RES_MASK 0xF8BFE77
+
+/* PMU STATUS mask for 43012C0 */
+#define CY_43012_PMU_STATUS_MASK 0x1AC
+
+/* PMU CONTROL EXT mask for 43012C0 */
+#define CY_43012_PMU_CONTROL_EXT_MASK 0x11
+
+/* PMU CONTROL EXT mask for 43012C0 */
+#define CY_43012_PMU_WATCHDOG_TICK_VAL 0x04
+
struct brcmf_core_priv {
struct brcmf_core pub;
u32 wrapbase;
@@ -1218,6 +1230,14 @@ struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub)
return cc;
}
+struct brcmf_core *brcmf_chip_get_gci(struct brcmf_chip *pub)
+{
+ struct brcmf_core *gci;
+
+ gci = brcmf_chip_get_core(pub, BCMA_CORE_GCI);
+ return gci;
+}
+
bool brcmf_chip_iscoreup(struct brcmf_core *pub)
{
struct brcmf_core_priv *core;
@@ -1444,3 +1464,138 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
}
}
+
+void brcmf_chip_reset_pmu_regs(struct brcmf_chip *pub)
+{
+ struct brcmf_chip_priv *chip;
+ u32 addr;
+ u32 base;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+ chip = container_of(pub, struct brcmf_chip_priv, pub);
+ base = brcmf_chip_get_pmu(pub)->base;
+
+ switch (pub->chip) {
+ case CY_CC_43012_CHIP_ID:
+ /* SW scratch */
+ addr = CORE_CC_REG(base, swscratch);
+ chip->ops->write32(chip->ctx, addr, 0);
+
+ /* PMU status */
+ addr = CORE_CC_REG(base, pmustatus);
+ chip->ops->write32(chip->ctx, addr,
+ CY_43012_PMU_STATUS_MASK);
+
+ /* PMU control ext */
+ addr = CORE_CC_REG(base, pmucontrol_ext);
+ chip->ops->write32(chip->ctx, addr,
+ CY_43012_PMU_CONTROL_EXT_MASK);
+
+ /* PMU watchdog */
+ addr = CORE_CC_REG(base, pmuwatchdog);
+ chip->ops->write32(chip->ctx, addr,
+ CY_43012_PMU_WATCHDOG_TICK_VAL);
+ break;
+
+ default:
+ brcmf_err("Unsupported chip id\n");
+ break;
+ }
+}
+
+void brcmf_chip_set_default_min_res_mask(struct brcmf_chip *pub)
+{
+ struct brcmf_chip_priv *chip;
+ u32 addr;
+ u32 base;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+ chip = container_of(pub, struct brcmf_chip_priv, pub);
+ base = brcmf_chip_get_pmu(pub)->base;
+ switch (pub->chip) {
+ case CY_CC_43012_CHIP_ID:
+ addr = CORE_CC_REG(base, min_res_mask);
+ chip->ops->write32(chip->ctx, addr,
+ CY_43012_PMU_MIN_RES_MASK);
+ break;
+
+ default:
+ brcmf_err("Unsupported chip id\n");
+ break;
+ }
+}
+
+void brcmf_chip_ulp_reset_lhl_regs(struct brcmf_chip *pub)
+{
+ struct brcmf_chip_priv *chip;
+ u32 base;
+ u32 addr;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+ chip = container_of(pub, struct brcmf_chip_priv, pub);
+ base = brcmf_chip_get_gci(pub)->base;
+
+ /* LHL Top Level Power Sequence Control */
+ addr = CORE_GCI_REG(base, lhl_top_pwrseq_ctl_adr);
+ chip->ops->write32(chip->ctx, addr, 0);
+
+ /* GPIO Interrupt Enable0 */
+ addr = CORE_GCI_REG(base, gpio_int_en_port_adr[0]);
+ chip->ops->write32(chip->ctx, addr, 0);
+
+ /* GPIO Interrupt Status0 */
+ addr = CORE_GCI_REG(base, gpio_int_st_port_adr[0]);
+ chip->ops->write32(chip->ctx, addr, ~0);
+
+ /* WL ARM Timer0 Interrupt Mask */
+ addr = CORE_GCI_REG(base, lhl_wl_armtim0_intrp_adr);
+ chip->ops->write32(chip->ctx, addr, 0);
+
+ /* WL ARM Timer0 Interrupt Status */
+ addr = CORE_GCI_REG(base, lhl_wl_armtim0_st_adr);
+ chip->ops->write32(chip->ctx, addr, ~0);
+
+ /* WL ARM Timer */
+ addr = CORE_GCI_REG(base, lhl_wl_armtim0_adr);
+ chip->ops->write32(chip->ctx, addr, 0);
+
+ /* WL MAC Timer0 Interrupt Mask */
+ addr = CORE_GCI_REG(base, lhl_wl_mactim0_intrp_adr);
+ chip->ops->write32(chip->ctx, addr, 0);
+
+ /* WL MAC Timer0 Interrupt Status */
+ addr = CORE_GCI_REG(base, lhl_wl_mactim0_st_adr);
+ chip->ops->write32(chip->ctx, addr, ~0);
+
+ /* WL MAC TimerInt0 */
+ addr = CORE_GCI_REG(base, lhl_wl_mactim_int0_adr);
+ chip->ops->write32(chip->ctx, addr, 0x0);
+}
+
+void brcmf_chip_reset_watchdog(struct brcmf_chip *pub)
+{
+ struct brcmf_chip_priv *chip;
+ u32 base;
+ u32 addr;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+ chip = container_of(pub, struct brcmf_chip_priv, pub);
+ base = brcmf_chip_get_pmu(pub)->base;
+
+ switch (pub->chip) {
+ case CY_CC_43012_CHIP_ID:
+ /* Watchdog res mask */
+ addr = CORE_CC_REG(base, watchdog_res_mask);
+ chip->ops->write32(chip->ctx, addr,
+ CY_43012_PMU_MIN_RES_MASK);
+ break;
+
+ default:
+ break;
+ }
+}
+
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
index d69f101f5834..2ba72ec12675 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
@@ -8,7 +8,10 @@
#include <linux/types.h>
#define CORE_CC_REG(base, field) \
- (base + offsetof(struct chipcregs, field))
+ ((base) + offsetof(struct chipcregs, field))
+
+#define CORE_GCI_REG(base, field) \
+ ((base) + offsetof(struct chipgciregs, field))
/**
* struct brcmf_chip - chip level information.
@@ -88,5 +91,9 @@ bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec);
bool brcmf_chip_sr_capable(struct brcmf_chip *pub);
char *brcmf_chip_name(u32 chipid, u32 chiprev, char *buf, uint len);
u32 brcmf_chip_enum_base(u16 devid);
+void brcmf_chip_reset_watchdog(struct brcmf_chip *pub);
+void brcmf_chip_ulp_reset_lhl_regs(struct brcmf_chip *pub);
+void brcmf_chip_reset_pmu_regs(struct brcmf_chip *pub);
+void brcmf_chip_set_default_min_res_mask(struct brcmf_chip *pub);
#endif /* BRCMF_AXIDMP_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index cdbb2fdb8a9b..ce5f807be3d6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4791,7 +4791,19 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
* necessary cores.
*/
msleep(20);
- brcmf_chip_set_passive(bus->ci);
+ if (bus->sdiodev->fmac_ulp.ulp_state ==
+ FMAC_ULP_ENTRY_RECV) {
+ brcmf_chip_ulp_reset_lhl_regs(bus->ci);
+ brcmf_chip_reset_pmu_regs(bus->ci);
+ brcmf_chip_set_default_min_res_mask(
+ bus->ci);
+ } else {
+ brcmf_chip_set_passive(bus->ci);
+ }
+ /* Reset the PMU, backplane and all the
+ * cores by using the PMUWatchdogCounter.
+ */
+ brcmf_chip_reset_watchdog(bus->ci);
brcmf_sdio_clkctl(bus, CLK_NONE, false);
sdio_release_host(bus->sdiodev->func1);
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h b/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
index 090a75bcd728..39cd34c22628 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
@@ -214,8 +214,197 @@ struct chipcregs {
u32 PAD[3];
u32 retention_grpidx; /* 0x680 */
u32 retention_grpctl; /* 0x684 */
- u32 PAD[94];
- u16 sromotp[768];
+ u32 mac_res_req_timer; /* 0x688 */
+ u32 mac_res_req_mask; /* 0x68c */
+ u32 PAD[18];
+ u32 pmucontrol_ext; /* 0x6d8 */
+ u32 slowclkperiod; /* 0x6dc */
+ u32 PAD[8];
+ u32 pmuintmask0; /* 0x700 */
+ u32 pmuintmask1; /* 0x704 */
+ u32 PAD[14];
+ u32 pmuintstatus; /* 0x740 */
+ u32 extwakeupstatus; /* 0x744 */
+ u32 watchdog_res_mask; /* 0x748 */
+ u32 swscratch; /* 0x750 */
+ u32 PAD[3];
+ u32 extwakemask[2]; /* 0x760-0x764 */
+ u32 PAD[2];
+ u32 extwakereqmask[2]; /* 0x770-0x774 */
+ u32 PAD[2];
+ u32 pmuintctrl0; /* 0x780 */
+ u32 pmuintctrl1; /* 0x784 */
+ u32 PAD[2];
+ u32 extwakectrl[2]; /* 0x790 */
+};
+
+#define CHIPGCIREGOFFS(field) offsetof(struct chipgciregs, field)
+
+struct chipgciregs {
+ u32 gci_corecaps0; /* 0x000 */
+ u32 gci_corecaps1; /* 0x004 */
+ u32 gci_corecaps2; /* 0x008 */
+ u32 gci_corectrl; /* 0x00c */
+ u32 gci_corestat; /* 0x010 */
+ u32 gci_intstat; /* 0x014 */
+ u32 gci_intmask; /* 0x018 */
+ u32 gci_wakemask; /* 0x01c */
+ u32 gci_levelintstat; /* 0x020 */
+ u32 gci_eventintstat; /* 0x024 */
+ u32 gci_wakelevelintstat; /* 0x028 */
+ u32 gci_wakeeventintstat; /* 0x02c */
+ u32 semaphoreintstatus; /* 0x030 */
+ u32 semaphoreintmask; /* 0x034 */
+ u32 semaphorerequest; /* 0x038 */
+ u32 semaphorereserve; /* 0x03c */
+ u32 gci_indirect_addr; /* 0x040 */
+ u32 gci_gpioctl; /* 0x044 */
+ u32 gci_gpiostatus; /* 0x048 */
+ u32 gci_gpiomask; /* 0x04c */
+ u32 eventsummary; /* 0x050 */
+ u32 gci_miscctl; /* 0x054 */
+ u32 gci_gpiointmask; /* 0x058 */
+ u32 gci_gpiowakemask; /* 0x05c */
+ u32 gci_input[32]; /* 0x060 */
+ u32 gci_event[32]; /* 0x0e0 */
+ u32 gci_output[4]; /* 0x160 */
+ u32 gci_control_0; /* 0x170 */
+ u32 gci_control_1; /* 0x174 */
+ u32 gci_intpolreg; /* 0x178 */
+ u32 gci_levelintmask; /* 0x17c */
+ u32 gci_eventintmask; /* 0x180 */
+ u32 wakelevelintmask; /* 0x184 */
+ u32 wakeeventintmask; /* 0x188 */
+ u32 hwmask; /* 0x18c */
+ u32 PAD;
+ u32 gci_inbandeventintmask; /* 0x194 */
+ u32 PAD;
+ u32 gci_inbandeventstatus; /* 0x19c */
+ u32 gci_seciauxtx; /* 0x1a0 */
+ u32 gci_seciauxrx; /* 0x1a4 */
+ u32 gci_secitx_datatag; /* 0x1a8 */
+ u32 gci_secirx_datatag; /* 0x1ac */
+ u32 gci_secitx_datamask; /* 0x1b0 */
+ u32 gci_seciusef0tx_reg; /* 0x1b4 */
+ u32 gci_secif0tx_offset; /* 0x1b8 */
+ u32 gci_secif0rx_offset; /* 0x1bc */
+ u32 gci_secif1tx_offset; /* 0x1c0 */
+ u32 gci_rxfifo_common_ctrl; /* 0x1c4 */
+ u32 gci_rxfifoctrl; /* 0x1c8 */
+ u32 gci_hw_sema_status; /* 0x1cc */
+ u32 gci_seciuartescval; /* 0x1d0 */
+ u32 gic_seciuartautobaudctr; /* 0x1d4 */
+ u32 gci_secififolevel; /* 0x1d8 */
+ u32 gci_seciuartdata; /* 0x1dc */
+ u32 gci_secibauddiv; /* 0x1e0 */
+ u32 gci_secifcr; /* 0x1e4 */
+ u32 gci_secilcr; /* 0x1e8 */
+ u32 gci_secimcr; /* 0x1ec */
+ u32 gci_secilsr; /* 0x1f0 */
+ u32 gci_secimsr; /* 0x1f4 */
+ u32 gci_baudadj; /* 0x1f8 */
+ u32 gci_inbandintmask; /* 0x1fc */
+ u32 gci_chipctrl; /* 0x200 */
+ u32 gci_chipsts; /* 0x204 */
+ u32 gci_gpioout; /* 0x208 */
+ u32 gci_gpioout_read; /* 0x20C */
+ u32 gci_mpwaketx; /* 0x210 */
+ u32 gci_mpwakedetect; /* 0x214 */
+ u32 gci_seciin_ctrl; /* 0x218 */
+ u32 gci_seciout_ctrl; /* 0x21C */
+ u32 gci_seciin_auxfifo_en; /* 0x220 */
+ u32 gci_seciout_txen_txbr; /* 0x224 */
+ u32 gci_seciin_rxbrstatus; /* 0x228 */
+ u32 gci_seciin_rxerrstatus; /* 0x22C */
+ u32 gci_seciin_fcstatus; /* 0x230 */
+ u32 gci_seciout_txstatus; /* 0x234 */
+ u32 gci_seciout_txbrstatus; /* 0x238 */
+ u32 wlan_mem_info; /* 0x23C */
+ u32 wlan_bankxinfo; /* 0x240 */
+ u32 bt_smem_select; /* 0x244 */
+ u32 bt_smem_stby; /* 0x248 */
+ u32 bt_smem_status; /* 0x24C */
+ u32 wlan_bankxactivepda; /* 0x250 */
+ u32 wlan_bankxsleeppda; /* 0x254 */
+ u32 wlan_bankxkill; /* 0x258 */
+ u32 PAD[41];
+ u32 gci_chipid; /* 0x300 */
+ u32 PAD[3];
+ u32 otpstatus; /* 0x310 */
+ u32 otpcontrol; /* 0x314 */
+ u32 otpprog; /* 0x318 */
+ u32 otplayout; /* 0x31c */
+ u32 otplayoutextension; /* 0x320 */
+ u32 otpcontrol1; /* 0x324 */
+ u32 otpprogdata; /* 0x328 */
+ u32 PAD[52];
+ u32 otpECCstatus; /* 0x3FC */
+ u32 PAD[512];
+ u32 lhl_core_capab_adr; /* 0xC00 */
+ u32 lhl_main_ctl_adr; /* 0xC04 */
+ u32 lhl_pmu_ctl_adr; /* 0xC08 */
+ u32 lhl_extlpo_ctl_adr; /* 0xC0C */
+ u32 lpo_ctl_adr; /* 0xC10 */
+ u32 lhl_lpo2_ctl_adr; /* 0xC14 */
+ u32 lhl_osc32k_ctl_adr; /* 0xC18 */
+ u32 lhl_clk_status_adr; /* 0xC1C */
+ u32 lhl_clk_det_ctl_adr; /* 0xC20 */
+ u32 lhl_clk_sel_adr; /* 0xC24 */
+ u32 hidoff_cnt_adr[2]; /* 0xC28-0xC2C */
+ u32 lhl_autoclk_ctl_adr; /* 0xC30 */
+ u32 PAD;
+ u32 lhl_hibtim_adr; /* 0xC38 */
+ u32 lhl_wl_ilp_val_adr; /* 0xC3C */
+ u32 lhl_wl_armtim0_intrp_adr; /* 0xC40 */
+ u32 lhl_wl_armtim0_st_adr; /* 0xC44 */
+ u32 lhl_wl_armtim0_adr; /* 0xC48 */
+ u32 PAD[9];
+ u32 lhl_wl_mactim0_intrp_adr; /* 0xC70 */
+ u32 lhl_wl_mactim0_st_adr; /* 0xC74 */
+ u32 lhl_wl_mactim_int0_adr; /* 0xC78 */
+ u32 lhl_wl_mactim_frac0_adr; /* 0xC7C */
+ u32 lhl_wl_mactim1_intrp_adr; /* 0xC80 */
+ u32 lhl_wl_mactim1_st_adr; /* 0xC84 */
+ u32 lhl_wl_mactim_int1_adr; /* 0xC88 */
+ u32 lhl_wl_mactim_frac1_adr; /* 0xC8C */
+ u32 PAD[8];
+ u32 gpio_int_en_port_adr[4]; /* 0xCB0-0xCBC */
+ u32 gpio_int_st_port_adr[4]; /* 0xCC0-0xCCC */
+ u32 gpio_ctrl_iocfg_p_adr[64]; /* 0xCD0-0xDCC */
+ u32 gpio_gctrl_iocfg_p0_p39_adr; /* 0xDD0 */
+ u32 gpio_gdsctrl_iocfg_p0_p25_p30_p39_adr; /* 0xDD4 */
+ u32 gpio_gdsctrl_iocfg_p26_p29_adr; /* 0xDD8 */
+ u32 PAD[8];
+ u32 lhl_gpio_din0_adr; /* 0xDFC */
+ u32 lhl_gpio_din1_adr; /* 0xE00 */
+ u32 lhl_wkup_status_adr; /* 0xE04 */
+ u32 lhl_ctl_adr; /* 0xE08 */
+ u32 lhl_adc_ctl_adr; /* 0xE0C */
+ u32 lhl_qdxyz_in_dly_adr; /* 0xE10 */
+ u32 lhl_optctl_adr; /* 0xE14 */
+ u32 lhl_optct2_adr; /* 0xE18 */
+ u32 lhl_scanp_cntr_init_val_adr; /* 0xE1C */
+ u32 lhl_opt_togg_val_adr[6]; /* 0xE20-0xE34 */
+ u32 lhl_optx_smp_val_adr; /* 0xE38 */
+ u32 lhl_opty_smp_val_adr; /* 0xE3C */
+ u32 lhl_optz_smp_val_adr; /* 0xE40 */
+ u32 lhl_hidoff_keepstate_adr[3]; /* 0xE44-0xE4C */
+ u32 lhl_bt_slmboot_ctl0_adr[4]; /* 0xE50-0xE5C */
+ u32 lhl_wl_fw_ctl; /* 0xE60 */
+ u32 lhl_wl_hw_ctl_adr[2]; /* 0xE64-0xE68 */
+ u32 lhl_bt_hw_ctl_adr; /* 0xE6C */
+ u32 lhl_top_pwrseq_en_adr; /* 0xE70 */
+ u32 lhl_top_pwrdn_ctl_adr; /* 0xE74 */
+ u32 lhl_top_pwrup_ctl_adr; /* 0xE78 */
+ u32 lhl_top_pwrseq_ctl_adr; /* 0xE7C */
+ u32 lhl_top_pwrdn2_ctl_adr; /* 0xE80 */
+ u32 lhl_top_pwrup2_ctl_adr; /* 0xE84 */
+ u32 wpt_regon_intrp_cfg_adr; /* 0xE88 */
+ u32 bt_regon_intrp_cfg_adr; /* 0xE8C */
+ u32 wl_regon_intrp_cfg_adr; /* 0xE90 */
+ u32 regon_intrp_st_adr; /* 0xE94 */
+ u32 regon_intrp_en_adr; /* 0xE98 */
+
};
/* chipid */
--
2.17.1

View File

@@ -0,0 +1,69 @@
From 5ee68395559714baa2229415fc7cc9cdede072e3 Mon Sep 17 00:00:00 2001
From: David Weng <david.weng@cypress.com>
Date: Mon, 28 Jan 2019 01:05:36 -0600
Subject: [PATCH 035/179] non-upstream: fix 43012 driver reload failure after
DS1 exit
Device is left in non-responding state when unloading driver in non-DS1
state if it ever enters DS1 at least once. It leaves that state only
after a hard reset or power cycle 43012.
Signed-off-by: David Weng <david.weng@cypress.com>
[Merge from 4.14.77 to 5.4.18]
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
SWWLAN-137253
---
.../net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 12 +++++++-----
.../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 --
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index d9b6b116a78d..599c1b5ead1b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -1491,11 +1491,6 @@ void brcmf_chip_reset_pmu_regs(struct brcmf_chip *pub)
addr = CORE_CC_REG(base, pmucontrol_ext);
chip->ops->write32(chip->ctx, addr,
CY_43012_PMU_CONTROL_EXT_MASK);
-
- /* PMU watchdog */
- addr = CORE_CC_REG(base, pmuwatchdog);
- chip->ops->write32(chip->ctx, addr,
- CY_43012_PMU_WATCHDOG_TICK_VAL);
break;
default:
@@ -1588,10 +1583,17 @@ void brcmf_chip_reset_watchdog(struct brcmf_chip *pub)
switch (pub->chip) {
case CY_CC_43012_CHIP_ID:
+ addr = CORE_CC_REG(base, min_res_mask);
+ chip->ops->write32(chip->ctx, addr,
+ CY_43012_PMU_MIN_RES_MASK);
/* Watchdog res mask */
addr = CORE_CC_REG(base, watchdog_res_mask);
chip->ops->write32(chip->ctx, addr,
CY_43012_PMU_MIN_RES_MASK);
+ /* PMU watchdog */
+ addr = CORE_CC_REG(base, pmuwatchdog);
+ chip->ops->write32(chip->ctx, addr,
+ CY_43012_PMU_WATCHDOG_TICK_VAL);
break;
default:
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index ce5f807be3d6..ba7d087d5144 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4795,8 +4795,6 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
FMAC_ULP_ENTRY_RECV) {
brcmf_chip_ulp_reset_lhl_regs(bus->ci);
brcmf_chip_reset_pmu_regs(bus->ci);
- brcmf_chip_set_default_min_res_mask(
- bus->ci);
} else {
brcmf_chip_set_passive(bus->ci);
}
--
2.17.1

View File

@@ -0,0 +1,60 @@
From 5760bb605b430b71beb78a128cd1addca751c06e Mon Sep 17 00:00:00 2001
From: Madhan Mohan R <madhanmohan.r@cypress.com>
Date: Tue, 28 Aug 2018 17:14:20 +0530
Subject: [PATCH 036/179] brcmfmac: reset PMU, backplane & all cores in CYW4373
during rmmod
To do a clean reset of the chip during rmmod brcmfmac, program
the PmuWatchdogCounter register. When a watchdog reset occurs,
the PMU, backplane and all of the cores in the chip are reset.
Signed-off-by: Madhan Mohan R <madhanmohan.r@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/chip.c | 21 +++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 599c1b5ead1b..6829ca086695 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -224,9 +224,15 @@ struct sbsocramregs {
/* PMU CONTROL EXT mask for 43012C0 */
#define CY_43012_PMU_CONTROL_EXT_MASK 0x11
-/* PMU CONTROL EXT mask for 43012C0 */
+/* PMU Watchdog Counter Tick value for 43012C0 */
#define CY_43012_PMU_WATCHDOG_TICK_VAL 0x04
+/* PMU Watchdog Counter Tick value for 4373 */
+#define CY_4373_PMU_WATCHDOG_TICK_VAL 0x04
+
+/* Minimum PMU resource mask for 4373 */
+#define CY_4373_PMU_MIN_RES_MASK 0xFCAFF7F
+
struct brcmf_core_priv {
struct brcmf_core pub;
u32 wrapbase;
@@ -1595,7 +1601,18 @@ void brcmf_chip_reset_watchdog(struct brcmf_chip *pub)
chip->ops->write32(chip->ctx, addr,
CY_43012_PMU_WATCHDOG_TICK_VAL);
break;
-
+ case CY_CC_4373_CHIP_ID:
+ addr = CORE_CC_REG(base, min_res_mask);
+ chip->ops->write32(chip->ctx, addr,
+ CY_4373_PMU_MIN_RES_MASK);
+ addr = CORE_CC_REG(base, watchdog_res_mask);
+ chip->ops->write32(chip->ctx, addr,
+ CY_4373_PMU_MIN_RES_MASK);
+ addr = CORE_CC_REG(base, pmuwatchdog);
+ chip->ops->write32(chip->ctx, addr,
+ CY_4373_PMU_WATCHDOG_TICK_VAL);
+ mdelay(100);
+ break;
default:
break;
}
--
2.17.1

View File

@@ -0,0 +1,51 @@
From d66c93b44fb5fba3db4c6d342233c79aed774fd4 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Mon, 1 Jan 2018 20:12:54 -0600
Subject: [PATCH 037/179] non-upstream: calling skb_orphan before sending skb
to SDIO bus
Linux 3.6 introduces TSQ which has a per socket threshold for TCP Tx
packet to reduce latency. In fcmode 1/2, host driver enqueues skb in
hanger and TCP doesn't push new skb frees until host frees the skb when
receiving fwstatus event. So using skb_orphan before sending skb to bus
will make the skb removing the ownership of socket. With this patch, we
got better throughput in fcmode 1/2.
We only call skb_orphan when Linux version is less than 4.16.0.
Tested 43455 TCP throughput in 20 MHz bandwidth with/without this patch.
fcmode 0: 59.5 / 59.6 (Mbps)
fcmode 1: 59.3 / 23.4 (Mbps)
fcmode 2: 59.6 / 21.5 (Mbps)
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index ba7d087d5144..71985089fb7c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3,6 +3,7 @@
* Copyright (c) 2010 Broadcom Corporation
*/
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/atomic.h>
#include <linux/kernel.h>
@@ -2369,6 +2370,9 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
&prec_out);
if (pkt == NULL)
break;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
+ skb_orphan(pkt);
+#endif
__skb_queue_tail(&pktq, pkt);
}
spin_unlock_bh(&bus->txq_lock);
--
2.17.1

View File

@@ -0,0 +1,158 @@
From e5ed9db2bf5a899639039f015869b89419855d79 Mon Sep 17 00:00:00 2001
From: Madhan Mohan R <madhanmohan.r@cypress.com>
Date: Fri, 4 Jan 2019 14:42:04 +0530
Subject: [PATCH 038/179] non-upstream: workaround for 4373 USB WMM 5.2.27 test
failure
With the addition of skb_orphan in the datapath, though the throughput
increases in TX path, it introduces an issue by removing the flowcontrol
from upper layer and allowing more data to flow for different access
category.
This workaround is to disable using skb_orphan when running multi-stream
data. This change will not be required in linux 4.15 and later versions.
We only use this feature when Linux version is less than 4.16.0.
Signed-off-by: Raveendran Somu <raveendran.somu@cypress.com>
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/bus.h | 4 ++
.../broadcom/brcm80211/brcmfmac/fwsignal.c | 46 +++++++++++++++++++
.../broadcom/brcm80211/brcmfmac/usb.c | 8 +++-
3 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index d2863bcf7f94..d78c2613d6f0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -7,6 +7,7 @@
#define BRCMFMAC_BUS_H
#include "debug.h"
+#include <linux/version.h>
/* IDs of the 6 default common rings of msgbuf protocol */
#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0
@@ -152,6 +153,9 @@ struct brcmf_bus {
const struct brcmf_bus_ops *ops;
struct brcmf_bus_msgbuf *msgbuf;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
+ bool allow_skborphan;
+#endif
};
/*
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
index 19b0f318f93e..4a9d8fbac44c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -502,6 +502,9 @@ struct brcmf_fws_info {
bool creditmap_received;
u8 mode;
bool avoid_queueing;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
+ int fifo_init_credit[BRCMF_FWS_FIFO_COUNT];
+#endif
};
#define BRCMF_FWS_TLV_DEF(name, id, len) \
@@ -1617,9 +1620,13 @@ static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
fws->fifo_credit_map |= 1 << i;
else
fws->fifo_credit_map &= ~(1 << i);
+
WARN_ONCE(fws->fifo_credit[i] < 0,
"fifo_credit[%d] is negative(%d)\n", i,
fws->fifo_credit[i]);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
+ fws->fifo_init_credit[i] = fws->fifo_credit[i];
+#endif
}
brcmf_fws_schedule_deq(fws);
brcmf_fws_unlock(fws);
@@ -2197,6 +2204,38 @@ void brcmf_fws_del_interface(struct brcmf_if *ifp)
brcmf_fws_unlock(fws);
}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
+static bool brcmf_fws_ismultistream(struct brcmf_fws_info *fws)
+{
+ bool ret = false;
+ u8 credit_usage = 0;
+
+ /* Check only for BE, VI and VO traffic */
+ u32 delay_map = fws->fifo_delay_map &
+ ((1 << BRCMF_FWS_FIFO_AC_BE) |
+ (1 << BRCMF_FWS_FIFO_AC_VI) |
+ (1 << BRCMF_FWS_FIFO_AC_VO));
+
+ if (hweight_long(delay_map) > 1) {
+ ret = true;
+ } else {
+ if (fws->fifo_credit[BRCMF_FWS_FIFO_AC_BE] <
+ fws->fifo_init_credit[BRCMF_FWS_FIFO_AC_BE])
+ credit_usage++;
+ if (fws->fifo_credit[BRCMF_FWS_FIFO_AC_VI] <
+ fws->fifo_init_credit[BRCMF_FWS_FIFO_AC_VI])
+ credit_usage++;
+ if (fws->fifo_credit[BRCMF_FWS_FIFO_AC_VO] <
+ fws->fifo_init_credit[BRCMF_FWS_FIFO_AC_VO])
+ credit_usage++;
+
+ if (credit_usage > 1)
+ ret = true;
+ }
+ return ret;
+}
+#endif
+
static void brcmf_fws_dequeue_worker(struct work_struct *worker)
{
struct brcmf_fws_info *fws;
@@ -2210,6 +2249,13 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work);
drvr = fws->drvr;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
+ if (brcmf_fws_ismultistream(fws))
+ drvr->bus_if->allow_skborphan = false;
+ else
+ drvr->bus_if->allow_skborphan = true;
+#endif
+
brcmf_fws_lock(fws);
for (fifo = BRCMF_FWS_FIFO_BCMC; fifo >= 0 && !fws->bus_flow_blocked;
fifo--) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 9b592094609c..65416ebb77bc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -639,7 +639,10 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
goto fail;
}
- skb_orphan(skb);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
+ if (devinfo->bus_pub.bus->allow_skborphan)
+ skb_orphan(skb);
+#endif
req->skb = skb;
req->devinfo = devinfo;
usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
@@ -1287,6 +1290,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
bus->ops = &brcmf_usb_bus_ops;
bus->proto_type = BRCMF_PROTO_BCDC;
bus->always_use_fws_queue = true;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
+ bus->allow_skborphan = true;
+#endif
#ifdef CONFIG_PM
bus->wowl_supported = true;
#endif
--
2.17.1

View File

@@ -0,0 +1,35 @@
From db1bccb569b0a01567410d2d39d8a3cd9da2cd7c Mon Sep 17 00:00:00 2001
From: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Date: Fri, 13 Mar 2020 03:08:13 -0500
Subject: [PATCH 039/179] non-upstream: disable command decode in sdio_aos for
4373
AOS is a part of the SDIOD core that becomes active when the rest of
SDIOD is sleeping to keep SDIO bus alive responding to reduced set of
commands.
Transaction between AOS and SDIOD is not protected, and if cmd 52 is
received in AOS and in the middle of response state changed from AOS to
SDIOD, response is corrupted and it causes to SDIO Host controller to
hang.
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 71985089fb7c..b1e037e1bf45 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3621,6 +3621,7 @@ static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
{
if (bus->ci->chip == CY_CC_43012_CHIP_ID ||
bus->ci->chip == CY_CC_43752_CHIP_ID ||
+ bus->ci->chip == CY_CC_4373_CHIP_ID ||
bus->ci->chip == BRCM_CC_4354_CHIP_ID ||
bus->ci->chip == BRCM_CC_4356_CHIP_ID)
return true;
--
2.17.1

View File

@@ -0,0 +1,36 @@
From 439e863b9433cc6f98c32d9159f04cd86a163224 Mon Sep 17 00:00:00 2001
From: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Date: Fri, 13 Mar 2020 03:12:05 -0500
Subject: [PATCH 040/179] non-upstream: disable command decode in sdio_aos for
4339
AOS is a part of the SDIOD core that becomes active when the rest of
SDIOD is sleeping to keep SDIO bus alive responding to reduced set of
commands.
Transaction between AOS and SDIOD is not protected, and if cmd 52 is
received in AOS and in the middle of response state changed from AOS to
SDIOD, response is corrupted and it causes to SDIO Host controller to
hang.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index b1e037e1bf45..c184a745b7c2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3622,6 +3622,7 @@ static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
if (bus->ci->chip == CY_CC_43012_CHIP_ID ||
bus->ci->chip == CY_CC_43752_CHIP_ID ||
bus->ci->chip == CY_CC_4373_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4339_CHIP_ID ||
bus->ci->chip == BRCM_CC_4354_CHIP_ID ||
bus->ci->chip == BRCM_CC_4356_CHIP_ID)
return true;
--
2.17.1

View File

@@ -0,0 +1,36 @@
From c7935ce4be334d9d4ca2766c1a38058e3d85d12a Mon Sep 17 00:00:00 2001
From: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Date: Fri, 13 Mar 2020 03:15:29 -0500
Subject: [PATCH 041/179] non-upstream: disable command decode in sdio_aos for
43455
AOS is a part of the SDIOD core that becomes active when the rest of
SDIOD is sleeping to keep SDIO bus alive responding to reduced set of
commands.
Transaction between AOS and SDIOD is not protected, and if cmd 52 is
received in AOS and in the middle of response state changed from AOS to
SDIOD, response is corrupted and it causes to SDIO Host controller to
hang.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index c184a745b7c2..f7c449f5c83e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3623,6 +3623,7 @@ static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
bus->ci->chip == CY_CC_43752_CHIP_ID ||
bus->ci->chip == CY_CC_4373_CHIP_ID ||
bus->ci->chip == BRCM_CC_4339_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4345_CHIP_ID ||
bus->ci->chip == BRCM_CC_4354_CHIP_ID ||
bus->ci->chip == BRCM_CC_4356_CHIP_ID)
return true;
--
2.17.1

View File

@@ -0,0 +1,280 @@
From 35180cab0299505ae12d8d377b6ef84e4fbe9dde Mon Sep 17 00:00:00 2001
From: Jia-Shyr Chuang <joseph.chuang@cypress.com>
Date: Thu, 22 Aug 2019 03:39:06 -0500
Subject: [PATCH 042/179] brcmfmac: support the forwarding packet
- Support packet forwarding mechanism on fmac driver
for some special usages on PCIE. Please ref to JIRA.
- Fixed BE/VI priority issue when pumping iperf
- Fix for linux coding style
Signed-off-by: Jia-Shyr Chuang <joseph.chuang@cypress.com>
Signed-off-by: Ting-Ying Li <tingying.li@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 13 ++-
.../broadcom/brcm80211/brcmfmac/core.c | 101 +++++++++++++++++-
.../broadcom/brcm80211/brcmfmac/core.h | 17 +++
.../broadcom/brcm80211/brcmfmac/msgbuf.c | 31 +++++-
4 files changed, 158 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 094a2e49d646..183ebbd293a0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -4855,7 +4855,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = -EINVAL;
goto exit;
}
-
+ ifp->isap = false;
/* Interface specific setup */
if (dev_role == NL80211_IFTYPE_AP) {
if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
@@ -4935,7 +4935,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err);
goto exit;
}
-
+ ifp->isap = true;
brcmf_dbg(TRACE, "AP mode configuration complete\n");
} else if (dev_role == NL80211_IFTYPE_P2P_GO) {
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
@@ -4967,6 +4967,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
}
+ ifp->isap = true;
brcmf_dbg(TRACE, "GO mode configuration complete\n");
} else {
WARN_ON(1);
@@ -6260,6 +6261,14 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
}
if (brcmf_is_apmode(ifp->vif)) {
+ if (e->event_code == BRCMF_E_ASSOC_IND ||
+ e->event_code == BRCMF_E_REASSOC_IND) {
+ brcmf_findadd_sta(ifp, e->addr);
+ } else if ((e->event_code == BRCMF_E_DISASSOC_IND) ||
+ (e->event_code == BRCMF_E_DEAUTH_IND) ||
+ (e->event_code == BRCMF_E_DEAUTH)) {
+ brcmf_del_sta(ifp, e->addr);
+ }
err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
} else if (brcmf_is_linkup(ifp->vif, e)) {
brcmf_dbg(CONN, "Linkup\n");
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index e2427d140b20..6570f83da931 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -62,6 +62,14 @@ struct wlc_d11rxhdr {
s8 rxpwr[4];
} __packed;
+#define BRCMF_IF_STA_LIST_LOCK_INIT(ifp) spin_lock_init(&(ifp)->sta_list_lock)
+#define BRCMF_IF_STA_LIST_LOCK(ifp, flags) \
+ spin_lock_irqsave(&(ifp)->sta_list_lock, (flags))
+#define BRCMF_IF_STA_LIST_UNLOCK(ifp, flags) \
+ spin_unlock_irqrestore(&(ifp)->sta_list_lock, (flags))
+
+#define BRCMF_STA_NULL ((struct brcmf_sta *)NULL)
+
char *brcmf_ifname(struct brcmf_if *ifp)
{
if (!ifp)
@@ -903,7 +911,9 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
init_waitqueue_head(&ifp->pend_8021x_wait);
spin_lock_init(&ifp->netif_stop_lock);
-
+ BRCMF_IF_STA_LIST_LOCK_INIT(ifp);
+ /* Initialize STA info list */
+ INIT_LIST_HEAD(&ifp->sta_list);
if (mac_addr != NULL)
memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
@@ -1744,3 +1754,92 @@ int brcmf_pktfilter_enable(struct net_device *ndev, bool enable)
}
return ret;
}
+
+/** Find STA with MAC address ea in an interface's STA list. */
+struct brcmf_sta *
+brcmf_find_sta(struct brcmf_if *ifp, const u8 *ea)
+{
+ struct brcmf_sta *sta;
+ unsigned long flags;
+
+ BRCMF_IF_STA_LIST_LOCK(ifp, flags);
+ list_for_each_entry(sta, &ifp->sta_list, list) {
+ if (!memcmp(sta->ea.octet, ea, ETH_ALEN)) {
+ brcmf_dbg(INFO, "Found STA: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x into sta list\n",
+ sta->ea.octet[0], sta->ea.octet[1],
+ sta->ea.octet[2], sta->ea.octet[3],
+ sta->ea.octet[4], sta->ea.octet[5]);
+ BRCMF_IF_STA_LIST_UNLOCK(ifp, flags);
+ return sta;
+ }
+ }
+ BRCMF_IF_STA_LIST_UNLOCK(ifp, flags);
+
+ return BRCMF_STA_NULL;
+}
+
+/** Add STA into the interface's STA list. */
+struct brcmf_sta *
+brcmf_add_sta(struct brcmf_if *ifp, const u8 *ea)
+{
+ struct brcmf_sta *sta;
+ unsigned long flags;
+
+ sta = kzalloc(sizeof(*sta), GFP_KERNEL);
+ if (sta == BRCMF_STA_NULL) {
+ brcmf_err("Alloc failed\n");
+ return BRCMF_STA_NULL;
+ }
+ memcpy(sta->ea.octet, ea, ETH_ALEN);
+ brcmf_dbg(INFO, "Add STA: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x into sta list\n",
+ sta->ea.octet[0], sta->ea.octet[1],
+ sta->ea.octet[2], sta->ea.octet[3],
+ sta->ea.octet[4], sta->ea.octet[5]);
+
+ /* link the sta and the dhd interface */
+ sta->ifp = ifp;
+ INIT_LIST_HEAD(&sta->list);
+
+ BRCMF_IF_STA_LIST_LOCK(ifp, flags);
+
+ list_add_tail(&sta->list, &ifp->sta_list);
+
+ BRCMF_IF_STA_LIST_UNLOCK(ifp, flags);
+ return sta;
+}
+
+/** Delete STA from the interface's STA list. */
+void
+brcmf_del_sta(struct brcmf_if *ifp, const u8 *ea)
+{
+ struct brcmf_sta *sta, *next;
+ unsigned long flags;
+
+ BRCMF_IF_STA_LIST_LOCK(ifp, flags);
+ list_for_each_entry_safe(sta, next, &ifp->sta_list, list) {
+ if (!memcmp(sta->ea.octet, ea, ETH_ALEN)) {
+ brcmf_dbg(INFO, "del STA: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x from sta list\n",
+ ea[0], ea[1], ea[2], ea[3],
+ ea[4], ea[5]);
+ list_del(&sta->list);
+ kfree(sta);
+ }
+ }
+
+ BRCMF_IF_STA_LIST_UNLOCK(ifp, flags);
+}
+
+/** Add STA if it doesn't exist. Not reentrant. */
+struct brcmf_sta*
+brcmf_findadd_sta(struct brcmf_if *ifp, const u8 *ea)
+{
+ struct brcmf_sta *sta = NULL;
+
+ sta = brcmf_find_sta(ifp, ea);
+
+ if (!sta) {
+ /* Add entry */
+ sta = brcmf_add_sta(ifp, ea);
+ }
+ return sta;
+}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index bf4b877acf48..67c4cce91196 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -188,6 +188,7 @@ struct brcmf_if {
struct brcmf_fws_mac_descriptor *fws_desc;
int ifidx;
s32 bsscfgidx;
+ bool isap;
u8 mac_addr[ETH_ALEN];
u8 netif_stop;
spinlock_t netif_stop_lock;
@@ -196,6 +197,19 @@ struct brcmf_if {
struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES];
u8 ipv6addr_idx;
bool fwil_fwerr;
+ struct list_head sta_list; /* sll of associated stations */
+ spinlock_t sta_list_lock;
+};
+
+struct ether_addr {
+ u8 octet[ETH_ALEN];
+};
+
+/** Per STA params. A list of dhd_sta objects are managed in dhd_if */
+struct brcmf_sta {
+ void *ifp; /* associated brcm_if */
+ struct ether_addr ea; /* stations ethernet mac address */
+ struct list_head list; /* link into brcmf_if::sta_list */
};
int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
@@ -221,4 +235,7 @@ void __exit brcmf_core_exit(void);
int brcmf_pktfilter_add_remove(struct net_device *ndev, int filter_num,
bool add);
int brcmf_pktfilter_enable(struct net_device *ndev, bool enable);
+void brcmf_del_sta(struct brcmf_if *ifp, const u8 *ea);
+struct brcmf_sta *brcmf_find_sta(struct brcmf_if *ifp, const u8 *ea);
+struct brcmf_sta *brcmf_findadd_sta(struct brcmf_if *ifp, const u8 *ea);
#endif /* BRCMFMAC_CORE_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index e856964cd048..eb6daca080e3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -1146,7 +1146,8 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
{
struct brcmf_pub *drvr = msgbuf->drvr;
struct msgbuf_rx_complete *rx_complete;
- struct sk_buff *skb;
+ struct sk_buff *skb, *cpskb = NULL;
+ struct ethhdr *eh;
u16 data_offset;
u16 buflen;
u16 flags;
@@ -1195,6 +1196,34 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
return;
}
+ eh = (struct ethhdr *)(skb->data);
+ if (ifp->isap) {
+ skb_set_network_header(skb, sizeof(struct ethhdr));
+ skb->protocol = eh->h_proto;
+ skb->priority = cfg80211_classify8021d(skb, NULL);
+ if (is_unicast_ether_addr(eh->h_dest)) {
+ if (brcmf_find_sta(ifp, eh->h_dest)) {
+ /* determine the priority */
+ if (skb->priority == 0 || skb->priority > 7) {
+ skb->priority =
+ cfg80211_classify8021d(skb,
+ NULL);
+ }
+ brcmf_proto_tx_queue_data(ifp->drvr,
+ ifp->ifidx, skb);
+ return;
+ }
+ } else {
+ cpskb = pskb_copy(skb, GFP_ATOMIC);
+ if (cpskb) {
+ brcmf_proto_tx_queue_data(ifp->drvr,
+ ifp->ifidx,
+ cpskb);
+ } else {
+ brcmf_err("Unable to do skb copy\n");
+ }
+ }
+ }
skb->protocol = eth_type_trans(skb, ifp->ndev);
brcmf_netif_rx(ifp, skb, false);
}
--
2.17.1

View File

@@ -0,0 +1,80 @@
From 6e02bc9d174e9212bd16a4f202c04a79e1e04e1a Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Fri, 20 Mar 2020 05:13:47 -0500
Subject: [PATCH 043/179] brcmfmac: add a variable for packet forwarding
condition
Some firmware does not support disabling "ap_isolate"
via iovar. Therefore, get iovar "ap_isolate" value after
setting to determine whether fmac driver should turn on
host-based packet forwarding.
Signed-off-by: Ting-Ying Li <tingying.li@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 13 ++++++++++++-
.../net/wireless/broadcom/brcm80211/brcmfmac/core.h | 1 +
.../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 4 ++--
3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 183ebbd293a0..0f76e4c1bb1d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5609,7 +5609,7 @@ brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,
{
struct brcmf_if *ifp;
int ret = 0;
- u32 ap_isolate;
+ u32 ap_isolate, val;
brcmf_dbg(TRACE, "Enter\n");
ifp = netdev_priv(dev);
@@ -5620,6 +5620,17 @@ brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,
brcmf_err("ap_isolate iovar failed: ret=%d\n", ret);
}
+ /* Get ap_isolate value from firmware to detemine whether fmac */
+ /* driver supports packet forwarding. */
+ if (brcmf_fil_iovar_int_get(ifp, "ap_isolate", &val) == 0) {
+ ifp->fmac_pkt_fwd_en =
+ ((params->ap_isolate == 0) && (val == 1)) ?
+ true : false;
+ } else {
+ brcmf_err("get ap_isolate iovar failed: ret=%d\n", ret);
+ ifp->fmac_pkt_fwd_en = false;
+ }
+
return ret;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index 67c4cce91196..c29ae6be1eaf 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -199,6 +199,7 @@ struct brcmf_if {
bool fwil_fwerr;
struct list_head sta_list; /* sll of associated stations */
spinlock_t sta_list_lock;
+ bool fmac_pkt_fwd_en;
};
struct ether_addr {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index eb6daca080e3..207433fbcc41 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -1196,8 +1196,8 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
return;
}
- eh = (struct ethhdr *)(skb->data);
- if (ifp->isap) {
+ if (ifp->isap && ifp->fmac_pkt_fwd_en) {
+ eh = (struct ethhdr *)(skb->data);
skb_set_network_header(skb, sizeof(struct ethhdr));
skb->protocol = eh->h_proto;
skb->priority = cfg80211_classify8021d(skb, NULL);
--
2.17.1

View File

@@ -0,0 +1,84 @@
From 52ad7ed2ac1a591bc370574f13d2c7955ea22a53 Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Mon, 13 Apr 2020 02:39:44 -0500
Subject: [PATCH 044/179] brcmfmac: don't allow arp/nd offload to be enabled if
ap mode exists
Add a condition to determine whether arp/nd offload enabling
request is allowed. If there is any interface acts as ap
mode and is operating, then reject the request of arp oflload
enabling from cfg80211.
Signed-off-by: Ting-Ying Li <tingying.li@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 17 ++++++++++++++++-
.../broadcom/brcm80211/brcmfmac/cfg80211.h | 1 +
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 5 +++++
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 0f76e4c1bb1d..9815d9be8a95 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -772,6 +772,21 @@ void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
}
}
+bool brcmf_is_apmode_operating(struct wiphy *wiphy)
+{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_cfg80211_vif *vif;
+ bool ret = false;
+
+ list_for_each_entry(vif, &cfg->vif_list, list) {
+ if (brcmf_is_apmode(vif) &&
+ test_bit(BRCMF_VIF_STATUS_AP_CREATED, &vif->sme_state))
+ ret = true;
+ }
+
+ return ret;
+}
+
s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
struct brcmf_if *ifp, bool aborted,
bool fw_abort)
@@ -5075,8 +5090,8 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
bphy_err(drvr, "bss_enable config failed %d\n", err);
}
brcmf_set_mpc(ifp, 1);
- brcmf_configure_arp_nd_offload(ifp, true);
clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
+ brcmf_configure_arp_nd_offload(ifp, true);
brcmf_net_setcarrier(ifp, false);
return err;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 118a47e1dd7f..2fe90639e65b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -486,5 +486,6 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
void brcmf_set_mpc(struct brcmf_if *ndev, int mpc);
void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg);
void brcmf_cfg80211_free_netdev(struct net_device *ndev);
+bool brcmf_is_apmode_operating(struct wiphy *wiphy);
#endif /* BRCMFMAC_CFG80211_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 6570f83da931..6587d0d92950 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -104,6 +104,11 @@ void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
s32 err;
u32 mode;
+ if (enable && brcmf_is_apmode_operating(ifp->drvr->wiphy)) {
+ brcmf_dbg(TRACE, "Skip ARP/ND offload enable when soft AP is running\n");
+ return;
+ }
+
if (enable)
mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
else
--
2.17.1

View File

@@ -0,0 +1,49 @@
From 2c09290d3db101e44d00a2ece31769aa8aa47eef Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Wed, 29 Apr 2020 00:51:13 -0500
Subject: [PATCH 045/179] non-upstream: ignore FW BADARG error when removing
non-existed pkt filter
The error check -ENOENT in removing packet filter never happen because
fwil_fwerr is falase. We should set fwil_fwerr to true and ignore FW
BADARG(-2) error if firmware does not have that packet filter pattern in
the list.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 4 +++-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 6587d0d92950..1a27f0686c95 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1718,9 +1718,11 @@ brcmf_pktfilter_add_remove(struct net_device *ndev, int filter_num, bool add)
} else {
/* Delete filter */
+ ifp->fwil_fwerr = true;
ret = brcmf_fil_iovar_int_set(ifp, "pkt_filter_delete",
pkt_filter->id);
- if (ret == -ENOENT)
+ ifp->fwil_fwerr = false;
+ if (ret == -BRCMF_FW_BADARG)
ret = 0;
if (ret)
goto failed;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
index caf18d3b4cca..8a9fca90323a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
@@ -79,6 +79,7 @@
#define BRCMF_C_SET_VAR 263
#define BRCMF_C_SET_WSEC_PMK 268
+#define BRCMF_FW_BADARG 2
#define BRCMF_FW_UNSUPPORTED 23
s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
--
2.17.1

View File

@@ -0,0 +1,359 @@
From 657ccada6d16171aa5af30f7afd24deb2358a6fb Mon Sep 17 00:00:00 2001
From: Kurt Lee <kurt.lee@cypress.com>
Date: Tue, 12 May 2020 05:55:29 -0500
Subject: [PATCH 046/179] brcmfmac: Support DPP feature
Let driver parse DPP frames from upper layer and do conresponding
configuration to firmware.
This change supports DPP handshake based on wpa_supplicant v2.9.
Signed-off-by: Kurt Lee <kurt.lee@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 85 ++++++++++++-------
.../broadcom/brcm80211/brcmfmac/p2p.c | 72 ++++++++++++----
.../broadcom/brcm80211/brcmfmac/p2p.h | 4 +-
.../broadcom/brcm80211/include/brcmu_wifi.h | 5 ++
4 files changed, 117 insertions(+), 49 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 9815d9be8a95..d5543170f5cc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -63,6 +63,9 @@
#define RSN_CAP_MFPC_MASK BIT(7)
#define RSN_PMKID_COUNT_LEN 2
+#define DPP_AKM_SUITE_TYPE 2
+#define WLAN_AKM_SUITE_DPP SUITE(WLAN_OUI_WFA, DPP_AKM_SUITE_TYPE)
+
#define VNDR_IE_CMD_LEN 4 /* length of the set command
* string :"add", "del" (+ NUL)
*/
@@ -1830,6 +1833,9 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
profile->is_ft = true;
break;
+ case WLAN_AKM_SUITE_DPP:
+ val = WFA_AUTH_DPP;
+ break;
default:
bphy_err(drvr, "invalid cipher group (%d)\n",
sme->crypto.cipher_group);
@@ -4173,6 +4179,12 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
}
+static bool brcmf_valid_dpp_suite(u8 *oui)
+{
+ return (memcmp(oui, WFA_OUI, TLV_OUI_LEN) == 0 &&
+ *(oui + TLV_OUI_LEN) == DPP_AKM_SUITE_TYPE);
+}
+
static s32
brcmf_configure_wpaie(struct brcmf_if *ifp,
const struct brcmf_vs_tlv *wpa_ie,
@@ -4286,42 +4298,47 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
goto exit;
}
for (i = 0; i < count; i++) {
- if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
+ if (brcmf_valid_dpp_suite(&data[offset])) {
+ wpa_auth |= WFA_AUTH_DPP;
+ offset += TLV_OUI_LEN;
+ } else if (brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
+ offset += TLV_OUI_LEN;
+ switch (data[offset]) {
+ case RSN_AKM_NONE:
+ brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
+ wpa_auth |= WPA_AUTH_NONE;
+ break;
+ case RSN_AKM_UNSPECIFIED:
+ brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
+ is_rsn_ie ?
+ (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
+ (wpa_auth |= WPA_AUTH_UNSPECIFIED);
+ break;
+ case RSN_AKM_PSK:
+ brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
+ is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
+ (wpa_auth |= WPA_AUTH_PSK);
+ break;
+ case RSN_AKM_SHA256_PSK:
+ brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
+ wpa_auth |= WPA2_AUTH_PSK_SHA256;
+ break;
+ case RSN_AKM_SHA256_1X:
+ brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
+ wpa_auth |= WPA2_AUTH_1X_SHA256;
+ break;
+ case RSN_AKM_SAE:
+ brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
+ wpa_auth |= WPA3_AUTH_SAE_PSK;
+ break;
+ default:
+ bphy_err(drvr, "Invalid key mgmt info\n");
+ }
+ } else {
err = -EINVAL;
bphy_err(drvr, "ivalid OUI\n");
goto exit;
}
- offset += TLV_OUI_LEN;
- switch (data[offset]) {
- case RSN_AKM_NONE:
- brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
- wpa_auth |= WPA_AUTH_NONE;
- break;
- case RSN_AKM_UNSPECIFIED:
- brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
- is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
- (wpa_auth |= WPA_AUTH_UNSPECIFIED);
- break;
- case RSN_AKM_PSK:
- brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
- is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
- (wpa_auth |= WPA_AUTH_PSK);
- break;
- case RSN_AKM_SHA256_PSK:
- brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
- wpa_auth |= WPA2_AUTH_PSK_SHA256;
- break;
- case RSN_AKM_SHA256_1X:
- brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
- wpa_auth |= WPA2_AUTH_1X_SHA256;
- break;
- case RSN_AKM_SAE:
- brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
- wpa_auth |= WPA3_AUTH_SAE_PSK;
- break;
- default:
- bphy_err(drvr, "Invalid key mgmt info\n");
- }
offset++;
}
@@ -4341,10 +4358,12 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
*/
if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
WPA2_AUTH_1X_SHA256 |
+ WFA_AUTH_DPP |
WPA3_AUTH_SAE_PSK))) {
err = -EINVAL;
goto exit;
}
+
/* Firmware has requirement that WPA2_AUTH_PSK/
* WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
* is to be included in the rsn ie.
@@ -5281,7 +5300,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
*cookie, le16_to_cpu(action_frame->len), freq);
ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
- af_params);
+ af_params, vif);
cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
GFP_KERNEL);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 9ec232e3dfe8..7ca37aee1783 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -231,7 +231,35 @@ static bool brcmf_p2p_is_pub_action(void *frame, u32 frame_len)
if (pact_frm->category == P2P_PUB_AF_CATEGORY &&
pact_frm->action == P2P_PUB_AF_ACTION &&
pact_frm->oui_type == P2P_VER &&
- memcmp(pact_frm->oui, P2P_OUI, P2P_OUI_LEN) == 0)
+ memcmp(pact_frm->oui, WFA_OUI, P2P_OUI_LEN) == 0)
+ return true;
+
+ return false;
+}
+
+/**
+ * brcmf_p2p_is_dpp_pub_action() - true if dpp public type frame.
+ *
+ * @frame: action frame data.
+ * @frame_len: length of action frame data.
+ *
+ * Determine if action frame is dpp public action type
+ */
+static bool brcmf_p2p_is_dpp_pub_action(void *frame, u32 frame_len)
+{
+ struct brcmf_p2p_pub_act_frame *pact_frm;
+
+ if (!frame)
+ return false;
+
+ pact_frm = (struct brcmf_p2p_pub_act_frame *)frame;
+ if (frame_len < sizeof(struct brcmf_p2p_pub_act_frame) - 1)
+ return false;
+
+ if (pact_frm->category == WLAN_CATEGORY_PUBLIC &&
+ pact_frm->action == WLAN_PUB_ACTION_VENDOR_SPECIFIC &&
+ pact_frm->oui_type == DPP_VER &&
+ memcmp(pact_frm->oui, WFA_OUI, TLV_OUI_LEN) == 0)
return true;
return false;
@@ -993,6 +1021,8 @@ int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
if (err)
goto exit;
+ p2p->remin_on_channel_wdev = wdev;
+
memcpy(&p2p->remain_on_channel, channel, sizeof(*channel));
*cookie = p2p->remain_on_channel_cookie;
cfg80211_ready_on_channel(wdev, *cookie, channel, duration, GFP_KERNEL);
@@ -1016,6 +1046,7 @@ int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
{
struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
struct brcmf_p2p_info *p2p = &cfg->p2p;
+ struct wireless_dev *wdev = p2p->remin_on_channel_wdev;
brcmf_dbg(TRACE, "Enter\n");
if (test_and_clear_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN,
@@ -1028,10 +1059,16 @@ int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
complete(&p2p->wait_next_af);
}
- cfg80211_remain_on_channel_expired(&ifp->vif->wdev,
+ wdev = p2p->remin_on_channel_wdev ?
+ p2p->remin_on_channel_wdev :
+ &ifp->vif->wdev;
+
+ cfg80211_remain_on_channel_expired(wdev,
p2p->remain_on_channel_cookie,
&p2p->remain_on_channel,
GFP_KERNEL);
+ p2p->remin_on_channel_wdev = NULL;
+
}
return 0;
}
@@ -1533,6 +1570,7 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
*
* @p2p: p2p info struct for vif.
* @af_params: action frame data/info.
+ * @vif: vif to send
*
* Send an action frame immediately without doing channel synchronization.
*
@@ -1541,12 +1579,17 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
* frame is transmitted.
*/
static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
- struct brcmf_fil_af_params_le *af_params)
+ struct brcmf_fil_af_params_le *af_params,
+ struct brcmf_cfg80211_vif *vif
+ )
{
struct brcmf_pub *drvr = p2p->cfg->pub;
- struct brcmf_cfg80211_vif *vif;
- struct brcmf_p2p_action_frame *p2p_af;
s32 err = 0;
+ struct brcmf_fil_action_frame_le *action_frame;
+ u16 action_frame_len;
+
+ action_frame = &af_params->action_frame;
+ action_frame_len = le16_to_cpu(action_frame->len);
brcmf_dbg(TRACE, "Enter\n");
@@ -1554,13 +1597,6 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);
clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status);
- /* check if it is a p2p_presence response */
- p2p_af = (struct brcmf_p2p_action_frame *)af_params->action_frame.data;
- if (p2p_af->subtype == P2P_AF_PRESENCE_RSP)
- vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif;
- else
- vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
-
err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params,
sizeof(*af_params));
if (err) {
@@ -1716,10 +1752,13 @@ static bool brcmf_p2p_check_dwell_overflow(u32 requested_dwell,
* @cfg: driver private data for cfg80211 interface.
* @ndev: net device to transmit on.
* @af_params: configuration data for action frame.
+ * @vif: virtual interface to send
*/
bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev,
- struct brcmf_fil_af_params_le *af_params)
+ struct brcmf_fil_af_params_le *af_params,
+ struct brcmf_cfg80211_vif *vif
+ )
{
struct brcmf_p2p_info *p2p = &cfg->p2p;
struct brcmf_if *ifp = netdev_priv(ndev);
@@ -1791,7 +1830,9 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
goto exit;
}
} else if (brcmf_p2p_is_p2p_action(action_frame->data,
- action_frame_len)) {
+ action_frame_len) ||
+ brcmf_p2p_is_dpp_pub_action(action_frame->data,
+ action_frame_len)) {
/* do not configure anything. it will be */
/* sent with a default configuration */
} else {
@@ -1859,7 +1900,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
if (af_params->channel)
msleep(P2P_AF_RETRY_DELAY_TIME);
- ack = !brcmf_p2p_tx_action_frame(p2p, af_params);
+ ack = !brcmf_p2p_tx_action_frame(p2p, af_params, vif);
tx_retry++;
dwell_overflow = brcmf_p2p_check_dwell_overflow(requested_dwell,
dwell_jiffies);
@@ -2510,6 +2551,7 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced)
pri_ifp = brcmf_get_ifp(cfg->pub, 0);
p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
+ init_completion(&p2p->send_af_done);
if (p2pdev_forced) {
err_ptr = brcmf_p2p_create_p2pdev(p2p, NULL, NULL);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
index d2ecee565bf2..bbc455238707 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
@@ -138,6 +138,7 @@ struct brcmf_p2p_info {
bool block_gon_req_tx;
bool p2pdev_dynamically;
bool wait_for_offchan_complete;
+ struct wireless_dev *remin_on_channel_wdev;
};
s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced);
@@ -170,7 +171,8 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
void *data);
bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev,
- struct brcmf_fil_af_params_le *af_params);
+ struct brcmf_fil_af_params_le *af_params,
+ struct brcmf_cfg80211_vif *vif);
bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
struct brcmf_bss_info_le *bi);
s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
index 7552bdb91991..3a9cad3730b8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
@@ -233,6 +233,11 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
#define WPA3_AUTH_SAE_PSK 0x40000 /* SAE with 4-way handshake */
+#define WFA_AUTH_DPP 0x200000 /* WFA DPP AUTH */
+
+#define WFA_OUI "\x50\x6F\x9A" /* WFA OUI */
+#define DPP_VER 0x1A /* WFA DPP v1.0 */
+
#define DOT11_DEFAULT_RTS_LEN 2347
#define DOT11_DEFAULT_FRAG_LEN 2346
--
2.17.1

View File

@@ -0,0 +1,123 @@
From 32df9a3f4ba1286602e297d40239818c1d293a50 Mon Sep 17 00:00:00 2001
From: Double Lo <double.lo@cypress.com>
Date: Tue, 12 May 2020 01:37:54 -0500
Subject: [PATCH 047/179] brcmfmac: move firmware path to cypress folder
To support upstreaming cypress firmware, move the firmware path
to /lib/firmware/cypress. The new files in "cypress" folder will be
called cyfmac<chip>-<bus>.bin/clm_blob/txt.
Signed-off-by: Double Lo <double.lo@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/firmware.h | 7 +++++++
.../broadcom/brcm80211/brcmfmac/pcie.c | 10 +++++-----
.../broadcom/brcm80211/brcmfmac/sdio.c | 20 +++++++++----------
.../broadcom/brcm80211/brcmfmac/usb.c | 2 +-
4 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
index e290dec9c53d..f0748500b345 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
@@ -11,6 +11,8 @@
#define BRCMF_FW_DEFAULT_PATH "brcm/"
+#define CY_FW_DEFAULT_PATH "cypress/"
+
/**
* struct brcmf_firmware_mapping - Used to map chipid/revmask to firmware
* filename and nvram filename. Each bus type implementation should create
@@ -39,6 +41,11 @@ static const char BRCM_ ## fw_name ## _FIRMWARE_BASENAME[] = \
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw_base ".bin"); \
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw_base ".clm_blob")
+#define CY_FW_DEF(fw_name, fw_base) \
+static const char BRCM_ ## fw_name ## _FIRMWARE_BASENAME[] = \
+ CY_FW_DEFAULT_PATH fw_base; \
+MODULE_FIRMWARE(CY_FW_DEFAULT_PATH fw_base ".bin")
+
#define BRCMF_FW_ENTRY(chipid, mask, name) \
{ chipid, mask, BRCM_ ## name ## _FIRMWARE_BASENAME }
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index f793fce879d2..ff03c282ea8f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -50,18 +50,18 @@ enum brcmf_pcie_state {
BRCMF_FW_DEF(43602, "brcmfmac43602-pcie");
BRCMF_FW_DEF(4350, "brcmfmac4350-pcie");
BRCMF_FW_DEF(4350C, "brcmfmac4350c2-pcie");
-BRCMF_FW_CLM_DEF(4356, "brcmfmac4356-pcie");
-BRCMF_FW_CLM_DEF(43570, "brcmfmac43570-pcie");
+CY_FW_DEF(4356, "cyfmac4356-pcie");
+CY_FW_DEF(43570, "cyfmac43570-pcie");
BRCMF_FW_DEF(4358, "brcmfmac4358-pcie");
-BRCMF_FW_DEF(4359, "brcmfmac4359-pcie");
+CY_FW_DEF(4359, "cyfmac4359-pcie");
BRCMF_FW_DEF(4364, "brcmfmac4364-pcie");
BRCMF_FW_DEF(4365B, "brcmfmac4365b-pcie");
BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie");
BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
-BRCMF_FW_DEF(4355, "brcmfmac89459-pcie");
-BRCMF_FW_DEF(54591, "brcmfmac54591-pcie");
+CY_FW_DEF(4355, "cyfmac89459-pcie");
+CY_FW_DEF(54591, "cyfmac54591-pcie");
/* firmware config files */
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt");
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index f7c449f5c83e..a1917af114fe 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -622,21 +622,21 @@ BRCMF_FW_DEF(43241B5, "brcmfmac43241b5-sdio");
BRCMF_FW_DEF(4329, "brcmfmac4329-sdio");
BRCMF_FW_DEF(4330, "brcmfmac4330-sdio");
BRCMF_FW_DEF(4334, "brcmfmac4334-sdio");
-BRCMF_FW_DEF(43340, "brcmfmac43340-sdio");
+CY_FW_DEF(43340, "cyfmac43340-sdio");
BRCMF_FW_DEF(4335, "brcmfmac4335-sdio");
-BRCMF_FW_DEF(43362, "brcmfmac43362-sdio");
-BRCMF_FW_DEF(4339, "brcmfmac4339-sdio");
+CY_FW_DEF(43362, "cyfmac43362-sdio");
+CY_FW_DEF(4339, "cyfmac4339-sdio");
BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio");
/* Note the names are not postfixed with a1 for backward compatibility */
-BRCMF_FW_CLM_DEF(43430A1, "brcmfmac43430-sdio");
+CY_FW_DEF(43430A1, "cyfmac43430-sdio");
BRCMF_FW_DEF(43430B0, "brcmfmac43430b0-sdio");
-BRCMF_FW_CLM_DEF(43455, "brcmfmac43455-sdio");
+CY_FW_DEF(43455, "cyfmac43455-sdio");
BRCMF_FW_DEF(43456, "brcmfmac43456-sdio");
-BRCMF_FW_CLM_DEF(4354, "brcmfmac4354-sdio");
-BRCMF_FW_CLM_DEF(4356, "brcmfmac4356-sdio");
-BRCMF_FW_DEF(4359, "brcmfmac4359-sdio");
-BRCMF_FW_CLM_DEF(4373, "brcmfmac4373-sdio");
-BRCMF_FW_CLM_DEF(43012, "brcmfmac43012-sdio");
+CY_FW_DEF(4354, "cyfmac4354-sdio");
+CY_FW_DEF(4356, "cyfmac4356-sdio");
+CY_FW_DEF(4359, "cyfmac4359-sdio");
+CY_FW_DEF(4373, "cyfmac4373-sdio");
+CY_FW_DEF(43012, "cyfmac43012-sdio");
BRCMF_FW_CLM_DEF(43752, "brcmfmac43752-sdio");
/* firmware config files */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 65416ebb77bc..22b873f055f0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -40,7 +40,7 @@ BRCMF_FW_DEF(43143, "brcmfmac43143");
BRCMF_FW_DEF(43236B, "brcmfmac43236b");
BRCMF_FW_DEF(43242A, "brcmfmac43242a");
BRCMF_FW_DEF(43569, "brcmfmac43569");
-BRCMF_FW_DEF(4373, "brcmfmac4373");
+CY_FW_DEF(4373, "cyfmac4373");
static const struct brcmf_firmware_mapping brcmf_usb_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
--
2.17.1

View File

@@ -0,0 +1,81 @@
From baaf9e70927f4e9839f5ead1e3dacb4c70bd1123 Mon Sep 17 00:00:00 2001
From: Brian Henriquez <brian.henriquez@cypress.com>
Date: Tue, 19 May 2020 00:04:02 -0500
Subject: [PATCH 048/179] brcmfmac: add support for sof time-stammping for tx
packets
This adds support for time-stamping outgoing tx packets to support
PTP with better accuracy. Packets are time-stamped very close to
when they are put on the bus.
Signed-off-by: Brian Henriquez <brian.henriquez@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 ++
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 2 ++
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 +++
3 files changed, 7 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 1a27f0686c95..5a86770a41bc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
#include <linux/module.h>
#include <linux/inetdevice.h>
#include <net/cfg80211.h>
@@ -594,6 +595,7 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
static const struct ethtool_ops brcmf_ethtool_ops = {
.get_drvinfo = brcmf_ethtool_get_drvinfo,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static int brcmf_netdev_stop(struct net_device *ndev)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index 207433fbcc41..d0cc9880b83e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/net_tstamp.h>
#include <brcmu_utils.h>
#include <brcmu_wifi.h>
@@ -720,6 +721,7 @@ static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid)
brcmf_flowring_qlen(flow, flowid));
break;
}
+ skb_tx_timestamp(skb);
skb_orphan(skb);
if (brcmf_msgbuf_alloc_pktid(msgbuf->drvr->bus_if->dev,
msgbuf->tx_pktids, skb, ETH_HLEN,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index a1917af114fe..0cf906af03f6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -24,6 +24,7 @@
#include <linux/bcma/bcma.h>
#include <linux/debugfs.h>
#include <linux/vmalloc.h>
+#include <linux/net_tstamp.h>
#include <asm/unaligned.h>
#include <defs.h>
#include <brcmu_wifi.h>
@@ -3018,6 +3019,8 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq));
bus->sdcnt.fcqueued++;
+ skb_tx_timestamp(pkt);
+
/* Priority based enq */
spin_lock_bh(&bus->txq_lock);
/* reset bus_flags in packet cb */
--
2.17.1

View File

@@ -0,0 +1,50 @@
From fb35041f347a1a96d573c121a10fcbae53b27f94 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Fri, 22 May 2020 03:52:01 -0500
Subject: [PATCH 049/179] non-upstream: free eventmask_msg after updating event
mask
To avoid memory leak, we should free eventmask_msg after updating
event mask.
Memory leak is detected by kmemleak
unreferenced object 0xa94436c0 (size 64):
comm "kworker/0:1", pid 1242, jiffies 208818 (age 20.650s)
hex dump (first 32 bytes):
01 03 13 15 00 00 00 00 00 00 40 00 00 04 00 00 ..........@.....
00 00 00 80 00 00 04 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<7f3d0f9c>] 0x7f3d0f9c
[<7f3dd3c8>] 0x7f3dd3c8
[<7f3d2444>] 0x7f3d2444
[<80536630>] request_firmware_work_func+0x3c/0x64
[<80144dd4>] process_one_work+0x1d8/0x414
[<80145a08>] worker_thread+0x38/0x574
[<8014a82c>] kthread+0x124/0x154
[<801077c8>] ret_from_fork+0x14/0x2c
[<ffffffff>] 0xffffffff
Signed-off-by: Wright Feng <wright.feng@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 6f12d03fb62c..f2f6d46ac74d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -370,8 +370,10 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
eventmask_msg, msglen);
if (err) {
brcmf_err("Set event_msgs_ext error (%d)\n", err);
+ kfree(eventmask_msg);
goto done;
}
+ kfree(eventmask_msg);
}
/* Setup default scan channel time */
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
--
2.17.1

View File

@@ -0,0 +1,98 @@
From 5518040dff6a3287b8d5ac6b1d2707c2a86aeddf Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Mon, 22 Jun 2020 22:06:15 -0500
Subject: [PATCH 050/179] brcmfmac: fix invalid address access when enabling
SCAN log level
The variable i is changed when setting random MAC address and causes
invalid address access when printing the value of pi->reqs[i]->reqid.
We replace reqs index with ri to fix the issue.
[ 136.726473] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000
[ 136.737365] Mem abort info:
[ 136.740172] ESR = 0x96000004
[ 136.743359] Exception class = DABT (current EL), IL = 32 bits
[ 136.749294] SET = 0, FnV = 0
[ 136.752481] EA = 0, S1PTW = 0
[ 136.755635] Data abort info:
[ 136.758514] ISV = 0, ISS = 0x00000004
[ 136.762487] CM = 0, WnR = 0
[ 136.765522] user pgtable: 4k pages, 48-bit VAs, pgdp = 000000005c4e2577
[ 136.772265] [0000000000000000] pgd=0000000000000000
[ 136.777160] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[ 136.782732] Modules linked in: brcmfmac(O) brcmutil(O) cfg80211(O) compat(O)
[ 136.789788] Process wificond (pid: 3175, stack limit = 0x00000000053048fb)
[ 136.796664] CPU: 3 PID: 3175 Comm: wificond Tainted: G O 4.19.42-00001-g531a5f5 #1
[ 136.805532] Hardware name: Freescale i.MX8MQ EVK (DT)
[ 136.810584] pstate: 60400005 (nZCv daif +PAN -UAO)
[ 136.815429] pc : brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac]
[ 136.821811] lr : brcmf_pno_config_sched_scans+0x67c/0xa80 [brcmfmac]
[ 136.828162] sp : ffff00000e9a3880
[ 136.831475] x29: ffff00000e9a3890 x28: ffff800020543400
[ 136.836786] x27: ffff8000b1008880 x26: ffff0000012bf6a0
[ 136.842098] x25: ffff80002054345c x24: ffff800088d22400
[ 136.847409] x23: ffff0000012bf638 x22: ffff0000012bf6d8
[ 136.852721] x21: ffff8000aced8fc0 x20: ffff8000ac164400
[ 136.858032] x19: ffff00000e9a3946 x18: 0000000000000000
[ 136.863343] x17: 0000000000000000 x16: 0000000000000000
[ 136.868655] x15: ffff0000093f3b37 x14: 0000000000000050
[ 136.873966] x13: 0000000000003135 x12: 0000000000000000
[ 136.879277] x11: 0000000000000000 x10: ffff000009a61888
[ 136.884589] x9 : 000000000000000f x8 : 0000000000000008
[ 136.889900] x7 : 303a32303d726464 x6 : ffff00000a1f957d
[ 136.895211] x5 : 0000000000000000 x4 : ffff00000e9a3942
[ 136.900523] x3 : 0000000000000000 x2 : ffff0000012cead8
[ 136.905834] x1 : ffff0000012bf6d8 x0 : 0000000000000000
[ 136.911146] Call trace:
[ 136.913623] brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac]
[ 136.919658] brcmf_pno_start_sched_scan+0xa4/0x118 [brcmfmac]
[ 136.925430] brcmf_cfg80211_sched_scan_start+0x80/0xe0 [brcmfmac]
[ 136.931636] nl80211_start_sched_scan+0x140/0x308 [cfg80211]
[ 136.937298] genl_rcv_msg+0x358/0x3f4
[ 136.940960] netlink_rcv_skb+0xb4/0x118
[ 136.944795] genl_rcv+0x34/0x48
[ 136.947935] netlink_unicast+0x264/0x300
[ 136.951856] netlink_sendmsg+0x2e4/0x33c
[ 136.955781] __sys_sendto+0x120/0x19c
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
index fabfbb0b40b0..d0a7465be586 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
@@ -158,12 +158,12 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
struct brcmf_pno_macaddr_le pfn_mac;
u8 *mac_addr = NULL;
u8 *mac_mask = NULL;
- int err, i;
+ int err, i, ri;
- for (i = 0; i < pi->n_reqs; i++)
- if (pi->reqs[i]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
- mac_addr = pi->reqs[i]->mac_addr;
- mac_mask = pi->reqs[i]->mac_addr_mask;
+ for (ri = 0; ri < pi->n_reqs; ri++)
+ if (pi->reqs[ri]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
+ mac_addr = pi->reqs[ri]->mac_addr;
+ mac_mask = pi->reqs[ri]->mac_addr_mask;
break;
}
@@ -185,7 +185,7 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
pfn_mac.mac[0] |= 0x02;
brcmf_dbg(SCAN, "enabling random mac: reqid=%llu mac=%pM\n",
- pi->reqs[i]->reqid, pfn_mac.mac);
+ pi->reqs[ri]->reqid, pfn_mac.mac);
err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
sizeof(pfn_mac));
if (err)
--
2.17.1

View File

@@ -0,0 +1,260 @@
From 33cb664bde0b2ef35384720bcd3e018d98175d37 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Fri, 10 Jul 2020 04:37:31 -0500
Subject: [PATCH 051/179] brcmfmac: add a timer to read console periodically in
PCIE bus
Currently, host only reads console buffer when receiving mailbox data or
hit crash with PCIE bus. Therefore, we add timer in PCIE code to read
console buffer periodically to help developer and user check firmware
message when there is no data transmission between host and dongle.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/bus.h | 6 +
.../broadcom/brcm80211/brcmfmac/pcie.c | 127 ++++++++++++++++++
.../broadcom/brcm80211/brcmfmac/sdio.c | 2 -
3 files changed, 133 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index d78c2613d6f0..18e3a4286a5d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -23,6 +23,12 @@
#define BRCMF_NROF_COMMON_MSGRINGS (BRCMF_NROF_H2D_COMMON_MSGRINGS + \
BRCMF_NROF_D2H_COMMON_MSGRINGS)
+/* The interval to poll console */
+#define BRCMF_CONSOLE 10
+
+/* The maximum console interval value (5 mins) */
+#define MAX_CONSOLE_INTERVAL (5 * 60)
+
/* The level of bus communication with the dongle */
enum brcmf_bus_state {
BRCMF_BUS_DOWN, /* Not ready for frame transfers */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index ff03c282ea8f..c392914f6057 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -13,6 +13,8 @@
#include <linux/bcma/bcma.h>
#include <linux/sched.h>
#include <linux/io.h>
+#include <linux/sched/signal.h>
+#include <linux/kthread.h>
#include <asm/unaligned.h>
#include <soc.h>
@@ -288,6 +290,11 @@ struct brcmf_pciedev_info {
#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
ulong bar1_size;
#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
+#ifdef DEBUG
+ u32 console_interval;
+ bool console_active;
+ struct timer_list timer;
+#endif
};
struct brcmf_pcie_ringbuf {
@@ -359,6 +366,10 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
static struct brcmf_fw_request *
brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo);
+static void
+brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active);
+static void brcmf_pcie_debugfs_create(struct device *dev);
+
#ifdef CONFIG_BRCMFMAC_PCIE_BARWIN_SZ
DEFINE_RAW_SPINLOCK(pcie_lock);
#endif /* CONFIG_BRCMFMAC_PCIE_BARWIN_SZ */
@@ -1586,6 +1597,11 @@ static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
static void brcmf_pcie_down(struct device *dev)
{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pciedev *pcie_bus_dev = bus_if->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo;
+
+ brcmf_pcie_fwcon_timer(devinfo, false);
}
static int brcmf_pcie_preinit(struct device *dev)
@@ -1727,6 +1743,7 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
.get_memdump = brcmf_pcie_get_memdump,
.get_fwname = brcmf_pcie_get_fwname,
.reset = brcmf_pcie_reset,
+ .debugfs_create = brcmf_pcie_debugfs_create,
};
@@ -2099,6 +2116,8 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
brcmf_pcie_bus_console_read(devinfo, false);
+ brcmf_pcie_fwcon_timer(devinfo, true);
+
return;
fail:
@@ -2138,6 +2157,105 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
return fwreq;
}
+#ifdef DEBUG
+static void
+brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active)
+{
+ if (!active) {
+ if (devinfo->console_active) {
+ del_timer_sync(&devinfo->timer);
+ devinfo->console_active = false;
+ }
+ return;
+ }
+
+ /* don't start the timer */
+ if (devinfo->state != BRCMFMAC_PCIE_STATE_UP ||
+ !devinfo->console_interval || !BRCMF_FWCON_ON())
+ return;
+
+ if (!devinfo->console_active) {
+ devinfo->timer.expires = jiffies + devinfo->console_interval;
+ add_timer(&devinfo->timer);
+ devinfo->console_active = true;
+ } else {
+ /* Reschedule the timer */
+ mod_timer(&devinfo->timer, jiffies + devinfo->console_interval);
+ }
+}
+
+static void
+brcmf_pcie_fwcon(struct timer_list *t)
+{
+ struct brcmf_pciedev_info *devinfo = from_timer(devinfo, t, timer);
+
+ if (!devinfo->console_active)
+ return;
+
+ brcmf_pcie_bus_console_read(devinfo, false);
+
+ /* Reschedule the timer if console interval is not zero */
+ mod_timer(&devinfo->timer, jiffies + devinfo->console_interval);
+}
+
+static int brcmf_pcie_console_interval_get(void *data, u64 *val)
+{
+ struct brcmf_pciedev_info *devinfo = data;
+
+ *val = devinfo->console_interval;
+
+ return 0;
+}
+
+static int brcmf_pcie_console_interval_set(void *data, u64 val)
+{
+ struct brcmf_pciedev_info *devinfo = data;
+
+ if (val > MAX_CONSOLE_INTERVAL)
+ return -EINVAL;
+
+ devinfo->console_interval = val;
+
+ if (!val && devinfo->console_active)
+ brcmf_pcie_fwcon_timer(devinfo, false);
+ else if (val)
+ brcmf_pcie_fwcon_timer(devinfo, true);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(brcmf_pcie_console_interval_fops,
+ brcmf_pcie_console_interval_get,
+ brcmf_pcie_console_interval_set,
+ "%llu\n");
+
+static void brcmf_pcie_debugfs_create(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pub *drvr = bus_if->drvr;
+ struct brcmf_pciedev *pcie_bus_dev = bus_if->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo;
+ struct dentry *dentry = brcmf_debugfs_get_devdir(drvr);
+
+ if (IS_ERR_OR_NULL(dentry))
+ return;
+
+ devinfo->console_interval = BRCMF_CONSOLE;
+
+ debugfs_create_file("console_interval", 0644, dentry, devinfo,
+ &brcmf_pcie_console_interval_fops);
+}
+
+#else
+void brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active)
+{
+}
+
+static void brcmf_pcie_debugfs_create(struct device *dev)
+{
+}
+#endif
+
static int
brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
@@ -2206,6 +2324,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret)
goto fail_bus;
+#ifdef DEBUG
+ /* Set up the fwcon timer */
+ timer_setup(&devinfo->timer, brcmf_pcie_fwcon, 0);
+#endif
fwreq = brcmf_pcie_prepare_fw_request(devinfo);
if (!fwreq) {
ret = -ENOMEM;
@@ -2251,6 +2373,8 @@ brcmf_pcie_remove(struct pci_dev *pdev)
devinfo = bus->bus_priv.pcie->devinfo;
+ brcmf_pcie_fwcon_timer(devinfo, false);
+
devinfo->state = BRCMFMAC_PCIE_STATE_DOWN;
if (devinfo->ci)
brcmf_pcie_intr_disable(devinfo);
@@ -2303,6 +2427,8 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
if (!retry && config->pm_state == BRCMF_CFG80211_PM_STATE_SUSPENDING)
brcmf_err(bus, "timed out wait for cfg80211 suspended\n");
+ brcmf_pcie_fwcon_timer(devinfo, false);
+
brcmf_bus_change_state(bus, BRCMF_BUS_DOWN);
devinfo->mbdata_completed = false;
@@ -2346,6 +2472,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
brcmf_bus_change_state(bus, BRCMF_BUS_UP);
brcmf_pcie_intr_enable(devinfo);
brcmf_pcie_hostready(devinfo);
+ brcmf_pcie_fwcon_timer(devinfo, true);
return 0;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 0cf906af03f6..6731159cd235 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -139,8 +139,6 @@ struct rte_console {
#define BRCMF_FIRSTREAD (1 << 6)
-#define BRCMF_CONSOLE 10 /* watchdog interval to poll console */
-
/* SBSDIO_DEVICE_CTL */
/* 1: device will assert busy signal when receiving CMD53 */
--
2.17.1

View File

@@ -0,0 +1,36 @@
From 54d419f1a1e74a5bfc1c9e91e9530dc03fbcd3ce Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Fri, 10 Jul 2020 04:38:46 -0500
Subject: [PATCH 052/179] brcmfmac: return error when getting invalid
max_flowrings from dongle
When firmware hit trap at initialization, host will read abnormal
max_flowrings number from dongle, and it will causes kernel panic when
doing iowrite to initialize dongle ring.
To detect this error at early stage, we directly return error when getting
invalid max_flowrings(>256).
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index c392914f6057..3c46a49b3b0e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -1396,6 +1396,10 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
BRCMF_NROF_H2D_COMMON_MSGRINGS;
max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
}
+ if (max_flowrings > 256) {
+ brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings);
+ return -EIO;
+ }
if (devinfo->dma_idx_sz != 0) {
bufsz = (max_submissionrings + max_completionrings) *
--
2.17.1

View File

@@ -0,0 +1,83 @@
From 34963d006498b5150e690a05127b2046edf2d02a Mon Sep 17 00:00:00 2001
From: Wataru Gohda <wataru.gohda@cypress.com>
Date: Fri, 19 Jun 2020 01:49:53 -0500
Subject: [PATCH 053/179] brcmfmac: Fix to add skb free for TIM update info
when tx is completed
The skb will be allocated to send TIM update info in brcmf_fws_tim_update.
Currently the skb will be freed when tx is failed but it will not be freed
when tx is completed successfully. The fix is to free the skb when tx is
completed always.
Signed-off-by: Wataru Gohda <wataru.gohda@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 3 +--
.../broadcom/brcm80211/brcmfmac/fwsignal.c | 15 +++++++++------
.../broadcom/brcm80211/brcmfmac/fwsignal.h | 3 ++-
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
index a04c29016d4b..4fefd8587e5c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
@@ -370,8 +370,7 @@ brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp,
/* await txstatus signal for firmware if active */
if (brcmf_fws_fc_active(bcdc->fws)) {
- if (!success)
- brcmf_fws_bustxfail(bcdc->fws, txp);
+ brcmf_fws_bustxcomplete(bcdc->fws, txp, success);
} else {
if (brcmf_proto_bcdc_hdrpull(bus_if->drvr, false, txp, &ifp))
brcmu_pkt_buf_free_skb(txp);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
index 4a9d8fbac44c..526cbd9248fb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -2521,7 +2521,8 @@ bool brcmf_fws_fc_active(struct brcmf_fws_info *fws)
return fws->fcmode != BRCMF_FWS_FCMODE_NONE;
}
-void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
+void brcmf_fws_bustxcomplete(struct brcmf_fws_info *fws, struct sk_buff *skb,
+ bool success)
{
u32 hslot;
@@ -2529,11 +2530,13 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
brcmu_pkt_buf_free_skb(skb);
return;
}
- brcmf_fws_lock(fws);
- hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
- brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0,
- 1);
- brcmf_fws_unlock(fws);
+ if (!success) {
+ brcmf_fws_lock(fws);
+ hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
+ brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
+ hslot, 0, 0, 1);
+ brcmf_fws_unlock(fws);
+ }
}
void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
index 50e424b5880d..c3b2d3691c43 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
@@ -40,7 +40,8 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb);
void brcmf_fws_reset_interface(struct brcmf_if *ifp);
void brcmf_fws_add_interface(struct brcmf_if *ifp);
void brcmf_fws_del_interface(struct brcmf_if *ifp);
-void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb);
+void brcmf_fws_bustxcomplete(struct brcmf_fws_info *fws, struct sk_buff *skb,
+ bool success);
void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked);
void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb, bool inirq);
--
2.17.1

View File

@@ -0,0 +1,31 @@
From cf0bf201b785121551405ff1d69e12cd7156a006 Mon Sep 17 00:00:00 2001
From: Wataru Gohda <wataru.gohda@cypress.com>
Date: Fri, 19 Jun 2020 01:16:09 -0500
Subject: [PATCH 054/179] brcmfmac: Fix to add brcmf_clear_assoc_ies when rmmod
Conn_info->req_ie/resp_ie is used to indicate the assoc_req_ies /
assoc_resp_ies to cfg80211 layer when connection is done. The buffer is
freed and allocated again at next connection establishment. The buffers
also needs to be freed at the timing of rmmod as well.
Signed-off-by: Wataru Gohda <wataru.gohda@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index d5543170f5cc..c09eb774a2bb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6641,6 +6641,7 @@ static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
cfg->dongle_up = false; /* dongle down */
brcmf_abort_scanning(cfg);
brcmf_deinit_priv_mem(cfg);
+ brcmf_clear_assoc_ies(cfg);
}
static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
--
2.17.1

View File

@@ -0,0 +1,65 @@
From 1b38a1cfc7823ec98ea9c95d604429b6c002823c Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Fri, 10 Jul 2020 04:46:05 -0500
Subject: [PATCH 055/179] brcmfmac: dump dongle memory when attaching failed
To enhance FW debugging, we add dongle memory dump when hitting attaching
failure with PCIE bus. It can help developer to get more information
about dongle trap reason and root cause.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++-
.../net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 10 +++++++---
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 5a86770a41bc..3be50e0dcb26 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1437,7 +1437,8 @@ void brcmf_fw_crashed(struct device *dev)
brcmf_dev_coredump(dev);
- schedule_work(&drvr->bus_reset);
+ if (drvr->bus_reset.func)
+ schedule_work(&drvr->bus_reset);
}
void brcmf_detach(struct device *dev)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 3c46a49b3b0e..21bf127499f6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -2046,13 +2046,14 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
struct brcmf_commonring **flowrings;
u32 i, nvram_len;
+ bus = dev_get_drvdata(dev);
+ pcie_bus_dev = bus->bus_priv.pcie;
+ devinfo = pcie_bus_dev->devinfo;
+
/* check firmware loading result */
if (ret)
goto fail;
- bus = dev_get_drvdata(dev);
- pcie_bus_dev = bus->bus_priv.pcie;
- devinfo = pcie_bus_dev->devinfo;
brcmf_pcie_attach(devinfo);
fw = fwreq->items[BRCMF_PCIE_FW_CODE].binary;
@@ -2125,6 +2126,9 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
return;
fail:
+ brcmf_err(bus, "Dongle setup failed\n");
+ brcmf_pcie_bus_console_read(devinfo, true);
+ brcmf_fw_crashed(dev);
device_release_driver(dev);
}
--
2.17.1

View File

@@ -0,0 +1,60 @@
From fa62ff729a94c8527db2cbf21e51b21a3106ab75 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Mon, 20 Jul 2020 02:44:36 -0500
Subject: [PATCH 056/179] brcmfmac: update address mode via test tool for AP
mode
When setting interface type to AP mode via IOCTL test tool, we should
update proto address mode as well. Without it, the firmware creates
flowing type to STA and get incorrect flowing ID. In softAP mode, it
causes device cannot ping to other STAs which are in power saving mode.
Fixes: 65b06108e57a ("brcmfmac: set net carrier on via test tool for AP mode")
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 2 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index c09eb774a2bb..e49dd3506c05 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -492,7 +492,7 @@ send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
return err;
}
-static void
+void
brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
{
struct brcmf_cfg80211_vif *vif;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 2fe90639e65b..86a7d8ac912e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -487,5 +487,5 @@ void brcmf_set_mpc(struct brcmf_if *ndev, int mpc);
void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg);
void brcmf_cfg80211_free_netdev(struct net_device *ndev);
bool brcmf_is_apmode_operating(struct wiphy *wiphy);
-
+void brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev);
#endif /* BRCMFMAC_CFG80211_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
index 0bad78d5f5c9..bf425d2c27bf 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
@@ -71,6 +71,7 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
} else {
ifp->vif->wdev.iftype = NL80211_IFTYPE_STATION;
}
+ brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
}
if (cmdhdr->set)
--
2.17.1

View File

@@ -0,0 +1,88 @@
From 29810edb2edff2e95a9011f76d8b8a165f6a7db4 Mon Sep 17 00:00:00 2001
From: Double Lo <double.lo@cypress.com>
Date: Wed, 29 Jul 2020 04:53:49 -0500
Subject: [PATCH 057/179] brcmfmac: load 54591 firmware for chip ID 0x4355
Use 54591 firmware for chip ID 0x4355.
Signed-off-by: Double Lo <double.lo@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/pcie.c | 19 +++----------------
.../broadcom/brcm80211/include/brcm_hw_ids.h | 3 ++-
2 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 21bf127499f6..5345f8fffd2b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -62,8 +62,7 @@ BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie");
BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie");
BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie");
BRCMF_FW_DEF(4371, "brcmfmac4371-pcie");
-CY_FW_DEF(4355, "cyfmac89459-pcie");
-CY_FW_DEF(54591, "cyfmac54591-pcie");
+CY_FW_DEF(4355, "cyfmac54591-pcie");
/* firmware config files */
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt");
@@ -93,7 +92,6 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C),
BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
BRCMF_FW_ENTRY(CY_CC_89459_CHIP_ID, 0xFFFFFFFF, 4355),
- BRCMF_FW_ENTRY(CY_CC_54591_CHIP_ID, 0xFFFFFFFF, 54591),
};
#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
@@ -1677,20 +1675,13 @@ static
int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
- struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
- struct brcmf_pciedev_info *devinfo = buspub->devinfo;
struct brcmf_fw_request *fwreq;
struct brcmf_fw_name fwnames[] = {
{ ext, fw_name },
};
u32 chip;
- if (devinfo->ci->chip == CY_CC_89459_CHIP_ID &&
- devinfo->pdev->device == CY_PCIE_54591_DEVICE_ID)
- chip = CY_CC_54591_CHIP_ID;
- else
- chip = bus_if->chip;
-
+ chip = bus_if->chip;
fwreq = brcmf_fw_alloc_request(chip, bus_if->chiprev,
brcmf_pcie_fwnames,
ARRAY_SIZE(brcmf_pcie_fwnames),
@@ -2142,11 +2133,7 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
};
u32 chip;
- if (devinfo->ci->chip == CY_CC_89459_CHIP_ID &&
- devinfo->pdev->device == CY_PCIE_54591_DEVICE_ID)
- chip = CY_CC_54591_CHIP_ID;
- else
- chip = devinfo->ci->chip;
+ chip = devinfo->ci->chip;
fwreq = brcmf_fw_alloc_request(chip, devinfo->ci->chiprev,
brcmf_pcie_fwnames,
ARRAY_SIZE(brcmf_pcie_fwnames),
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 6f35cfd7b16c..26cc84ae12d7 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -54,7 +54,8 @@
#define CY_CC_43012_CHIP_ID 43012
#define CY_CC_43752_CHIP_ID 43752
#define CY_CC_89459_CHIP_ID 0x4355
-#define CY_CC_54591_CHIP_ID 0x54591
+#define CY_CC_89459_CHIP_ID 0x4355
+
/* USB Device IDs */
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
--
2.17.1

View File

@@ -0,0 +1,137 @@
From c9c1f37c5acd7fd3e214fe402886ec4410dae1ce Mon Sep 17 00:00:00 2001
From: Kurt Lee <kurt.lee@cypress.com>
Date: Thu, 20 Aug 2020 03:07:02 -0500
Subject: [PATCH 058/179] brcmfmac: Fix interoperating DPP and other encryption
network access
1. If firmware supports 4-way handshake offload but not supports DPP
4-way offload, when user first connects encryption network, driver will
set "sup_wpa 1" to firmware, but it will further result in DPP
connection failure since firmware won't send EAPOL frame to host.
2. Fix DPP AP mode handling action frames.
3. For some firmware without fwsup support, the join procedure will be
skipped due to "sup_wpa" iovar returning not-support. Check the fwsup
feature before do such iovar.
Signed-off-by: Kurt Lee <kurt.lee@cypress.com>
Signed-off-by: Double Lo <double.lo@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 68 ++++++++++---------
.../broadcom/brcm80211/brcmfmac/p2p.c | 5 ++
2 files changed, 42 insertions(+), 31 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index e49dd3506c05..19b941bf3b70 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2151,44 +2151,50 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
goto done;
}
- if (sme->crypto.psk &&
- profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
- if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
- err = -EINVAL;
- goto done;
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) {
+ if (sme->crypto.psk) {
+ if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
+ if (WARN_ON(profile->use_fwsup !=
+ BRCMF_PROFILE_FWSUP_NONE)) {
+ err = -EINVAL;
+ goto done;
+ }
+ brcmf_dbg(INFO, "using PSK offload\n");
+ profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
+ }
+ } else {
+ profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
}
- brcmf_dbg(INFO, "using PSK offload\n");
- profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
- }
- if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
- /* enable firmware supplicant for this interface */
- err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
- if (err < 0) {
- bphy_err(drvr, "failed to enable fw supplicant\n");
- goto done;
+ if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
+ /* enable firmware supplicant for this interface */
+ err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
+ if (err < 0) {
+ bphy_err(drvr, "failed to enable fw supplicant\n");
+ goto done;
+ }
+ } else {
+ err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 0);
}
- }
- if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
- err = brcmf_set_pmk(ifp, sme->crypto.psk,
- BRCMF_WSEC_MAX_PSK_LEN);
- else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
- /* clean up user-space RSNE */
- err = brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0);
- if (err) {
- bphy_err(drvr, "failed to clean up user-space RSNE\n");
- goto done;
- }
- err = brcmf_set_sae_password(ifp, sme->crypto.sae_pwd,
- sme->crypto.sae_pwd_len);
- if (!err && sme->crypto.psk)
+ if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
err = brcmf_set_pmk(ifp, sme->crypto.psk,
BRCMF_WSEC_MAX_PSK_LEN);
+ else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
+ /* clean up user-space RSNE */
+ if (brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0)) {
+ bphy_err(drvr, "failed to clean up user-space RSNE\n");
+ goto done;
+ }
+ err = brcmf_set_sae_password(ifp, sme->crypto.sae_pwd,
+ sme->crypto.sae_pwd_len);
+ if (!err && sme->crypto.psk)
+ err = brcmf_set_pmk(ifp, sme->crypto.psk,
+ BRCMF_WSEC_MAX_PSK_LEN);
+ }
+ if (err)
+ goto done;
}
- if (err)
- goto done;
-
/* Join with specific BSSID and cached SSID
* If SSID is zero join based on BSSID only
*/
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 7ca37aee1783..1d5352eeecec 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -1320,6 +1320,10 @@ static s32 brcmf_p2p_abort_action_frame(struct brcmf_cfg80211_info *cfg)
brcmf_dbg(TRACE, "Enter\n");
vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
+
+ if (!vif)
+ vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
+
err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe_abort", &int_val,
sizeof(s32));
if (err)
@@ -1869,6 +1873,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
/* validate channel and p2p ies */
if (config_af_params.search_channel &&
IS_P2P_SOCIAL_CHANNEL(le32_to_cpu(af_params->channel)) &&
+ p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif &&
p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->saved_ie.probe_req_ie_len) {
afx_hdl = &p2p->afx_hdl;
afx_hdl->peer_listen_chan = le32_to_cpu(af_params->channel);
--
2.17.1

View File

@@ -0,0 +1,63 @@
From 75634632240b400d1448753e4a617f4da5aa31ab Mon Sep 17 00:00:00 2001
From: Raveendran Somu <raveendran.somu@cypress.com>
Date: Tue, 11 Aug 2020 20:30:23 -0500
Subject: [PATCH 059/179] brcmfmac: fix SDIO bus errors during high-temp tests
Below error message was observed during the 85degC test runs.
brcmf_sdio_readframes: read 104 bytes from channel 2 failed: -84
Setting appropriate sdio watermark to address the issue.
Also fix the error "brcmf_fws_hanger_poppkt: entry not in use" during
the test, this is due to the state was updated before retrieving the skb
to free it.
Signed-off-by: Raveendran Somu <raveendran.somu@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 1 -
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 8 +++++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
index 526cbd9248fb..8723ecfb810a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -638,7 +638,6 @@ static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q,
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
hi = &fws->hanger.items[hslot];
WARN_ON(skb != hi->pkt);
- hi->state = BRCMF_FWS_HANGER_ITEM_STATE_FREE;
brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
true);
brcmu_pkt_buf_free_skb(skb);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 6731159cd235..bd1e5842dc3d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -45,8 +45,10 @@
/* watermark expressed in number of words */
#define DEFAULT_F2_WATERMARK 0x8
-#define CY_4373_F2_WATERMARK 0x40
-#define CY_4373_F1_MESBUSYCTRL (CY_4373_F2_WATERMARK | SBSDIO_MESBUSYCTRL_ENAB)
+#define CY_4373_F2_WATERMARK 0x4C
+#define CY_4373_MES_WATERMARK 0x44
+#define CY_4373_MESBUSYCTRL (CY_4373_MES_WATERMARK | \
+ SBSDIO_MESBUSYCTRL_ENAB)
#define CY_43012_F2_WATERMARK 0x60
#define CY_43012_MES_WATERMARK 0x50
#define CY_43012_MESBUSYCTRL (CY_43012_MES_WATERMARK | \
@@ -4486,7 +4488,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl,
&err);
brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_MESBUSYCTRL,
- CY_4373_F1_MESBUSYCTRL, &err);
+ CY_4373_MESBUSYCTRL, &err);
break;
case SDIO_DEVICE_ID_BROADCOM_CYPRESS_43012:
brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n",
--
2.17.1

View File

@@ -0,0 +1,349 @@
From b2b2aa897a88b4d9405068a3edfd68c92dfbf745 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Mon, 24 Aug 2020 02:51:00 -0500
Subject: [PATCH 060/179] brcmfmac: Add dump_survey cfg80211 ops for HostApd
AutoChannelSelection
To enable ACS feature in Hostap daemon, dump_survey cfg80211 ops and dump
obss survey command in firwmare side are needed. This patch is for adding
dump_survey feature and adding DUMP_OBSS feature flag to check if
firmware supports dump_obss iovar.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 256 ++++++++++++++++++
.../broadcom/brcm80211/brcmfmac/feature.c | 3 +-
.../broadcom/brcm80211/brcmfmac/feature.h | 4 +-
3 files changed, 261 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 19b941bf3b70..b1b875b2a935 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -90,9 +90,39 @@
#define BRCMF_PS_MAX_TIMEOUT_MS 2000
+/* Dump obss definitions */
+#define ACS_MSRMNT_DELAY 100
+#define CHAN_NOISE_DUMMY (-80)
+#define OBSS_TOKEN_IDX 15
+#define IBSS_TOKEN_IDX 15
+#define TX_TOKEN_IDX 14
+#define CTG_TOKEN_IDX 13
+#define PKT_TOKEN_IDX 15
+#define IDLE_TOKEN_IDX 12
+
#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
+struct brcmf_dump_survey {
+ u32 obss;
+ u32 ibss;
+ u32 no_ctg;
+ u32 no_pckt;
+ u32 tx;
+ u32 idle;
+};
+
+struct cca_stats_n_flags {
+ u32 msrmnt_time; /* Time for Measurement (msec) */
+ u32 msrmnt_done; /* flag set when measurement complete */
+ char buf[1];
+};
+
+struct cca_msrmnt_query {
+ u32 msrmnt_query;
+ u32 time_req;
+};
+
static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
{
if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
@@ -7777,6 +7807,227 @@ static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
return 0;
}
+static int
+brcmf_parse_dump_obss(char *buf, struct brcmf_dump_survey *survey)
+{
+ int i;
+ char *token;
+ char delim[] = "\n ";
+ unsigned long val;
+ int err = 0;
+
+ token = strsep(&buf, delim);
+ while (token) {
+ if (!strcmp(token, "OBSS")) {
+ for (i = 0; i < OBSS_TOKEN_IDX; i++)
+ token = strsep(&buf, delim);
+ err = kstrtoul(token, 10, &val);
+ survey->obss = val;
+ }
+
+ if (!strcmp(token, "IBSS")) {
+ for (i = 0; i < IBSS_TOKEN_IDX; i++)
+ token = strsep(&buf, delim);
+ err = kstrtoul(token, 10, &val);
+ survey->ibss = val;
+ }
+
+ if (!strcmp(token, "TXDur")) {
+ for (i = 0; i < TX_TOKEN_IDX; i++)
+ token = strsep(&buf, delim);
+ err = kstrtoul(token, 10, &val);
+ survey->tx = val;
+ }
+
+ if (!strcmp(token, "Category")) {
+ for (i = 0; i < CTG_TOKEN_IDX; i++)
+ token = strsep(&buf, delim);
+ err = kstrtoul(token, 10, &val);
+ survey->no_ctg = val;
+ }
+
+ if (!strcmp(token, "Packet")) {
+ for (i = 0; i < PKT_TOKEN_IDX; i++)
+ token = strsep(&buf, delim);
+ err = kstrtoul(token, 10, &val);
+ survey->no_pckt = val;
+ }
+
+ if (!strcmp(token, "Opp(time):")) {
+ for (i = 0; i < IDLE_TOKEN_IDX; i++)
+ token = strsep(&buf, delim);
+ err = kstrtoul(token, 10, &val);
+ survey->idle = val;
+ }
+
+ token = strsep(&buf, delim);
+
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+brcmf_dump_obss(struct brcmf_if *ifp, struct cca_msrmnt_query req,
+ struct brcmf_dump_survey *survey)
+{
+ struct cca_stats_n_flags *results;
+ char *buf;
+ int err;
+
+ buf = kzalloc(sizeof(char) * BRCMF_DCMD_MEDLEN, GFP_KERNEL);
+ if (unlikely(!buf)) {
+ brcmf_err("%s: buf alloc failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ memcpy(buf, &req, sizeof(struct cca_msrmnt_query));
+ err = brcmf_fil_iovar_data_get(ifp, "dump_obss",
+ buf, BRCMF_DCMD_MEDLEN);
+ if (err < 0) {
+ brcmf_err("dump_obss error (%d)\n", err);
+ goto exit;
+ }
+ results = (struct cca_stats_n_flags *)(buf);
+
+ if (req.msrmnt_query)
+ brcmf_parse_dump_obss(results->buf, survey);
+
+ kfree(buf);
+ return 0;
+exit:
+ kfree(buf);
+ return -EINVAL;
+}
+
+static s32
+cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type)
+{
+ u16 chspec = 0;
+ int err = 0;
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
+
+ /* set_channel */
+ chspec = channel_to_chanspec(&cfg->d11inf, chan);
+ if (chspec != INVCHANSPEC) {
+ err = brcmf_fil_iovar_int_set(ifp, "chanspec", chspec);
+ if (err)
+ err = -EINVAL;
+ } else {
+ brcmf_err("failed to convert host chanspec to fw chanspec\n");
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+static int
+brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
+ int idx, struct survey_info *info)
+{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
+ struct brcmf_dump_survey *survey;
+ struct ieee80211_supported_band *band;
+ struct ieee80211_channel *chan;
+ struct cca_msrmnt_query req;
+ u32 val, noise;
+ int err;
+
+ brcmf_dbg(TRACE, "Enter: channel idx=%d\n", idx);
+
+ band = wiphy->bands[NL80211_BAND_2GHZ];
+ if (band && idx >= band->n_channels) {
+ idx -= band->n_channels;
+ band = NULL;
+ }
+
+ if (!band || idx >= band->n_channels) {
+ band = wiphy->bands[NL80211_BAND_5GHZ];
+ if (idx >= band->n_channels)
+ return -ENOENT;
+ }
+
+ /* Setting current channel to the requested channel */
+ chan = &band->channels[idx];
+ err = cfg80211_set_channel(wiphy, ndev, chan, NL80211_CHAN_HT20);
+ if (err) {
+ info->channel = chan;
+ info->filled = 0;
+ return 0;
+ }
+
+ if (!idx) {
+ /* Disable mpc */
+ val = 0;
+ brcmf_set_mpc(ifp, val);
+ /* Set interface up, explicitly. */
+ val = 1;
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, val);
+ if (err) {
+ brcmf_err("BRCMF_C_UP error (%d)\n", err);
+ return -EIO;
+ }
+ }
+
+ /* Get noise value */
+ err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PHY_NOISE, &noise);
+ if (err) {
+ brcmf_err("Get Phy Noise failed, error = %d\n", err);
+ noise = CHAN_NOISE_DUMMY;
+ }
+
+ survey = kzalloc(sizeof(*survey), GFP_KERNEL);
+ if (unlikely(!survey)) {
+ brcmf_err("%s: alloc failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Start Measurement for obss stats on current channel */
+ req.msrmnt_query = 0;
+ req.time_req = ACS_MSRMNT_DELAY;
+ err = brcmf_dump_obss(ifp, req, survey);
+ if (err)
+ goto exit;
+
+ /* Add 10 ms for IOVAR completion */
+ msleep(ACS_MSRMNT_DELAY + 10);
+
+ /* Issue IOVAR to collect measurement results */
+ req.msrmnt_query = 1;
+ err = brcmf_dump_obss(ifp, req, survey);
+ if (err < 0)
+ goto exit;
+
+ info->channel = chan;
+ info->noise = noise;
+ info->time = ACS_MSRMNT_DELAY;
+ info->time_busy = ACS_MSRMNT_DELAY - survey->idle;
+ info->time_rx = survey->obss + survey->ibss + survey->no_ctg +
+ survey->no_pckt;
+ info->time_tx = survey->tx;
+ info->filled = SURVEY_INFO_NOISE_DBM | SURVEY_INFO_TIME |
+ SURVEY_INFO_TIME_BUSY | SURVEY_INFO_TIME_RX |
+ SURVEY_INFO_TIME_TX;
+
+ brcmf_dbg(INFO, "OBSS dump: channel %d: survey duraion %d\n",
+ ieee80211_frequency_to_channel(chan->center_freq),
+ ACS_MSRMNT_DELAY);
+ brcmf_dbg(INFO, "noise(%d) busy(%llu) rx(%llu) tx(%llu)\n",
+ info->noise, info->time_busy, info->time_rx, info->time_tx);
+
+ kfree(survey);
+ return 0;
+exit:
+ kfree(survey);
+ return err;
+}
+
static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *req)
{
@@ -7930,6 +8181,11 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
#endif
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DUMP_OBSS))
+ ops->dump_survey = brcmf_cfg80211_dump_survey;
+ else
+ ops->dump_survey = NULL;
+
err = wiphy_register(wiphy);
if (err < 0) {
bphy_err(drvr, "Could not register wiphy device (%d)\n", err);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 2733977b07a8..f483f0a3f8dd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -142,7 +142,7 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
ifp->fwil_fwerr = true;
err = brcmf_fil_iovar_int_get(ifp, name, &data);
- if (err == 0) {
+ if (err != -BRCMF_FW_UNSUPPORTED) {
brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
ifp->drvr->feat_flags |= BIT(id);
} else {
@@ -278,6 +278,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MFP, "mfp");
+ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_DUMP_OBSS, "dump_obss");
pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
err = brcmf_fil_iovar_data_get(ifp, "pfn_macaddr", &pfn_mac,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
index d1f4257af696..f1b086a69d73 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
@@ -29,6 +29,7 @@
* DOT11H: firmware supports 802.11h
* SAE: simultaneous authentication of equals
* FWAUTH: Firmware authenticator
+ * DUMP_OBSS: Firmware has capable to dump obss info to support ACS
*/
#define BRCMF_FEAT_LIST \
BRCMF_FEAT_DEF(MBSS) \
@@ -51,7 +52,8 @@
BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) \
BRCMF_FEAT_DEF(DOT11H) \
BRCMF_FEAT_DEF(SAE) \
- BRCMF_FEAT_DEF(FWAUTH)
+ BRCMF_FEAT_DEF(FWAUTH) \
+ BRCMF_FEAT_DEF(DUMP_OBSS)
/*
* Quirks:
--
2.17.1

View File

@@ -0,0 +1,40 @@
From a17b92baec44ce27ca9df9e13d2a33707011474c Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Wed, 26 Aug 2020 02:06:19 -0500
Subject: [PATCH 061/179] revert: brcmfmac: set state of hanger slot to FREE
when flushing PSQ
Revert this change because it is conflict with upstream
commit c80d26e81ef1 ("brcmfmac: fix WARNING during USB disconnect in
case of unempty psq")
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
index 8723ecfb810a..8d41be637760 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -624,7 +624,6 @@ static inline int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h,
static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q,
int ifidx)
{
- struct brcmf_fws_hanger_item *hi;
bool (*matchfn)(struct sk_buff *, void *) = NULL;
struct sk_buff *skb;
int prec;
@@ -636,8 +635,6 @@ static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q,
skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx);
while (skb) {
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
- hi = &fws->hanger.items[hslot];
- WARN_ON(skb != hi->pkt);
brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
true);
brcmu_pkt_buf_free_skb(skb);
--
2.17.1

View File

@@ -0,0 +1,39 @@
From 5a6b817fc45ca7eec69e4af1302f551fda0360f9 Mon Sep 17 00:00:00 2001
From: Brian Henriquez <brian.henriquez@cypress.com>
Date: Wed, 21 Oct 2020 23:50:23 -0500
Subject: [PATCH 062/179] brcmfmac: correctly remove all p2p vif
When deleting a P2P AGO interface we should make sure that
relevant entry in bss_idx[] array is removed. We were always
removing only 'vif' at P2PAPI_BSSCFG_CONNECTION before,
regardless of the number of created P2P AGO interfaces.
brcmfmac: correctly remove all p2p vif
Signed-off-by: Brian Henriquez <brian.henriquez@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 1d5352eeecec..a614d0cf583e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -2472,8 +2472,12 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
brcmf_remove_interface(vif->ifp, true);
brcmf_cfg80211_arm_vif_event(cfg, NULL);
- if (iftype != NL80211_IFTYPE_P2P_DEVICE)
- p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
+ if (iftype != NL80211_IFTYPE_P2P_DEVICE) {
+ if (vif == p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif)
+ p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
+ if (vif == p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION2].vif)
+ p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION2].vif = NULL;
+ }
return err;
}
--
2.17.1

View File

@@ -0,0 +1,138 @@
From f1ba291a15f975f33a8079c9048e37ddd1938e5d Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Fri, 23 Oct 2020 03:27:49 -0500
Subject: [PATCH 063/179] brcmfmac: fix firmware trap while dumping obss stats
When doing dump_survey, host will call "dump_obss" iovar to firmware
side. Host need to make sure the HW clock in dongle is on, or there is
high probability that firmware gets trap because register or shared
memory access failed. To fix this, we disable mpc when doing dump obss
and set it back after that.
[28350.512799] brcmfmac: brcmf_dump_obss: dump_obss error (-52)
[28743.402314] ieee80211 phy0: brcmf_fw_crashed: Firmware has halted or
crashed
[28745.869430] brcmfmac: brcmf_sdio_bus_rxctl: resumed on timeout
[28745.877546] brcmfmac: brcmf_sdio_checkdied: firmware trap in dongle
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 49 ++++++++-----------
1 file changed, 21 insertions(+), 28 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index b1b875b2a935..32d0f194a1af 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -7878,16 +7878,15 @@ brcmf_dump_obss(struct brcmf_if *ifp, struct cca_msrmnt_query req,
int err;
buf = kzalloc(sizeof(char) * BRCMF_DCMD_MEDLEN, GFP_KERNEL);
- if (unlikely(!buf)) {
- brcmf_err("%s: buf alloc failed\n", __func__);
+ if (!buf)
return -ENOMEM;
- }
memcpy(buf, &req, sizeof(struct cca_msrmnt_query));
err = brcmf_fil_iovar_data_get(ifp, "dump_obss",
buf, BRCMF_DCMD_MEDLEN);
- if (err < 0) {
+ if (err) {
brcmf_err("dump_obss error (%d)\n", err);
+ err = -EINVAL;
goto exit;
}
results = (struct cca_stats_n_flags *)(buf);
@@ -7895,11 +7894,9 @@ brcmf_dump_obss(struct brcmf_if *ifp, struct cca_msrmnt_query req,
if (req.msrmnt_query)
brcmf_parse_dump_obss(results->buf, survey);
- kfree(buf);
- return 0;
exit:
kfree(buf);
- return -EINVAL;
+ return err;
}
static s32
@@ -7936,7 +7933,7 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
struct ieee80211_supported_band *band;
struct ieee80211_channel *chan;
struct cca_msrmnt_query req;
- u32 val, noise;
+ u32 noise;
int err;
brcmf_dbg(TRACE, "Enter: channel idx=%d\n", idx);
@@ -7962,31 +7959,27 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
return 0;
}
- if (!idx) {
- /* Disable mpc */
- val = 0;
- brcmf_set_mpc(ifp, val);
- /* Set interface up, explicitly. */
- val = 1;
- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, val);
- if (err) {
- brcmf_err("BRCMF_C_UP error (%d)\n", err);
- return -EIO;
- }
+ survey = kzalloc(sizeof(*survey), GFP_KERNEL);
+ if (!survey)
+ return -ENOMEM;
+
+ /* Disable mpc */
+ brcmf_set_mpc(ifp, 0);
+
+ /* Set interface up, explicitly. */
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
+ if (err) {
+ brcmf_err("set interface up failed, err = %d\n", err);
+ goto exit;
}
/* Get noise value */
err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PHY_NOISE, &noise);
if (err) {
- brcmf_err("Get Phy Noise failed, error = %d\n", err);
+ brcmf_err("Get Phy Noise failed, use dummy value\n");
noise = CHAN_NOISE_DUMMY;
}
- survey = kzalloc(sizeof(*survey), GFP_KERNEL);
- if (unlikely(!survey)) {
- brcmf_err("%s: alloc failed\n", __func__);
- return -ENOMEM;
- }
/* Start Measurement for obss stats on current channel */
req.msrmnt_query = 0;
@@ -8001,7 +7994,7 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
/* Issue IOVAR to collect measurement results */
req.msrmnt_query = 1;
err = brcmf_dump_obss(ifp, req, survey);
- if (err < 0)
+ if (err)
goto exit;
info->channel = chan;
@@ -8021,9 +8014,9 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
brcmf_dbg(INFO, "noise(%d) busy(%llu) rx(%llu) tx(%llu)\n",
info->noise, info->time_busy, info->time_rx, info->time_tx);
- kfree(survey);
- return 0;
exit:
+ if (!brcmf_is_apmode(ifp->vif))
+ brcmf_set_mpc(ifp, 1);
kfree(survey);
return err;
}
--
2.17.1

View File

@@ -0,0 +1,193 @@
From 85ad35189b57ebe05de3b87a05d170f9bb613ab3 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Tue, 26 Jun 2018 22:19:31 -0500
Subject: [PATCH 064/179] brcmfmac: add creating station interface support
With RSDB device, it is able to control two station interfaces
concurrently. So we add creating station interface support and
allow user to create it via cfg80211.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 80 ++++++++++++++++---
.../broadcom/brcm80211/brcmfmac/core.h | 1 +
2 files changed, 69 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 32d0f194a1af..a0d9454664e2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -269,6 +269,19 @@ struct parsed_vndr_ies {
#define WLC_E_IF_ROLE_STA 0 /* Infra STA */
#define WLC_E_IF_ROLE_AP 1 /* Access Point */
+#define WL_INTERFACE_MAC_DONT_USE 0x0
+#define WL_INTERFACE_MAC_USE 0x2
+
+#define WL_INTERFACE_CREATE_STA 0x0
+#define WL_INTERFACE_CREATE_AP 0x1
+
+struct wl_interface_create {
+ u16 ver;
+ u32 flags;
+ u8 mac_addr[ETH_ALEN];
+ u8 pad[13];
+};
+
static u8 nl80211_band_to_fwil(enum nl80211_band band)
{
switch (band) {
@@ -556,6 +569,42 @@ static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
return -ENOMEM;
}
+static void brcmf_set_sta_iface_macaddr(struct brcmf_if *ifp,
+ struct wl_interface_create *iface)
+{
+ u8 mac_idx = ifp->drvr->sta_mac_idx;
+
+ /* set difference MAC address with locally administered bit */
+ iface->flags |= WL_INTERFACE_MAC_USE;
+ memcpy(iface->mac_addr, ifp->mac_addr, ETH_ALEN);
+ iface->mac_addr[0] |= 0x02;
+ iface->mac_addr[3] ^= mac_idx ? 0xC0 : 0xA0;
+ mac_idx++;
+ mac_idx = mac_idx % 2;
+ ifp->drvr->sta_mac_idx = mac_idx;
+}
+
+static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr)
+{
+ struct wl_interface_create iface;
+ int err;
+
+ memset(&iface, 0, sizeof(iface));
+
+ iface.ver = 0;
+ iface.flags = WL_INTERFACE_CREATE_STA;
+ if (!is_zero_ether_addr(macaddr)) {
+ /* set MAC address in cfg80211 params */
+ memcpy(iface.mac_addr, macaddr, ETH_ALEN);
+ } else {
+ brcmf_set_sta_iface_macaddr(ifp, &iface);
+ }
+
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create", &iface,
+ sizeof(iface));
+ return err;
+}
+
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
{
struct brcmf_pub *drvr = ifp->drvr;
@@ -581,15 +630,16 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
}
/**
- * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
+ * brcmf_ap_add_vif() - create a new AP or STA virtual interface
*
* @wiphy: wiphy device of new interface.
* @name: name of the new interface.
- * @params: contains mac address for AP device.
+ * @params: contains mac address for AP or STA device.
*/
static
-struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
- struct vif_params *params)
+struct wireless_dev *brcmf_apsta_add_vif(struct wiphy *wiphy, const char *name,
+ struct vif_params *params,
+ enum nl80211_iftype type)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
@@ -597,18 +647,24 @@ struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
struct brcmf_cfg80211_vif *vif;
int err;
+ if (type != NL80211_IFTYPE_STATION && type != NL80211_IFTYPE_AP)
+ return ERR_PTR(-EINVAL);
+
if (brcmf_cfg80211_vif_event_armed(cfg))
return ERR_PTR(-EBUSY);
brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
- vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
+ vif = brcmf_alloc_vif(cfg, type);
if (IS_ERR(vif))
return (struct wireless_dev *)vif;
brcmf_cfg80211_arm_vif_event(cfg, vif);
- err = brcmf_cfg80211_request_ap_if(ifp);
+ if (type == NL80211_IFTYPE_STATION)
+ err = brcmf_cfg80211_request_sta_if(ifp, params->macaddr);
+ else
+ err = brcmf_cfg80211_request_ap_if(ifp);
if (err) {
brcmf_cfg80211_arm_vif_event(cfg, NULL);
goto fail;
@@ -755,15 +811,15 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
}
switch (type) {
case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_MESH_POINT:
return ERR_PTR(-EOPNOTSUPP);
case NL80211_IFTYPE_MONITOR:
return brcmf_mon_add_vif(wiphy, name);
+ case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_AP:
- wdev = brcmf_ap_add_vif(wiphy, name, params);
+ wdev = brcmf_apsta_add_vif(wiphy, name, params, type);
break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_P2P_GO:
@@ -898,8 +954,8 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
return err;
}
-static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
- struct wireless_dev *wdev)
+static int brcmf_cfg80211_del_apsta_iface(struct wiphy *wiphy,
+ struct wireless_dev *wdev)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = wdev->netdev;
@@ -956,15 +1012,15 @@ int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
switch (wdev->iftype) {
case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_MESH_POINT:
return -EOPNOTSUPP;
case NL80211_IFTYPE_MONITOR:
return brcmf_mon_del_vif(wiphy, wdev);
+ case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_AP:
- return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
+ return brcmf_cfg80211_del_apsta_iface(wiphy, wdev);
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_P2P_DEVICE:
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index c29ae6be1eaf..c0e35ce686f1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -138,6 +138,7 @@ struct brcmf_pub {
u8 clmver[BRCMF_DCMD_SMLEN];
struct brcmf_pkt_filter_enable_le pkt_filter[MAX_PKT_FILTER_COUNT];
+ u8 sta_mac_idx;
};
--
2.17.1

View File

@@ -0,0 +1,232 @@
From 36d29fdfdd46ec717b40976214a84089cb6553d6 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Wed, 7 Nov 2018 21:27:46 -0600
Subject: [PATCH 065/179] brcmfmac: support station interface creation version
1, 2 and 3
To create virtual station interface for RSDB and VSDB, we add interface
creation version 1, 2 and 3 supports
The structures of each version are different and only version 3 and
later version are able to get interface creating version from firmware
side.
The patch has been verified two concurrent stations pings test with
interface create version 1:
89342(4359b1)-PCIE: 9.40.100
interface create version 2:
4373a0-sdio: 13.10.271
interface create version 3:
4373a0-sdio: 13.35.48
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 148 +++++++++++++++---
1 file changed, 124 insertions(+), 24 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index a0d9454664e2..e765f8e3cb1c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -269,17 +269,46 @@ struct parsed_vndr_ies {
#define WLC_E_IF_ROLE_STA 0 /* Infra STA */
#define WLC_E_IF_ROLE_AP 1 /* Access Point */
+#define WL_INTERFACE_CREATE_VER_1 1
+#define WL_INTERFACE_CREATE_VER_2 2
+#define WL_INTERFACE_CREATE_VER_3 3
+#define WL_INTERFACE_CREATE_VER_MAX WL_INTERFACE_CREATE_VER_3
+
#define WL_INTERFACE_MAC_DONT_USE 0x0
#define WL_INTERFACE_MAC_USE 0x2
#define WL_INTERFACE_CREATE_STA 0x0
#define WL_INTERFACE_CREATE_AP 0x1
-struct wl_interface_create {
- u16 ver;
- u32 flags;
- u8 mac_addr[ETH_ALEN];
- u8 pad[13];
+struct wl_interface_create_v1 {
+ u16 ver; /* structure version */
+ u32 flags; /* flags for operation */
+ u8 mac_addr[ETH_ALEN]; /* MAC address */
+ u32 wlc_index; /* optional for wlc index */
+};
+
+struct wl_interface_create_v2 {
+ u16 ver; /* structure version */
+ u8 pad1[2];
+ u32 flags; /* flags for operation */
+ u8 mac_addr[ETH_ALEN]; /* MAC address */
+ u8 iftype; /* type of interface created */
+ u8 pad2;
+ u32 wlc_index; /* optional for wlc index */
+};
+
+struct wl_interface_create_v3 {
+ u16 ver; /* structure version */
+ u16 len; /* length of structure + data */
+ u16 fixed_len; /* length of structure */
+ u8 iftype; /* type of interface created */
+ u8 wlc_index; /* optional for wlc index */
+ u32 flags; /* flags for operation */
+ u8 mac_addr[ETH_ALEN]; /* MAC address */
+ u8 bssid[ETH_ALEN]; /* optional for BSSID */
+ u8 if_index; /* interface index request */
+ u8 pad[3];
+ u8 data[]; /* Optional for specific data */
};
static u8 nl80211_band_to_fwil(enum nl80211_band band)
@@ -569,16 +598,14 @@ static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
return -ENOMEM;
}
-static void brcmf_set_sta_iface_macaddr(struct brcmf_if *ifp,
- struct wl_interface_create *iface)
+static void brcmf_set_vif_sta_macaddr(struct brcmf_if *ifp, u8 *mac_addr)
{
u8 mac_idx = ifp->drvr->sta_mac_idx;
/* set difference MAC address with locally administered bit */
- iface->flags |= WL_INTERFACE_MAC_USE;
- memcpy(iface->mac_addr, ifp->mac_addr, ETH_ALEN);
- iface->mac_addr[0] |= 0x02;
- iface->mac_addr[3] ^= mac_idx ? 0xC0 : 0xA0;
+ memcpy(mac_addr, ifp->mac_addr, ETH_ALEN);
+ mac_addr[0] |= 0x02;
+ mac_addr[3] ^= mac_idx ? 0xC0 : 0xA0;
mac_idx++;
mac_idx = mac_idx % 2;
ifp->drvr->sta_mac_idx = mac_idx;
@@ -586,23 +613,96 @@ static void brcmf_set_sta_iface_macaddr(struct brcmf_if *ifp,
static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr)
{
- struct wl_interface_create iface;
+ struct wl_interface_create_v1 iface_v1;
+ struct wl_interface_create_v2 iface_v2;
+ struct wl_interface_create_v3 iface_v3;
+ u32 iface_create_ver;
int err;
- memset(&iface, 0, sizeof(iface));
+ /* interface_create version 1 */
+ memset(&iface_v1, 0, sizeof(iface_v1));
+ iface_v1.ver = WL_INTERFACE_CREATE_VER_1;
+ iface_v1.flags = WL_INTERFACE_CREATE_STA |
+ WL_INTERFACE_MAC_USE;
+ if (!is_zero_ether_addr(macaddr))
+ memcpy(iface_v1.mac_addr, macaddr, ETH_ALEN);
+ else
+ brcmf_set_vif_sta_macaddr(ifp, iface_v1.mac_addr);
- iface.ver = 0;
- iface.flags = WL_INTERFACE_CREATE_STA;
- if (!is_zero_ether_addr(macaddr)) {
- /* set MAC address in cfg80211 params */
- memcpy(iface.mac_addr, macaddr, ETH_ALEN);
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
+ &iface_v1,
+ sizeof(iface_v1));
+ if (err) {
+ brcmf_info("failed to create interface(v1), err=%d\n",
+ err);
} else {
- brcmf_set_sta_iface_macaddr(ifp, &iface);
+ brcmf_dbg(INFO, "interface created(v1)\n");
+ return 0;
}
- err = brcmf_fil_iovar_data_get(ifp, "interface_create", &iface,
- sizeof(iface));
- return err;
+ /* interface_create version 2 */
+ memset(&iface_v2, 0, sizeof(iface_v2));
+ iface_v2.ver = WL_INTERFACE_CREATE_VER_2;
+ iface_v2.flags = WL_INTERFACE_MAC_USE;
+ iface_v2.iftype = WL_INTERFACE_CREATE_STA;
+ if (!is_zero_ether_addr(macaddr))
+ memcpy(iface_v2.mac_addr, macaddr, ETH_ALEN);
+ else
+ brcmf_set_vif_sta_macaddr(ifp, iface_v2.mac_addr);
+
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
+ &iface_v2,
+ sizeof(iface_v2));
+ if (err) {
+ brcmf_info("failed to create interface(v2), err=%d\n",
+ err);
+ } else {
+ brcmf_dbg(INFO, "interface created(v2)\n");
+ return 0;
+ }
+
+ /* interface_create version 3+ */
+ /* get supported version from firmware side */
+ iface_create_ver = 0;
+ err = brcmf_fil_bsscfg_int_get(ifp, "interface_create",
+ &iface_create_ver);
+ if (err) {
+ brcmf_err("fail to get supported version, err=%d\n", err);
+ return -EOPNOTSUPP;
+ }
+
+ switch (iface_create_ver) {
+ case WL_INTERFACE_CREATE_VER_3:
+ memset(&iface_v3, 0, sizeof(iface_v3));
+ iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
+ iface_v3.flags = WL_INTERFACE_MAC_USE;
+ iface_v3.iftype = WL_INTERFACE_CREATE_STA;
+ if (!is_zero_ether_addr(macaddr))
+ memcpy(iface_v3.mac_addr, macaddr, ETH_ALEN);
+ else
+ brcmf_set_vif_sta_macaddr(ifp, iface_v3.mac_addr);
+
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
+ &iface_v3,
+ sizeof(iface_v3));
+
+ if (!err)
+ brcmf_dbg(INFO, "interface created(v3)\n");
+ break;
+ default:
+ brcmf_err("not support interface create(v%d)\n",
+ iface_create_ver);
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ if (err) {
+ brcmf_info("station interface creation failed (%d)\n",
+ err);
+ return -EIO;
+ }
+
+ return 0;
}
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
@@ -7301,7 +7401,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
*
* p2p, mchan, and mbss:
*
- * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
+ * #STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
* #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
* #AP <= 4, matching BI, channels = 1, 4 total
*
@@ -7347,7 +7447,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
goto err;
combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
- c0_limits[i].max = 1;
+ c0_limits[i].max = 1 + (p2p && mchan);
c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
if (mon_flag) {
c0_limits[i].max = 1;
--
2.17.1

View File

@@ -0,0 +1,37 @@
From ba08f9de18f048636239d33116f4d966a2709d27 Mon Sep 17 00:00:00 2001
From: Prasanna Kerekoppa <prasanna.kerekoppa@cypress.com>
Date: Wed, 4 Nov 2020 22:37:13 -0600
Subject: [PATCH 066/179] brcmfmac: To fix crash when platform does not contain
platform data/DTS
dev_get_platdata() will return NULL in this case which causes the NULL access
Some snippet of the dump below
[ 298.890591] Hardware name: Freescale i.MX8QXP MEK (DT) 22
[ 298.895734] task: ffff80083662a880 task.stack: ffff000028358000 23
[ 298.901865] PC is at brcmf_common_pd_probe+0x2c/0x68 [brcmfmac] 24
[ 298.907963] LR is at brcmf_common_pd_probe+0x24/0x68 [brcmfmac] 25
[ 298.913883] pc : [<ffff000000eee02c>] lr : [<ffff000000eee024>] pstate: 40000145 26
[ 298.921283] sp : ffff00002835baa0
Signed-off-by: Prasanna Kerekoppa <prasanna.kerekoppa@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index f2f6d46ac74d..2825d6575dc1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -534,7 +534,7 @@ static int __init brcmf_common_pd_probe(struct platform_device *pdev)
brcmfmac_pdata = dev_get_platdata(&pdev->dev);
- if (brcmfmac_pdata->power_on)
+ if (brcmfmac_pdata && brcmfmac_pdata->power_on)
brcmfmac_pdata->power_on();
return 0;
--
2.17.1

View File

@@ -0,0 +1,71 @@
From 629d4869b02725c86f09945e49f8b6c240d83c7b Mon Sep 17 00:00:00 2001
From: Ramesh Rangavittal <ramesh.rangavittal@infineon.com>
Date: Fri, 13 Nov 2020 09:48:26 -0600
Subject: [PATCH 067/179] brcmfmac: Remove the call to "dtim_assoc" IOVAR
When STA roams from one AP to another, after roam is complete, host
driver tries to get TIM information from firmware. This is no longer
supported in the firmware & hence, this call will always fail.
This failure results in the below message being displayed on the
console all the time when roam is done.
ieee80211 phy0: brcmf_update_bss_info: wl dtim_assoc failed (-52)
Changes ensure that the host driver will no longer try to get TIM
information from firmware.
Signed-off-by: Ramesh Rangavittal <ramesh.rangavittal@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 26 +------------------
1 file changed, 1 insertion(+), 25 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index e765f8e3cb1c..e6632733bd74 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3381,10 +3381,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
struct brcmf_if *ifp)
{
struct brcmf_pub *drvr = cfg->pub;
- struct brcmf_bss_info_le *bi;
- const struct brcmf_tlv *tim;
- size_t ie_len;
- u8 *ie;
+ struct brcmf_bss_info_le *bi = NULL;
s32 err = 0;
brcmf_dbg(TRACE, "Enter\n");
@@ -3398,29 +3395,8 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
bphy_err(drvr, "Could not get bss info %d\n", err);
goto update_bss_info_out;
}
-
bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
err = brcmf_inform_single_bss(cfg, bi);
- if (err)
- goto update_bss_info_out;
-
- ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
- ie_len = le32_to_cpu(bi->ie_length);
-
- tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
- if (!tim) {
- /*
- * active scan was done so we could not get dtim
- * information out of probe response.
- * so we speficially query dtim information to dongle.
- */
- u32 var;
- err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
- if (err) {
- bphy_err(drvr, "wl dtim_assoc failed (%d)\n", err);
- goto update_bss_info_out;
- }
- }
update_bss_info_out:
brcmf_dbg(TRACE, "Exit");
--
2.17.1

View File

@@ -0,0 +1,40 @@
From 61466ea09dadfdbf1124f6c69c32b30cfee4e70b Mon Sep 17 00:00:00 2001
From: Double Lo <double.lo@cypress.com>
Date: Tue, 15 Dec 2020 20:36:43 -0600
Subject: [PATCH 068/179] brcmfmac: fix CERT-P2P:5.1.10 failure
This patch fix CERT-P2P:5.1.10 failure at step 18 Group formation failed
due to chip is under dump survey. Decrease the dump survery duration to
pass this certification case.
Signed-off-by: Double Lo <Double.Lo@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index e6632733bd74..e981a9905572 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -91,7 +91,7 @@
#define BRCMF_PS_MAX_TIMEOUT_MS 2000
/* Dump obss definitions */
-#define ACS_MSRMNT_DELAY 100
+#define ACS_MSRMNT_DELAY 80
#define CHAN_NOISE_DUMMY (-80)
#define OBSS_TOKEN_IDX 15
#define IBSS_TOKEN_IDX 15
@@ -8140,7 +8140,7 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
SURVEY_INFO_TIME_BUSY | SURVEY_INFO_TIME_RX |
SURVEY_INFO_TIME_TX;
- brcmf_dbg(INFO, "OBSS dump: channel %d: survey duraion %d\n",
+ brcmf_dbg(INFO, "OBSS dump: channel %d: survey duration %d\n",
ieee80211_frequency_to_channel(chan->center_freq),
ACS_MSRMNT_DELAY);
brcmf_dbg(INFO, "noise(%d) busy(%llu) rx(%llu) tx(%llu)\n",
--
2.17.1

View File

@@ -0,0 +1,84 @@
From b258a24902ae911624661546cfb1f796efe9e95d Mon Sep 17 00:00:00 2001
From: Wataru Gohda <wataru.gohda@cypress.com>
Date: Thu, 17 Dec 2020 01:02:23 -0600
Subject: [PATCH 069/179] brcmfmac: Fix for when connect request is not success
Currently brcmfmac is expecting to be set for both
BRCMF_VIF_STATUS_EAP_SUCCESS and BRCMF_VIF_STATUS_EAP status bit based
on dongle event and those bits are cleared to complete connect request
successfully.
But when connect request is finished unsuccessfully, either
BRCMF_VIF_STATUS_EAP_SUCCESS / BRCMF_VIF_STATUS_EAP bits are not
cleared depending on how the connect fail event happens. These status
bits are carried over to following new connect request and this will lead
to generate below kernel warning for some case. Worst case status
mismatch happens between dongle and wpa_supplicant.
WARNING: CPU: 0 PID: 3086 at /opt/FMAC/cypress-fmac-v5.4.18-2020_0402/v5.4.18-backports_cypatch/net/wireless/sme.c:756 __cfg80211_connect_result+0x42c/0x4a0 [cfg80211]
The fix is to clear the BRCMF_VIF_STATUS_EAP_SUCCESS /
BRCMF_VIF_STATUS_EAP bits during the link down process and add to call
link down process when link down event received during
BRCMF_VIF_STATUS_CONNECTING as well as BRCMF_VIF_STATUS_CONNECTED
state.
Signed-off-by: Wataru Gohda <wataru.gohda@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index e981a9905572..c63ea0e4c249 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -1618,6 +1618,8 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason,
locally_generated, GFP_KERNEL);
}
clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
+ clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
+ clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
@@ -2490,6 +2492,8 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
+ clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &ifp->vif->sme_state);
+ clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &ifp->vif->sme_state);
cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
@@ -6390,6 +6394,10 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
&ifp->vif->sme_state);
conn_params.status = WLAN_STATUS_SUCCESS;
} else {
+ clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS,
+ &ifp->vif->sme_state);
+ clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS,
+ &ifp->vif->sme_state);
conn_params.status = WLAN_STATUS_AUTH_TIMEOUT;
}
conn_params.bssid = profile->bssid;
@@ -6500,9 +6508,13 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
} else if (brcmf_is_linkdown(ifp->vif, e)) {
brcmf_dbg(CONN, "Linkdown\n");
if (!brcmf_is_ibssmode(ifp->vif) &&
- test_bit(BRCMF_VIF_STATUS_CONNECTED,
- &ifp->vif->sme_state)) {
- if (memcmp(profile->bssid, e->addr, ETH_ALEN))
+ (test_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state) ||
+ test_bit(BRCMF_VIF_STATUS_CONNECTING,
+ &ifp->vif->sme_state))) {
+ if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
+ &ifp->vif->sme_state) &&
+ memcmp(profile->bssid, e->addr, ETH_ALEN))
return err;
brcmf_bss_connect_done(cfg, ndev, e, false);
--
2.17.1

View File

@@ -0,0 +1,41 @@
From dc52908e2202056876d5bb2b87a9f8ca58248fdc Mon Sep 17 00:00:00 2001
From: Prasanna Kerekoppa <prasanna.kerekoppa@cypress.com>
Date: Wed, 27 Jan 2021 14:48:29 -0800
Subject: [PATCH 070/179] brcmfmac: Avoiding Connection delay
Channel info passed by supplicant is not given to firmware. This causes
delay (about 3seconds) due to full scan. Supplicant already provides the
channel info for the specific SSID. channel_hint carries this channel
info for the connect call back.
Patch has been verified on 43012 and 43455.
Signed-off-by: Prasanna Kerekoppa <prasanna.kerekoppa@cypress.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index c63ea0e4c249..40dac929b91e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2264,6 +2264,14 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
return -EOPNOTSUPP;
}
+ if (sme->channel_hint) {
+ chan = sme->channel_hint;
+ }
+
+ if (sme->bssid_hint) {
+ sme->bssid = sme->bssid_hint;
+ }
+
if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
/* A normal (non P2P) connection request setup. */
ie = NULL;
--
2.17.1

View File

@@ -0,0 +1,37 @@
From 470b94ce0942df49af724ff66a3bf2f7ca9f36ab Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Wed, 3 Feb 2021 21:36:51 -0600
Subject: [PATCH 071/179] non-upstream: Revert "brcm80211: select
WANT_DEV_COREDUMP conditionally for brcmfmac"
This reverts commit 885a93cf31106808cd3ded7c5e01e35fa495fdc5.
To fix DEV_COREDUMP function to be disabled in compat/Kconfig
of backports. The root cause is because the parsing rule of
lib/kconfig.py in backports will not consider the "select <sym>
if xxx" as a sel_line. In order to aviod affecting other driver's
configs, so we do not modify the sel_line logic in backports.
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/Kconfig b/drivers/net/wireless/broadcom/brcm80211/Kconfig
index ee17eb21a084..5b801ff6b904 100644
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
@@ -34,7 +34,7 @@ config BRCM_TRACING
config BRCMDBG
bool "Broadcom driver debug functions"
depends on BRCMSMAC || BRCMFMAC
- select WANT_DEV_COREDUMP if BRCMFMAC
+ select WANT_DEV_COREDUMP
help
Selecting this enables additional code for debug purposes.
--
2.17.1

View File

@@ -0,0 +1,39 @@
From 86a3bcaa6e42d5d7aea4342a3cfaf4ef016f3714 Mon Sep 17 00:00:00 2001
From: Kurt Lee <kurt.lee@cypress.com>
Date: Tue, 9 Mar 2021 02:18:13 -0600
Subject: [PATCH 072/179] brcmfmac: Fix connecting enterprise AP failure
Use alternative to check AKM-DPP enabled thus this change won't let
status un-sync on use_fwsup between driver and firmware
Signed-off-by: Kurt Lee <kurt.lee@cypress.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 40dac929b91e..fdec3aa80613 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2023,6 +2023,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
break;
case WLAN_AKM_SUITE_DPP:
val = WFA_AUTH_DPP;
+ profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
break;
default:
bphy_err(drvr, "invalid cipher group (%d)\n",
@@ -2358,8 +2359,6 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
brcmf_dbg(INFO, "using PSK offload\n");
profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
}
- } else {
- profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
}
if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
--
2.17.1

View File

@@ -0,0 +1,42 @@
From 56ef76e7bb4dd6074b9586cc3be42b9d6affb25e Mon Sep 17 00:00:00 2001
From: Double Lo <double.lo@cypress.com>
Date: Wed, 24 Feb 2021 04:34:37 -0600
Subject: [PATCH 073/179] brcmfmac: Fix for skbuf allocation failure in memory
limited system
While downloading the 4343W WLAN firmware, observed the error below:
brcmfmac: brcmf_sdiod_ramrw: dev_alloc_skb failed: len 32768
brcmf_sdio_download_code_file: error -5 on writing 397444 membytes
at 0x00000000
It is randomly caused because of the limited memory.
The pkt = dev_alloc_skb(dsize) tries to allocate memory with GFP_ATOMIC
set.As a result, it will fail instantly with the above error if memory is
not available at that time.
Use __dev_alloc_skb(dsize, GFP_KERNEL) to allocate this memory.
Signed-off-by: Double Lo <Double.Lo@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 48f1198a617c..df4fd7837b6d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -671,7 +671,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
uint dsize;
dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
- pkt = dev_alloc_skb(dsize);
+ pkt = __dev_alloc_skb(dsize, GFP_KERNEL);
if (!pkt) {
brcmf_err("dev_alloc_skb failed: len %d\n", dsize);
return -EIO;
--
2.17.1

View File

@@ -0,0 +1,52 @@
From cab3dd40c7694ba1aec2f4ab1d5953787fd23d2f Mon Sep 17 00:00:00 2001
From: Syed Rafiuddeen <syed.rafiuddeen@cypress.com>
Date: Wed, 10 Mar 2021 16:33:25 -0600
Subject: [PATCH 074/179] brcmfmac: Update SSID of hidden AP while informing
its bss to cfg80211 layer
cfg80211 layer on DUT STA is disconnecting ongoing connection attempt after
receiving association response, because cfg80211 layer does not have valid
AP bss information. On association response event, brcmfmac communicates
the AP bss information to cfg80211 layer, but SSID seem to be empty in AP
bss information, and cfg80211 layer prints kernel warning and then
disconnects the ongoing connection attempt.
SSID is empty in SSID IE, but 'bi->SSID' contains a valid SSID, so
updating the SSID for hidden AP while informing its bss information
to cfg80211 layer.
Signed-off-by: Syed Rafiuddeen <syed.rafiuddeen@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index fdec3aa80613..bf121ce39fc4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3221,6 +3221,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
u8 *notify_ie;
size_t notify_ielen;
struct cfg80211_inform_bss bss_data = {};
+ const struct brcmf_tlv *ssid = NULL;
if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
bphy_err(drvr, "Bss info is larger than buffer. Discarding\n");
@@ -3250,6 +3251,12 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
notify_ielen = le32_to_cpu(bi->ie_length);
bss_data.signal = (s16)le16_to_cpu(bi->RSSI) * 100;
+ ssid = brcmf_parse_tlvs(notify_ie, notify_ielen, WLAN_EID_SSID);
+ if (ssid && ssid->data[0] == '\0' && ssid->len == bi->SSID_len) {
+ /* Update SSID for hidden AP */
+ memcpy((u8 *)ssid->data, bi->SSID, bi->SSID_len);
+ }
+
brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
--
2.17.1

View File

@@ -0,0 +1,459 @@
From 1439760bd15d8ebb64f29712e68b518f81f9d158 Mon Sep 17 00:00:00 2001
From: Prasanna Kerekoppa <prasanna.kerekoppa@infineon.com>
Date: Thu, 11 Feb 2021 01:49:41 -0600
Subject: [PATCH 075/179] brcmfmac: Fix PCIE suspend/resume issue
This change fixes the issue of PCIE suspend issue for the chips
which has IPC version >= 6.
The root cause seems that the firmware uses PCIE IPC version >=6
which need the H2D_HOST_D3_INFORM message to enter into D3 suspend
state instead of the mailbox interrupt which puts the chip in suspend
state in PCIE IPC version 5.
Signed-off-by: Prasanna Kerekoppa <prasanna.kerekoppa@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/msgbuf.c | 66 ++++++++
.../broadcom/brcm80211/brcmfmac/msgbuf.h | 1 +
.../broadcom/brcm80211/brcmfmac/pcie.c | 145 ++++++++++++------
.../broadcom/brcm80211/brcmfmac/pcie.h | 2 +
4 files changed, 171 insertions(+), 43 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index d0cc9880b83e..920ec9314e32 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -24,6 +24,7 @@
#include "flowring.h"
#include "bus.h"
#include "tracepoint.h"
+#include "pcie.h"
#define MSGBUF_IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000)
@@ -48,6 +49,8 @@
#define MSGBUF_TYPE_RX_CMPLT 0x12
#define MSGBUF_TYPE_LPBK_DMAXFER 0x13
#define MSGBUF_TYPE_LPBK_DMAXFER_CMPLT 0x14
+#define MSGBUF_TYPE_H2D_MAILBOX_DATA 0x23
+#define MSGBUF_TYPE_D2H_MAILBOX_DATA 0x24
#define NR_TX_PKTIDS 2048
#define NR_RX_PKTIDS 1024
@@ -105,6 +108,12 @@ struct msgbuf_tx_msghdr {
__le32 rsvd0;
};
+struct msgbuf_h2d_mbdata {
+ struct msgbuf_common_hdr msg;
+ __le32 mbdata;
+ __le16 rsvd0[7];
+};
+
struct msgbuf_rx_bufpost {
struct msgbuf_common_hdr msg;
__le16 metadata_buf_len;
@@ -219,6 +228,13 @@ struct msgbuf_flowring_flush_resp {
__le32 rsvd0[3];
};
+struct msgbuf_d2h_mailbox_data {
+ struct msgbuf_common_hdr msg;
+ struct msgbuf_completion_hdr compl_hdr;
+ __le32 mbdata;
+ __le32 rsvd0[2];
+} d2h_mailbox_data_t;
+
struct brcmf_msgbuf_work_item {
struct list_head queue;
u32 flowid;
@@ -291,6 +307,8 @@ struct brcmf_msgbuf_pktids {
};
static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf);
+static void brcmf_msgbuf_process_d2h_mbdata(struct brcmf_msgbuf *msgbuf,
+ void *buf);
static struct brcmf_msgbuf_pktids *
@@ -425,6 +443,34 @@ static void brcmf_msgbuf_release_pktids(struct brcmf_msgbuf *msgbuf)
msgbuf->tx_pktids);
}
+int brcmf_msgbuf_tx_mbdata(struct brcmf_pub *drvr, u32 mbdata)
+{
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+ struct brcmf_commonring *commonring;
+ struct msgbuf_h2d_mbdata *h2d_mbdata;
+ void *ret_ptr;
+ int err;
+
+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
+ brcmf_commonring_lock(commonring);
+ ret_ptr = brcmf_commonring_reserve_for_write(commonring);
+ if (!ret_ptr) {
+ brcmf_err("Failed to reserve space in commonring\n");
+ brcmf_commonring_unlock(commonring);
+ return -ENOMEM;
+ }
+ h2d_mbdata = (struct msgbuf_h2d_mbdata *)ret_ptr;
+ memset(h2d_mbdata, 0, sizeof(*h2d_mbdata));
+
+ h2d_mbdata->msg.msgtype = MSGBUF_TYPE_H2D_MAILBOX_DATA;
+ h2d_mbdata->mbdata = cpu_to_le32(mbdata);
+
+ err = brcmf_commonring_write_complete(commonring);
+ brcmf_commonring_unlock(commonring);
+
+ return err;
+}
+
static int brcmf_msgbuf_tx_ioctl(struct brcmf_pub *drvr, int ifidx,
uint cmd, void *buf, uint len)
@@ -1313,6 +1359,21 @@ brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
brcmf_msgbuf_remove_flowring(msgbuf, flowid);
}
+static void
+brcmf_msgbuf_process_d2h_mbdata(struct brcmf_msgbuf *msgbuf,
+ void *buf)
+{
+ struct msgbuf_d2h_mailbox_data *d2h_mbdata;
+
+ d2h_mbdata = (struct msgbuf_d2h_mailbox_data *)buf;
+
+ if (!d2h_mbdata) {
+ brcmf_err("d2h_mbdata is null\n");
+ return;
+ }
+
+ brcmf_pcie_handle_mb_data(msgbuf->drvr->bus_if, d2h_mbdata->mbdata);
+}
static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf)
{
@@ -1356,6 +1417,11 @@ static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf)
brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RX_CMPLT\n");
brcmf_msgbuf_process_rx_complete(msgbuf, buf);
break;
+ case MSGBUF_TYPE_D2H_MAILBOX_DATA:
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_D2H_MAILBOX_DATA\n");
+ brcmf_msgbuf_process_d2h_mbdata(msgbuf, buf);
+ break;
+
default:
bphy_err(drvr, "Unsupported msgtype %d\n", msg->msgtype);
break;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
index 2e322edbb907..ff0b5c1aa874 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
@@ -39,5 +39,6 @@ static inline int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
}
static inline void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr) {}
#endif
+int brcmf_msgbuf_tx_mbdata(struct brcmf_pub *drvr, u32 mbdata);
#endif /* BRCMFMAC_MSGBUF_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 5345f8fffd2b..41c60b9bcd57 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -151,12 +151,14 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_PCIE_MB_INT_D2H3_DB0 | \
BRCMF_PCIE_MB_INT_D2H3_DB1)
+#define BRCMF_PCIE_SHARED_VERSION_6 6
#define BRCMF_PCIE_SHARED_VERSION_7 7
#define BRCMF_PCIE_MIN_SHARED_VERSION 5
#define BRCMF_PCIE_MAX_SHARED_VERSION BRCMF_PCIE_SHARED_VERSION_7
#define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF
#define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000
#define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000
+#define BRCMF_PCIE_SHARED_USE_MAILBOX 0x2000000
#define BRCMF_PCIE_SHARED_HOSTRDY_DB1 0x10000000
#define BRCMF_PCIE_FLAGS_HTOD_SPLIT 0x4000
@@ -173,6 +175,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
#define BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET 56
#define BRCMF_SHARED_DMA_RINGUPD_LEN_OFFSET 64
#define BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET 68
+#define BRCMF_SHARED_HOST_CAP_OFFSET 84
#define BRCMF_RING_H2D_RING_COUNT_OFFSET 0
#define BRCMF_RING_D2H_RING_COUNT_OFFSET 1
@@ -187,6 +190,8 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
#define BRCMF_DEF_MAX_RXBUFPOST 255
+#define BRCMF_H2D_ENABLE_HOSTRDY 0x400
+
#define BRCMF_CONSOLE_BUFADDR_OFFSET 8
#define BRCMF_CONSOLE_BUFSIZE_OFFSET 12
#define BRCMF_CONSOLE_WRITEIDX_OFFSET 16
@@ -273,6 +278,9 @@ struct brcmf_pciedev_info {
struct brcmf_chip *ci;
u32 coreid;
struct brcmf_pcie_shared_info shared;
+ u8 hostready;
+ bool use_mailbox;
+ bool use_d0_inform;
wait_queue_head_t mbdata_resp_wait;
bool mbdata_completed;
bool irq_allocated;
@@ -906,41 +914,53 @@ static int
brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data)
{
struct brcmf_pcie_shared_info *shared;
+ struct brcmf_bus *bus;
+ int err;
struct brcmf_core *core;
u32 addr;
u32 cur_htod_mb_data;
u32 i;
shared = &devinfo->shared;
- addr = shared->htod_mb_data_addr;
- cur_htod_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);
-
- if (cur_htod_mb_data != 0)
- brcmf_dbg(PCIE, "MB transaction is already pending 0x%04x\n",
- cur_htod_mb_data);
-
- i = 0;
- while (cur_htod_mb_data != 0) {
- msleep(10);
- i++;
- if (i > 100)
- return -EIO;
+ bus = dev_get_drvdata(&devinfo->pdev->dev);
+ if (shared->version >= BRCMF_PCIE_SHARED_VERSION_6 &&
+ !devinfo->use_mailbox) {
+ err = brcmf_msgbuf_tx_mbdata(bus->drvr, htod_mb_data);
+ if (err) {
+ brcmf_err(bus, "sendimg mbdata failed err=%d\n", err);
+ return err;
+ }
+ } else {
+ addr = shared->htod_mb_data_addr;
cur_htod_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);
- }
- brcmf_pcie_write_tcm32(devinfo, addr, htod_mb_data);
- pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1);
+ if (cur_htod_mb_data != 0)
+ brcmf_dbg(PCIE, "MB transaction is already pending 0x%04x\n",
+ cur_htod_mb_data);
+
+ i = 0;
+ while (cur_htod_mb_data != 0) {
+ msleep(10);
+ i++;
+ if (i > 100)
+ return -EIO;
+ cur_htod_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);
+ }
- /* Send mailbox interrupt twice as a hardware workaround */
- core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2);
- if (core->rev <= 13)
+ brcmf_pcie_write_tcm32(devinfo, addr, htod_mb_data);
pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1);
+ /* Send mailbox interrupt twice as a hardware workaround */
+ core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2);
+ if (core->rev <= 13)
+ pci_write_config_dword(devinfo->pdev,
+ BRCMF_PCIE_REG_SBMBX, 1);
+ }
return 0;
}
-static void brcmf_pcie_handle_mb_data(struct brcmf_pciedev_info *devinfo)
+static u32 brcmf_pcie_read_mb_data(struct brcmf_pciedev_info *devinfo)
{
struct brcmf_pcie_shared_info *shared;
u32 addr;
@@ -949,32 +969,37 @@ static void brcmf_pcie_handle_mb_data(struct brcmf_pciedev_info *devinfo)
shared = &devinfo->shared;
addr = shared->dtoh_mb_data_addr;
dtoh_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);
+ brcmf_pcie_write_tcm32(devinfo, addr, 0);
+ return dtoh_mb_data;
+}
- if (!dtoh_mb_data)
- return;
+void brcmf_pcie_handle_mb_data(struct brcmf_bus *bus_if, u32 d2h_mb_data)
+{
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
- brcmf_pcie_write_tcm32(devinfo, addr, 0);
+ brcmf_dbg(INFO, "D2H_MB_DATA: 0x%04x\n", d2h_mb_data);
- brcmf_dbg(PCIE, "D2H_MB_DATA: 0x%04x\n", dtoh_mb_data);
- if (dtoh_mb_data & BRCMF_D2H_DEV_DS_ENTER_REQ) {
- brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP REQ\n");
+ if (d2h_mb_data & BRCMF_D2H_DEV_DS_ENTER_REQ) {
+ brcmf_dbg(INFO, "D2H_MB_DATA: DEEP SLEEP REQ\n");
brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_DS_ACK);
- brcmf_dbg(PCIE, "D2H_MB_DATA: sent DEEP SLEEP ACK\n");
+ brcmf_dbg(INFO, "D2H_MB_DATA: sent DEEP SLEEP ACK\n");
}
- if (dtoh_mb_data & BRCMF_D2H_DEV_DS_EXIT_NOTE)
- brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP EXIT\n");
- if (dtoh_mb_data & BRCMF_D2H_DEV_D3_ACK) {
- brcmf_dbg(PCIE, "D2H_MB_DATA: D3 ACK\n");
+
+ if (d2h_mb_data & BRCMF_D2H_DEV_DS_EXIT_NOTE)
+ brcmf_dbg(INFO, "D2H_MB_DATA: DEEP SLEEP EXIT\n");
+ if (d2h_mb_data & BRCMF_D2H_DEV_D3_ACK) {
+ brcmf_dbg(INFO, "D2H_MB_DATA: D3 ACK\n");
devinfo->mbdata_completed = true;
wake_up(&devinfo->mbdata_resp_wait);
}
- if (dtoh_mb_data & BRCMF_D2H_DEV_FWHALT) {
- brcmf_dbg(PCIE, "D2H_MB_DATA: FW HALT\n");
+
+ if (d2h_mb_data & BRCMF_D2H_DEV_FWHALT) {
+ brcmf_dbg(INFO, "D2H_MB_DATA: FW HALT\n");
brcmf_fw_crashed(&devinfo->pdev->dev);
}
}
-
static void brcmf_pcie_bus_console_init(struct brcmf_pciedev_info *devinfo)
{
struct brcmf_pcie_shared_info *shared;
@@ -1084,6 +1109,9 @@ static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
{
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
u32 status;
+ u32 d2h_mbdata;
+ struct pci_dev *pdev = devinfo->pdev;
+ struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
devinfo->in_irq = true;
status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
@@ -1092,8 +1120,11 @@ static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
status);
if (status & (BRCMF_PCIE_MB_INT_FN0_0 |
- BRCMF_PCIE_MB_INT_FN0_1))
- brcmf_pcie_handle_mb_data(devinfo);
+ BRCMF_PCIE_MB_INT_FN0_1)) {
+ d2h_mbdata = brcmf_pcie_read_mb_data(devinfo);
+ brcmf_pcie_handle_mb_data(bus, d2h_mbdata);
+ }
+
if (status & BRCMF_PCIE_MB_INT_D2H_DB) {
if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
brcmf_proto_msgbuf_rx_trigger(
@@ -1771,6 +1802,7 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
struct brcmf_pcie_shared_info *shared;
u32 addr;
+ u32 host_cap;
shared = &devinfo->shared;
shared->tcm_base_address = sharedram_addr;
@@ -1810,6 +1842,26 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
addr = sharedram_addr + BRCMF_SHARED_RING_INFO_ADDR_OFFSET;
shared->ring_info_addr = brcmf_pcie_read_tcm32(devinfo, addr);
+ if (shared->version >= BRCMF_PCIE_SHARED_VERSION_6) {
+ host_cap = shared->version;
+
+ devinfo->hostready =
+ ((shared->flags & BRCMF_PCIE_SHARED_HOSTRDY_DB1)
+ == BRCMF_PCIE_SHARED_HOSTRDY_DB1);
+ if (devinfo->hostready) {
+ brcmf_dbg(PCIE, "HostReady supported by dongle.\n");
+ host_cap = host_cap | BRCMF_H2D_ENABLE_HOSTRDY;
+ }
+ devinfo->use_mailbox =
+ ((shared->flags & BRCMF_PCIE_SHARED_USE_MAILBOX)
+ == BRCMF_PCIE_SHARED_USE_MAILBOX);
+ devinfo->use_d0_inform = false;
+ addr = sharedram_addr + BRCMF_SHARED_HOST_CAP_OFFSET;
+ brcmf_pcie_write_tcm32(devinfo, addr, host_cap);
+ } else {
+ devinfo->use_d0_inform = true;
+ }
+
brcmf_dbg(PCIE, "max rx buf post %d, rx dataoffset %d\n",
shared->max_rxbufpost, shared->rx_dataoffset);
@@ -2459,14 +2511,25 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
/* Check if device is still up and running, if so we are ready */
if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
brcmf_dbg(PCIE, "Try to wakeup device....\n");
- if (brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM))
- goto cleanup;
+ if (devinfo->use_d0_inform) {
+ if (brcmf_pcie_send_mb_data(devinfo,
+ BRCMF_H2D_HOST_D0_INFORM))
+ goto cleanup;
+ } else {
+ brcmf_pcie_hostready(devinfo);
+ }
+
brcmf_dbg(PCIE, "Hot resume, continue....\n");
devinfo->state = BRCMFMAC_PCIE_STATE_UP;
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
brcmf_bus_change_state(bus, BRCMF_BUS_UP);
brcmf_pcie_intr_enable(devinfo);
- brcmf_pcie_hostready(devinfo);
+ if (devinfo->use_d0_inform) {
+ brcmf_dbg(TRACE, "sending brcmf_pcie_hostready since use_d0_inform=%d\n",
+ devinfo->use_d0_inform);
+ brcmf_pcie_hostready(devinfo);
+ }
+
brcmf_pcie_fwcon_timer(devinfo, true);
return 0;
}
@@ -2531,10 +2594,8 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
{ /* end: all zeroes */ }
};
-
MODULE_DEVICE_TABLE(pci, brcmf_pcie_devid_table);
-
static struct pci_driver brcmf_pciedrvr = {
.node = {},
.name = KBUILD_MODNAME,
@@ -2547,14 +2608,12 @@ static struct pci_driver brcmf_pciedrvr = {
.driver.coredump = brcmf_dev_coredump,
};
-
int brcmf_pcie_register(void)
{
brcmf_dbg(PCIE, "Enter\n");
return pci_register_driver(&brcmf_pciedrvr);
}
-
void brcmf_pcie_exit(void)
{
brcmf_dbg(PCIE, "Enter\n");
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h
index 8e6c227e8315..8e4f48637894 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h
@@ -11,4 +11,6 @@ struct brcmf_pciedev {
struct brcmf_pciedev_info *devinfo;
};
+void brcmf_pcie_handle_mb_data(struct brcmf_bus *bus_if, u32 d2h_mb_data);
+
#endif /* BRCMFMAC_PCIE_H */
--
2.17.1

View File

@@ -0,0 +1,107 @@
From e31bda91b203333903b66d82a308d07e275e03bd Mon Sep 17 00:00:00 2001
From: Divya Madhyan <Divya.Madhyan@infineon.com>
Date: Sun, 4 Apr 2021 14:49:12 -0500
Subject: [PATCH 076/179] brcmfmac: disable mpc when power_save is disabled
These set of changes intend to integrate the PM and mpc commands,
implying that whenever power save is off, mpc is also turned off
and when PM is on again, mpc takes the corresponding appropriate value.
Signed-off-by: Divya Madhyan <Divya.Madhyan@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 21 ++++++++++++++++---
.../broadcom/brcm80211/brcmfmac/core.c | 1 +
.../broadcom/brcm80211/brcmfmac/core.h | 1 +
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index bf121ce39fc4..3105eb32cc4b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -950,9 +950,16 @@ void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
{
struct brcmf_pub *drvr = ifp->drvr;
s32 err = 0;
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ ifp->drvr->req_mpc = mpc;
if (check_vif_up(ifp->vif)) {
- err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
+ if (cfg->pwr_save)
+ err = brcmf_fil_iovar_int_set(ifp, "mpc",
+ ifp->drvr->req_mpc);
+ else
+ err = brcmf_fil_iovar_int_set(ifp, "mpc", 0);
+
if (err) {
bphy_err(drvr, "fail to set mpc\n");
return;
@@ -3186,6 +3193,12 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
pm = PM_OFF;
}
+
+ if (cfg->pwr_save)
+ brcmf_set_mpc(ifp, ifp->drvr->req_mpc);
+ else
+ brcmf_set_mpc(ifp, 0);
+
brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
@@ -4042,6 +4055,9 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
struct brcmf_bus *bus_if = drvr->bus_if;
struct brcmf_cfg80211_info *config = drvr->config;
int retry = BRCMF_PM_WAIT_MAXRETRY;
+ s32 power_mode;
+
+ power_mode = cfg->pwr_save ? ifp->drvr->settings->default_pm : PM_OFF;
brcmf_dbg(TRACE, "Enter\n");
@@ -4062,7 +4078,7 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
brcmf_configure_arp_nd_offload(ifp, true);
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
- cfg->wowl.pre_pmmode);
+ power_mode);
cfg->wowl.active = false;
if (cfg->wowl.nd_enabled) {
brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev, 0);
@@ -4092,7 +4108,6 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
brcmf_configure_arp_nd_offload(ifp, false);
- brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
wowl_config = 0;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 3be50e0dcb26..920056a2aec8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1367,6 +1367,7 @@ int brcmf_attach(struct device *dev, bool start_bus)
/* Link to bus module */
drvr->hdrlen = 0;
+ drvr->req_mpc = 1;
/* Attach and link in the protocol */
ret = brcmf_proto_attach(drvr);
if (ret != 0) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index c0e35ce686f1..0b2938a09c5a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -124,6 +124,7 @@ struct brcmf_pub {
u32 feat_flags;
u32 chip_quirks;
+ int req_mpc;
struct brcmf_rev_info revinfo;
#ifdef DEBUG
--
2.17.1

View File

@@ -0,0 +1,41 @@
From fa8b1ad5399495accb517311ccf1536022b25ae4 Mon Sep 17 00:00:00 2001
From: Ramesh Rangavittal <ramesh.rangavittal@infineon.com>
Date: Sat, 27 Mar 2021 10:56:15 -0500
Subject: [PATCH 077/179] brcmfmac: Fix authentication latency caused by OBSS
stats survey
Auto Channel Select feature of HostAP uses dump_survey to fetch
OBSS statistics. When the device is in the middle of an authentication
sequence or just at the end of authentication completion, running
dump_survey would trigger a channel change. The channel change in-turn
can cause packet loss, resulting in authentication delay. With this change,
dump_survey wont be run when authentication or association is in progress &
hence resolving the issue.
Signed-off-by: Ramesh Rangavittal <ramesh.rangavittal@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 3105eb32cc4b..6f2361da5f9e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -8111,6 +8111,12 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
brcmf_dbg(TRACE, "Enter: channel idx=%d\n", idx);
+ /* Do not run survey when VIF in CONNECTING / CONNECTED states */
+ if ((test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) ||
+ (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))) {
+ return -EBUSY;
+ }
+
band = wiphy->bands[NL80211_BAND_2GHZ];
if (band && idx >= band->n_channels) {
idx -= band->n_channels;
--
2.17.1

View File

@@ -0,0 +1,588 @@
From 3b967b04b13612c5886f97588b8d747f30498d37 Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Date: Fri, 9 Apr 2021 02:48:51 -0500
Subject: [PATCH 078/179] brcmfmac: support external SAE authentication in
station mode
Firmware has SME functionality but would like the userspace to handle
SAE authentication. This patch adds support for such an external SAE
authentication mechanism in station mode.
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 255 +++++++++++++++++-
.../broadcom/brcm80211/brcmfmac/cfg80211.h | 18 ++
.../broadcom/brcm80211/brcmfmac/feature.c | 3 +-
.../broadcom/brcm80211/brcmfmac/feature.h | 4 +-
.../broadcom/brcm80211/brcmfmac/fweh.c | 28 +-
.../broadcom/brcm80211/brcmfmac/fweh.h | 8 +-
.../broadcom/brcm80211/brcmfmac/fwil_types.h | 45 ++++
7 files changed, 343 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 6f2361da5f9e..33f1f5beac21 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -90,6 +90,9 @@
#define BRCMF_PS_MAX_TIMEOUT_MS 2000
+#define MGMT_AUTH_FRAME_DWELL_TIME 4000
+#define MGMT_AUTH_FRAME_WAIT_TIME (MGMT_AUTH_FRAME_DWELL_TIME + 100)
+
/* Dump obss definitions */
#define ACS_MSRMNT_DELAY 80
#define CHAN_NOISE_DUMMY (-80)
@@ -1821,14 +1824,18 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
s32 val = 0;
s32 err = 0;
- if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
+ if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
- else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
- val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
- else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3)
+ } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
+ if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_SAE)
+ val = WPA3_AUTH_SAE_PSK;
+ else
+ val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
+ } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3) {
val = WPA3_AUTH_SAE_PSK;
- else
+ } else {
val = WPA_AUTH_DISABLED;
+ }
brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val);
if (err) {
@@ -2108,7 +2115,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
skip_mfp_config:
- brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
+ brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
if (err) {
bphy_err(drvr, "could not set wpa_auth (%d)\n", err);
@@ -5423,9 +5430,12 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
s32 ie_len;
struct brcmf_fil_action_frame_le *action_frame;
struct brcmf_fil_af_params_le *af_params;
- bool ack;
+ bool ack = false;
s32 chan_nr;
u32 freq;
+ struct brcmf_mf_params_le *mf_params;
+ u32 mf_params_len;
+ s32 timeout;
brcmf_dbg(TRACE, "Enter\n");
@@ -5506,6 +5516,71 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
GFP_KERNEL);
kfree(af_params);
+ } else if (ieee80211_is_auth(mgmt->frame_control)) {
+ reinit_completion(&vif->mgmt_tx);
+ clear_bit(BRCMF_MGMT_TX_ACK, &vif->mgmt_tx_status);
+ clear_bit(BRCMF_MGMT_TX_NOACK, &vif->mgmt_tx_status);
+ clear_bit(BRCMF_MGMT_TX_OFF_CHAN_COMPLETED,
+ &vif->mgmt_tx_status);
+
+ mf_params_len = offsetof(struct brcmf_mf_params_le, data) +
+ (len - DOT11_MGMT_HDR_LEN);
+ mf_params = kzalloc(mf_params_len, GFP_KERNEL);
+ if (!mf_params) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ mf_params->dwell_time = cpu_to_le32(MGMT_AUTH_FRAME_DWELL_TIME);
+ mf_params->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
+ mf_params->frame_control = mgmt->frame_control;
+
+ if (chan)
+ freq = chan->center_freq;
+ else
+ brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
+ &freq);
+ chan_nr = ieee80211_frequency_to_channel(freq);
+ mf_params->channel = cpu_to_le32(chan_nr);
+ memcpy(&mf_params->da[0], &mgmt->da[0], ETH_ALEN);
+ memcpy(&mf_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
+ mf_params->packet_id = cpu_to_le32(*cookie);
+ memcpy(mf_params->data, &buf[DOT11_MGMT_HDR_LEN],
+ le16_to_cpu(mf_params->len));
+
+ brcmf_dbg(TRACE, "Auth frame, cookie=%d, fc=%04x, len=%d, channel=%d\n",
+ le32_to_cpu(mf_params->packet_id),
+ le16_to_cpu(mf_params->frame_control),
+ le16_to_cpu(mf_params->len),
+ le32_to_cpu(mf_params->channel));
+
+ vif->mgmt_tx_id = le32_to_cpu(mf_params->packet_id);
+ set_bit(BRCMF_MGMT_TX_SEND_FRAME, &vif->mgmt_tx_status);
+
+ err = brcmf_fil_bsscfg_data_set(vif->ifp, "mgmt_frame",
+ mf_params, mf_params_len);
+ if (err) {
+ bphy_err(drvr, "Failed to send Auth frame: err=%d\n",
+ err);
+ goto tx_status;
+ }
+
+ timeout =
+ wait_for_completion_timeout(&vif->mgmt_tx,
+ MGMT_AUTH_FRAME_WAIT_TIME);
+ if (test_bit(BRCMF_MGMT_TX_ACK, &vif->mgmt_tx_status)) {
+ brcmf_dbg(TRACE, "TX Auth frame operation is success\n");
+ ack = true;
+ } else {
+ bphy_err(drvr, "TX Auth frame operation is failed: status=%ld)\n",
+ vif->mgmt_tx_status);
+ }
+
+tx_status:
+ cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
+ GFP_KERNEL);
+ kfree(mf_params);
+
} else {
brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len);
@@ -5869,6 +5944,40 @@ brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,
return ret;
}
+static int
+brcmf_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_external_auth_params *params)
+{
+ struct brcmf_if *ifp;
+ struct brcmf_pub *drvr;
+ struct brcmf_auth_req_status_le auth_status;
+ int ret = 0;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+ ifp = netdev_priv(dev);
+ drvr = ifp->drvr;
+ if (params->status == WLAN_STATUS_SUCCESS) {
+ auth_status.flags = cpu_to_le16(BRCMF_EXTAUTH_SUCCESS);
+ } else {
+ bphy_err(drvr, "External authentication failed: status=%d\n",
+ params->status);
+ auth_status.flags = cpu_to_le16(BRCMF_EXTAUTH_FAIL);
+ }
+
+ memcpy(auth_status.peer_mac, params->bssid, ETH_ALEN);
+ auth_status.ssid_len = cpu_to_le32(min_t(u8, params->ssid.ssid_len,
+ IEEE80211_MAX_SSID_LEN));
+ memcpy(auth_status.ssid, params->ssid.ssid, auth_status.ssid_len);
+
+ ret = brcmf_fil_iovar_data_set(ifp, "auth_status", &auth_status,
+ sizeof(auth_status));
+ if (ret < 0)
+ bphy_err(drvr, "auth_status iovar failed: ret=%d\n", ret);
+
+ return ret;
+}
+
static struct cfg80211_ops brcmf_cfg80211_ops = {
.add_virtual_intf = brcmf_cfg80211_add_iface,
.del_virtual_intf = brcmf_cfg80211_del_iface,
@@ -5917,6 +6026,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
.set_pmk = brcmf_cfg80211_set_pmk,
.del_pmk = brcmf_cfg80211_del_pmk,
.change_bss = brcmf_cfg80211_change_bss,
+ .external_auth = brcmf_cfg80211_external_auth,
};
struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
@@ -5963,6 +6073,7 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
vif->mbss = mbss;
}
+ init_completion(&vif->mgmt_tx);
list_add_tail(&vif->list, &cfg->vif_list);
return vif;
}
@@ -6737,6 +6848,122 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
return -EINVAL;
}
+static s32
+brcmf_notify_ext_auth_request(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *e, void *data)
+{
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct cfg80211_external_auth_params params;
+ struct brcmf_auth_req_status_le *auth_req =
+ (struct brcmf_auth_req_status_le *)data;
+ s32 err = 0;
+
+ brcmf_dbg(INFO, "Enter: event %s (%d) received\n",
+ brcmf_fweh_event_name(e->event_code), e->event_code);
+
+ if (e->datalen < sizeof(*auth_req)) {
+ bphy_err(drvr, "Event %s (%d) data too small. Ignore\n",
+ brcmf_fweh_event_name(e->event_code), e->event_code);
+ return -EINVAL;
+ }
+
+ memset(&params, 0, sizeof(params));
+ params.action = NL80211_EXTERNAL_AUTH_START;
+ params.key_mgmt_suite = ntohl(WLAN_AKM_SUITE_SAE);
+ params.status = WLAN_STATUS_SUCCESS;
+ params.ssid.ssid_len = min_t(u32, 32, le32_to_cpu(auth_req->ssid_len));
+ memcpy(params.ssid.ssid, auth_req->ssid, params.ssid.ssid_len);
+ memcpy(params.bssid, auth_req->peer_mac, ETH_ALEN);
+
+ err = cfg80211_external_auth_request(ifp->ndev, &params, GFP_ATOMIC);
+ if (err)
+ bphy_err(drvr, "Ext Auth request to supplicant failed (%d)\n",
+ err);
+
+ return err;
+}
+
+static s32
+brcmf_notify_auth_frame_rx(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *e, void *data)
+{
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_cfg80211_info *cfg = drvr->config;
+ struct wireless_dev *wdev;
+ u32 mgmt_frame_len = e->datalen - sizeof(struct brcmf_rx_mgmt_data);
+ struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
+ u8 *frame = (u8 *)(rxframe + 1);
+ struct brcmu_chan ch;
+ struct ieee80211_mgmt *mgmt_frame;
+ s32 freq;
+
+ brcmf_dbg(INFO, "Enter: event %s (%d) received\n",
+ brcmf_fweh_event_name(e->event_code), e->event_code);
+
+ if (e->datalen < sizeof(*rxframe)) {
+ bphy_err(drvr, "Event %s (%d) data too small. Ignore\n",
+ brcmf_fweh_event_name(e->event_code), e->event_code);
+ return -EINVAL;
+ }
+
+ wdev = &ifp->vif->wdev;
+ WARN_ON(!wdev);
+
+ ch.chspec = be16_to_cpu(rxframe->chanspec);
+ cfg->d11inf.decchspec(&ch);
+
+ mgmt_frame = kzalloc(mgmt_frame_len, GFP_KERNEL);
+ if (!mgmt_frame)
+ return -ENOMEM;
+
+ mgmt_frame->frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH);
+ memcpy(mgmt_frame->da, ifp->mac_addr, ETH_ALEN);
+ memcpy(mgmt_frame->sa, e->addr, ETH_ALEN);
+ brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, mgmt_frame->bssid,
+ ETH_ALEN);
+ frame += offsetof(struct ieee80211_mgmt, u);
+ memcpy(&mgmt_frame->u, frame,
+ mgmt_frame_len - offsetof(struct ieee80211_mgmt, u));
+
+ freq = ieee80211_channel_to_frequency(ch.control_ch_num,
+ ch.band == BRCMU_CHAN_BAND_2G ?
+ NL80211_BAND_2GHZ :
+ NL80211_BAND_5GHZ);
+
+ cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len,
+ NL80211_RXMGMT_FLAG_EXTERNAL_AUTH);
+ kfree(mgmt_frame);
+ return 0;
+}
+
+static s32
+brcmf_notify_mgmt_tx_status(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *e, void *data)
+{
+ struct brcmf_cfg80211_vif *vif = ifp->vif;
+ u32 *packet_id = (u32 *)data;
+
+ brcmf_dbg(INFO, "Enter: event %s (%d), status=%d\n",
+ brcmf_fweh_event_name(e->event_code), e->event_code,
+ e->status);
+
+ if (!test_bit(BRCMF_MGMT_TX_SEND_FRAME, &vif->mgmt_tx_status) ||
+ (*packet_id != vif->mgmt_tx_id))
+ return 0;
+
+ if (e->event_code == BRCMF_E_MGMT_FRAME_TXSTATUS) {
+ if (e->status == BRCMF_E_STATUS_SUCCESS)
+ set_bit(BRCMF_MGMT_TX_ACK, &vif->mgmt_tx_status);
+ else
+ set_bit(BRCMF_MGMT_TX_NOACK, &vif->mgmt_tx_status);
+ } else {
+ set_bit(BRCMF_MGMT_TX_OFF_CHAN_COMPLETED, &vif->mgmt_tx_status);
+ }
+
+ complete(&vif->mgmt_tx);
+ return 0;
+}
+
static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
{
conf->frag_threshold = (u32)-1;
@@ -6781,7 +7008,16 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
brcmf_p2p_notify_action_tx_complete);
brcmf_fweh_register(cfg->pub, BRCMF_E_PSK_SUP,
brcmf_notify_connect_status);
- brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, brcmf_notify_rssi);
+ brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI,
+ brcmf_notify_rssi);
+ brcmf_fweh_register(cfg->pub, BRCMF_E_EXT_AUTH_REQ,
+ brcmf_notify_ext_auth_request);
+ brcmf_fweh_register(cfg->pub, BRCMF_E_EXT_AUTH_FRAME_RX,
+ brcmf_notify_auth_frame_rx);
+ brcmf_fweh_register(cfg->pub, BRCMF_E_MGMT_FRAME_TXSTATUS,
+ brcmf_notify_mgmt_tx_status);
+ brcmf_fweh_register(cfg->pub, BRCMF_E_MGMT_FRAME_OFF_CHAN_COMPLETE,
+ brcmf_notify_mgmt_tx_status);
}
static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
@@ -7355,6 +7591,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
[NL80211_IFTYPE_STATION] = {
.tx = 0xffff,
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
},
[NL80211_IFTYPE_P2P_CLIENT] = {
@@ -7683,6 +7920,8 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_SAE_OFFLOAD_AP);
}
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE_EXT))
+ wiphy->features |= NL80211_FEATURE_SAE;
wiphy->mgmt_stypes = brcmf_txrx_stypes;
wiphy->max_remain_on_channel_duration = 5000;
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 86a7d8ac912e..cb1455059d84 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -195,6 +195,21 @@ enum brcmf_cfg80211_pm_state {
BRCMF_CFG80211_PM_STATE_SUSPENDING,
};
+/**
+ * enum brcmf_mgmt_tx_status - mgmt frame tx status
+ *
+ * @BRCMF_MGMT_TX_ACK: mgmt frame acked
+ * @BRCMF_MGMT_TX_NOACK: mgmt frame not acked
+ * @BRCMF_MGMT_TX_OFF_CHAN_COMPLETED: off-channel complete
+ * @BRCMF_MGMT_TX_SEND_FRAME: mgmt frame tx is in progres
+ */
+enum brcmf_mgmt_tx_status {
+ BRCMF_MGMT_TX_ACK,
+ BRCMF_MGMT_TX_NOACK,
+ BRCMF_MGMT_TX_OFF_CHAN_COMPLETED,
+ BRCMF_MGMT_TX_SEND_FRAME
+};
+
/**
* struct vif_saved_ie - holds saved IEs for a virtual interface.
*
@@ -241,6 +256,9 @@ struct brcmf_cfg80211_vif {
unsigned long sme_state;
struct vif_saved_ie saved_ie;
struct list_head list;
+ struct completion mgmt_tx;
+ unsigned long mgmt_tx_status;
+ u32 mgmt_tx_id;
u16 mgmt_rx_reg;
bool mbss;
int is_11d;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index f483f0a3f8dd..94fa06749631 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -40,8 +40,9 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
{ BRCMF_FEAT_MONITOR_FLAG, "rtap" },
{ BRCMF_FEAT_MONITOR_FMT_RADIOTAP, "rtap" },
{ BRCMF_FEAT_DOT11H, "802.11h" },
- { BRCMF_FEAT_SAE, "sae" },
+ { BRCMF_FEAT_SAE, "sae " },
{ BRCMF_FEAT_FWAUTH, "idauth" },
+ { BRCMF_FEAT_SAE_EXT, "sae_ext " },
};
#ifdef DEBUG
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
index f1b086a69d73..bc6753e928f4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
@@ -30,6 +30,7 @@
* SAE: simultaneous authentication of equals
* FWAUTH: Firmware authenticator
* DUMP_OBSS: Firmware has capable to dump obss info to support ACS
+ * SAE_EXT: SAE be handled by userspace supplicant
*/
#define BRCMF_FEAT_LIST \
BRCMF_FEAT_DEF(MBSS) \
@@ -53,7 +54,8 @@
BRCMF_FEAT_DEF(DOT11H) \
BRCMF_FEAT_DEF(SAE) \
BRCMF_FEAT_DEF(FWAUTH) \
- BRCMF_FEAT_DEF(DUMP_OBSS)
+ BRCMF_FEAT_DEF(DUMP_OBSS) \
+ BRCMF_FEAT_DEF(SAE_EXT)
/*
* Quirks:
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
index bc3f4e4edcdf..b463bcf11863 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
@@ -355,26 +355,42 @@ int brcmf_fweh_activate_events(struct brcmf_if *ifp)
{
struct brcmf_pub *drvr = ifp->drvr;
int i, err;
- s8 eventmask[BRCMF_EVENTING_MASK_LEN];
+ struct eventmsgs_ext *eventmask_msg;
+ u32 msglen;
+
+ msglen = EVENTMSGS_EXT_STRUCT_SIZE + BRCMF_EVENTING_MASK_LEN;
+ eventmask_msg = kzalloc(msglen, GFP_KERNEL);
+ if (!eventmask_msg)
+ return -ENOMEM;
- memset(eventmask, 0, sizeof(eventmask));
for (i = 0; i < BRCMF_E_LAST; i++) {
if (ifp->drvr->fweh.evt_handler[i]) {
brcmf_dbg(EVENT, "enable event %s\n",
brcmf_fweh_event_name(i));
- setbit(eventmask, i);
+ setbit(eventmask_msg->mask, i);
}
}
/* want to handle IF event as well */
brcmf_dbg(EVENT, "enable event IF\n");
- setbit(eventmask, BRCMF_E_IF);
+ setbit(eventmask_msg->mask, BRCMF_E_IF);
+
+ eventmask_msg->ver = EVENTMSGS_VER;
+ eventmask_msg->command = EVENTMSGS_SET_MASK;
+ eventmask_msg->len = BRCMF_EVENTING_MASK_LEN;
+
+ err = brcmf_fil_iovar_data_set(ifp, "event_msgs_ext", eventmask_msg,
+ msglen);
+ if (!err)
+ goto end;
- err = brcmf_fil_iovar_data_set(ifp, "event_msgs",
- eventmask, BRCMF_EVENTING_MASK_LEN);
+ err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask_msg->mask,
+ BRCMF_EVENTING_MASK_LEN);
if (err)
bphy_err(drvr, "Set event_msgs error (%d)\n", err);
+end:
+ kfree(eventmask_msg);
return err;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
index 09cca13b860f..f92700237d0c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
@@ -92,7 +92,11 @@ struct brcmf_cfg80211_info;
BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
BRCMF_ENUM_DEF(PHY_TEMP, 111) \
BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \
- BRCMF_ENUM_DEF(ULP, 146)
+ BRCMF_ENUM_DEF(ULP, 146) \
+ BRCMF_ENUM_DEF(EXT_AUTH_REQ, 187) \
+ BRCMF_ENUM_DEF(EXT_AUTH_FRAME_RX, 188) \
+ BRCMF_ENUM_DEF(MGMT_FRAME_TXSTATUS, 189) \
+ BRCMF_ENUM_DEF(MGMT_FRAME_OFF_CHAN_COMPLETE, 190)
#define BRCMF_ENUM_DEF(id, val) \
BRCMF_E_##id = (val),
@@ -104,7 +108,7 @@ enum brcmf_fweh_event_code {
* minimum length check in device firmware so it is
* hard-coded here.
*/
- BRCMF_E_LAST = 147
+ BRCMF_E_LAST = 191
};
#undef BRCMF_ENUM_DEF
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index 0706e04b983e..afedb7627029 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -182,6 +182,11 @@ enum {
#define BRCMF_HE_CAP_MCS_MAP_NSS_MAX 8
+#define BRCMF_EXTAUTH_START 1
+#define BRCMF_EXTAUTH_ABORT 2
+#define BRCMF_EXTAUTH_FAIL 3
+#define BRCMF_EXTAUTH_SUCCESS 4
+
/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each
* ioctl. It is relatively small because firmware has small maximum size input
* playload restriction for ioctls.
@@ -544,6 +549,46 @@ struct brcmf_wsec_sae_pwd_le {
u8 key[BRCMF_WSEC_MAX_SAE_PASSWORD_LEN];
};
+/**
+ * struct brcmf_auth_req_status_le - external auth request and status update
+ *
+ * @flags: flags for external auth status
+ * @peer_mac: peer MAC address
+ * @ssid_len: length of ssid
+ * @ssid: ssid characters
+ */
+struct brcmf_auth_req_status_le {
+ __le16 flags;
+ u8 peer_mac[ETH_ALEN];
+ __le32 ssid_len;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+};
+
+/**
+ * struct brcmf_mf_params_le - management frame parameters for mgmt_frame iovar
+ *
+ * @version: version of the iovar
+ * @dwell_time: dwell duration in ms
+ * @len: length of frame data
+ * @frame_control: frame control
+ * @channel: channel
+ * @da: peer MAC address
+ * @bssid: BSS network identifier
+ * @packet_id: packet identifier
+ * @data: frame data
+ */
+struct brcmf_mf_params_le {
+ __le32 version;
+ __le32 dwell_time;
+ __le16 len;
+ __le16 frame_control;
+ __le16 channel;
+ u8 da[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ __le32 packet_id;
+ u8 data[1];
+};
+
/* Used to get specific STA parameters */
struct brcmf_scb_val_le {
__le32 val;
--
2.17.1

View File

@@ -0,0 +1,46 @@
From e1990521f370bf646b58c83115efd989763132d6 Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Fri, 26 Mar 2021 02:14:17 -0500
Subject: [PATCH 079/179] brcmfmac: fix sdio watchdog timer start fail issue
brcmf_sdio_wd_timer() started before F2 function enabling. In
such case, it will be returned because the sdiodev state is not
BRCMF_SDIOD_DATA. The first timer start will then fail. As a
fix, run brcmf_sdio_wd_timer() after F2 function enabling instead.
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index bd1e5842dc3d..3ced22ffa78b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4435,10 +4435,6 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
goto fail;
bus->alp_only = false;
- /* Start the watchdog timer */
- bus->sdcnt.tickcnt = 0;
- brcmf_sdio_wd_timer(bus, true);
-
sdio_claim_host(sdiod->func1);
/* Make sure backplane clock is on, needed to generate F2 interrupt */
@@ -4587,6 +4583,10 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
sdio_release_host(sdiod->func1);
+ /* Start the watchdog timer */
+ bus->sdcnt.tickcnt = 0;
+ brcmf_sdio_wd_timer(bus, true);
+
err = brcmf_alloc(sdiod->dev, sdiod->settings);
if (err) {
brcmf_err("brcmf_alloc failed\n");
--
2.17.1

View File

@@ -0,0 +1,147 @@
From 6a5c92be8baaa0d6b44f47ac8a2232503c2ac67f Mon Sep 17 00:00:00 2001
From: Divya Madhyan <Divya.Madhyan@infineon.com>
Date: Mon, 5 Apr 2021 05:49:50 -0500
Subject: [PATCH 080/179] brcmfmac: Frameburst vendor command addition
These set of changes are added to enable frameburst
vendor command support in IW tool.
The vendor send command has to be in the format :
./iw dev wlan0 vendor send 0x001018 0x02 0x0/0x1
The vendor get/query command will be in the format :
./iw dev wlan0 vendor recv 0x001018 0x02 0xff
Signed-off-by: Divya Madhyan <Divya.Madhyan@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +-
.../broadcom/brcm80211/brcmfmac/fwil.h | 1 +
.../broadcom/brcm80211/brcmfmac/vendor.c | 64 +++++++++++++++++++
.../broadcom/brcm80211/brcmfmac/vendor.h | 1 +
4 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 33f1f5beac21..5acc7fbfcee2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3201,10 +3201,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
pm = PM_OFF;
}
- if (cfg->pwr_save)
- brcmf_set_mpc(ifp, ifp->drvr->req_mpc);
- else
- brcmf_set_mpc(ifp, 0);
+ brcmf_set_mpc(ifp, ifp->drvr->req_mpc);
brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
index 8a9fca90323a..17302da9fb51 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
@@ -71,6 +71,7 @@
#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
#define BRCMF_C_SET_ASSOC_PREFER 205
#define BRCMF_C_GET_VALID_CHANNELS 217
+#define BRCMF_C_GET_FAKEFRAG 218
#define BRCMF_C_SET_FAKEFRAG 219
#define BRCMF_C_GET_KEY_PRIMARY 235
#define BRCMF_C_SET_KEY_PRIMARY 236
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
index bf425d2c27bf..dec1307a0e00 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c
@@ -114,6 +114,60 @@ static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
return ret;
}
+static int brcmf_cfg80211_vndr_cmds_int_get(struct brcmf_if *ifp,
+ u32 cmd, struct wiphy *wiphy)
+{
+ struct sk_buff *reply;
+ int get_value = 0;
+ int ret;
+
+ ret = brcmf_fil_cmd_int_get(ifp, cmd, &get_value);
+ if (ret)
+ brcmf_err("Command %u get failure. Error : %d\n", cmd, ret);
+
+ reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(int));
+ nla_put_nohdr(reply, sizeof(int), &get_value);
+ ret = cfg80211_vendor_cmd_reply(reply);
+ if (ret)
+ brcmf_err("Command %u failure. Error : %d\n", cmd, ret);
+ return ret;
+}
+
+static int brcmf_cfg80211_vndr_cmds_int_set(struct brcmf_if *ifp, int val, u32 cmd)
+{
+ int ret;
+
+ ret = brcmf_fil_cmd_int_set(ifp, cmd, val);
+ if (ret < 0)
+ brcmf_err("Command %u set failure. Error : %d\n", cmd, ret);
+ return ret;
+}
+
+static int brcmf_cfg80211_vndr_cmds_frameburst(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int len)
+{
+ int ret;
+ int val = *(int *)data;
+ struct brcmf_cfg80211_vif *vif;
+ struct brcmf_if *ifp;
+
+ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
+ ifp = vif->ifp;
+
+ if (val == 0x0 || val == 0x1)
+ ret = brcmf_cfg80211_vndr_cmds_int_set(ifp, val,
+ BRCMF_C_SET_FAKEFRAG);
+ else if (val == 0xff)
+ ret = brcmf_cfg80211_vndr_cmds_int_get(ifp,
+ BRCMF_C_GET_FAKEFRAG,
+ wiphy);
+ else
+ brcmf_err("Invalid Input\n");
+
+ return ret;
+}
+
s32
brcmf_wiphy_phy_temp_evt_handler(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
@@ -175,6 +229,16 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = {
.policy = VENDOR_CMD_RAW_DATA,
.doit = brcmf_cfg80211_vndr_cmds_dcmd_handler
},
+ {
+ {
+ .vendor_id = BROADCOM_OUI,
+ .subcmd = BRCMF_VNDR_CMDS_FRAMEBURST
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .policy = VENDOR_CMD_RAW_DATA,
+ .doit = brcmf_cfg80211_vndr_cmds_frameburst
+ },
};
const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h
index 3bdf47369788..3c691bbe0bae 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h
@@ -11,6 +11,7 @@
enum brcmf_vndr_cmds {
BRCMF_VNDR_CMDS_UNSPEC,
BRCMF_VNDR_CMDS_DCMD,
+ BRCMF_VNDR_CMDS_FRAMEBURST,
BRCMF_VNDR_CMDS_LAST
};
--
2.17.1

View File

@@ -0,0 +1,88 @@
From e7c2474c59499879dc85649a285c62b637de0615 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Wed, 15 Apr 2020 04:01:46 -0500
Subject: [PATCH 081/179] brcmfmac: add support for CYW43439 SDIO chipset
CYW43439 is 43430a5 chip, which is Single-band 2.4 GHz IEEE 802.11b/g/n
256-QAM/Turbo QAMand 20 MHz channel bandwidth.
Without OTP programmed, the chip ID is 43430 with revision 5.
With OTP programmed, the chip ID is 43439 with revision 5.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 +
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 5 ++++-
.../net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
include/linux/mmc/sdio_ids.h | 1 +
4 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index df4fd7837b6d..089039d4134e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -990,6 +990,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4359),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43439),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_4373),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43012),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43752),
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 3ced22ffa78b..21221afb54cc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -631,6 +631,7 @@ BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio");
/* Note the names are not postfixed with a1 for backward compatibility */
CY_FW_DEF(43430A1, "cyfmac43430-sdio");
BRCMF_FW_DEF(43430B0, "brcmfmac43430b0-sdio");
+CY_FW_DEF(43439, "cyfmac43439-sdio");
CY_FW_DEF(43455, "cyfmac43455-sdio");
BRCMF_FW_DEF(43456, "brcmfmac43456-sdio");
CY_FW_DEF(4354, "cyfmac4354-sdio");
@@ -660,13 +661,15 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362),
BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0),
- BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000002, 43430A1),
+ BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x0000001E, 43430A1),
BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFC, 43430B0),
BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0x00000200, 43456),
BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455),
BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359),
+ BRCMF_FW_ENTRY(CY_CC_43430_CHIP_ID, 0xFFFFFFE0, 43439),
+ BRCMF_FW_ENTRY(CY_CC_43439_CHIP_ID, 0xFFFFFFE0, 43439),
BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373),
BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012),
BRCMF_FW_ENTRY(CY_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752)
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 26cc84ae12d7..237925a13d38 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -50,6 +50,8 @@
#define BRCM_CC_43664_CHIP_ID 43664
#define BRCM_CC_43666_CHIP_ID 43666
#define BRCM_CC_4371_CHIP_ID 0x4371
+#define CY_CC_43430_CHIP_ID 43430
+#define CY_CC_43439_CHIP_ID 43439
#define CY_CC_4373_CHIP_ID 0x4373
#define CY_CC_43012_CHIP_ID 43012
#define CY_CC_43752_CHIP_ID 43752
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index a85c9f0bd470..4e62dfaca878 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -66,6 +66,7 @@
#define SDIO_DEVICE_ID_BROADCOM_CYPRESS_89359 0x4355
#define SDIO_DEVICE_ID_BROADCOM_4356 0x4356
#define SDIO_DEVICE_ID_BROADCOM_4359 0x4359
+#define SDIO_DEVICE_ID_BROADCOM_CYPRESS_43439 0xa9af
#define SDIO_DEVICE_ID_BROADCOM_CYPRESS_4373 0x4373
#define SDIO_DEVICE_ID_BROADCOM_CYPRESS_43012 0xa804
#define SDIO_DEVICE_ID_BROADCOM_43143 0xa887
--
2.17.1

View File

@@ -0,0 +1,622 @@
From 1421a6cf03dec762a6aa45955b77087838e3388f Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Wed, 15 Apr 2020 01:25:45 -0500
Subject: [PATCH 082/179] brcmfmac: add BT shared SDIO support
This feature is about sharing the SDIO bus interface between BT host
driver and FMAC WiFi host driver. To enable this feature, it needs to
set CONFIG_BRCMFMAC_BT_SHRAED_SDIO=y in kernel configuration.
Verified: BTSDIO driver loopback test
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Ian Lin <ian.lin-ee@infineon.com>
---
.../net/wireless/broadcom/brcm80211/Kconfig | 9 +
.../broadcom/brcm80211/brcmfmac/Kconfig | 7 +
.../broadcom/brcm80211/brcmfmac/Makefile | 2 +
.../brcm80211/brcmfmac/bt_shared_sdio.c | 326 ++++++++++++++++++
.../brcm80211/brcmfmac/bt_shared_sdio.h | 43 +++
.../broadcom/brcm80211/brcmfmac/bus.h | 17 +
.../broadcom/brcm80211/brcmfmac/sdio.c | 68 +++-
7 files changed, 471 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.c
create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.h
diff --git a/drivers/net/wireless/broadcom/brcm80211/Kconfig b/drivers/net/wireless/broadcom/brcm80211/Kconfig
index 5b801ff6b904..5dbc1e2a83fc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
@@ -48,3 +48,12 @@ config BRCMFMAC_PCIE_BARWIN_SZ
window size. Say Y to allow developers to use custom PCIE
BAR window size when HOST PCIE IP can support less then 4MB
BAR window.
+
+config BRCMFMAC_BT_SHARED_SDIO
+ bool "FMAC shares SDIO bus to Bluetooth"
+ depends on BRCMFMAC
+ depends on BRCMFMAC_SDIO
+ default n
+ help
+ Selecting this to enables sharing the SDIO bus interface between
+ Cypress BT and WiFi host drivers.
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig
index 32794c1eca23..48b5bccd5474 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig
@@ -48,3 +48,10 @@ config BRCMFMAC_PCIE
IEEE802.11ac embedded FullMAC WLAN driver. Say Y if you want to
use the driver for an PCIE wireless card.
+config BRCMFMAC_BT_SHARED_SDIO
+ bool "FMAC shares SDIO bus to Bluetooth"
+ depends on BRCMFMAC_SDIO
+ default n
+ help
+ This option enables the feautre of sharing the SDIO bus interface
+ between Cypress BT and WiFi host drivers.
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
index 13c13504a6e8..baf713279532 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
@@ -47,3 +47,5 @@ brcmfmac-$(CONFIG_OF) += \
of.o
brcmfmac-$(CONFIG_DMI) += \
dmi.o
+brcmfmac-${CONFIG_BRCMFMAC_BT_SHARED_SDIO} += \
+ bt_shared_sdio.o
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.c
new file mode 100644
index 000000000000..ef6283622697
--- /dev/null
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: ISC
+
+/* Copyright 2019, Cypress Semiconductor Corporation or a subsidiary of
+ * Cypress Semiconductor Corporation. All rights reserved.
+ * This software, including source code, documentation and related
+ * materials ("Software"), is owned by Cypress Semiconductor
+ * Corporation or one of its subsidiaries ("Cypress") and is protected by
+ * and subject to worldwide patent protection (United States and foreign),
+ * United States copyright laws and international treaty provisions.
+ * Therefore, you may use this Software only as provided in the license
+ * agreement accompanying the software package from which you
+ * obtained this Software ("EULA"). If no EULA applies, Cypress hereby grants
+ * you a personal, nonexclusive, non-transferable license to copy, modify,
+ * and compile the Software source code solely for use in connection with
+ * Cypress's integrated circuit products. Any reproduction, modification,
+ * translation, compilation, or representation of this Software except as
+ * specified above is prohibited without the express written permission of
+ * Cypress.
+ * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress
+ * reserves the right to make changes to the Software without notice. Cypress
+ * does not assume any liability arising out of the application or use of the
+ * Software or any product or circuit described in the Software. Cypress does
+ * not authorize its products for use in any products where a malfunction or
+ * failure of the Cypress product may reasonably be expected to result in
+ * significant property damage, injury or death ("High Risk Product"). By
+ * including Cypress's product in a High Risk Product, the manufacturer
+ * of such system or application assumes all risk of such use and in doing
+ * so agrees to indemnify Cypress against all liability.
+ */
+
+#include <linux/types.h>
+#include <linux/atomic.h>
+#include <linux/kernel.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/card.h>
+#include "bus.h"
+#include "chipcommon.h"
+#include "core.h"
+#include "sdio.h"
+#include "soc.h"
+#include "fwil.h"
+
+#define SDIOD_ADDR_BOUND 0x1000
+#define SDIOD_ADDR_BOUND_MASK 0xfff
+
+struct brcmf_bus *g_bus_if;
+
+enum bus_owner {
+ WLAN_MODULE = 0,
+ BT_MODULE
+};
+
+struct btsdio_info {
+ u32 bt_buf_reg_addr;
+ u32 host_ctrl_reg_addr;
+ u32 bt_ctrl_reg_addr;
+ u32 bt_buf_addr;
+ u32 wlan_buf_addr;
+};
+
+void brcmf_btsdio_int_handler(struct brcmf_bus *bus_if)
+{
+ struct brcmf_bt_dev *btdev = bus_if->bt_dev;
+
+ if (btdev && btdev->bt_sdio_int_cb)
+ btdev->bt_sdio_int_cb(btdev->bt_data);
+}
+
+int brcmf_btsdio_init(struct brcmf_bus *bus_if)
+{
+ if (!bus_if)
+ return -EINVAL;
+
+ g_bus_if = bus_if;
+ return 0;
+}
+
+int brcmf_btsdio_attach(struct brcmf_bus *bus_if, void *btdata,
+ void (*bt_int_fun)(void *data))
+{
+ struct brcmf_bt_dev *btdev;
+
+ /* Allocate bt dev */
+ btdev = kzalloc(sizeof(*btdev), GFP_ATOMIC);
+ if (!btdev)
+ return -ENOMEM;
+
+ btdev->bt_data = btdata;
+ btdev->bt_sdio_int_cb = bt_int_fun;
+ bus_if->bt_dev = btdev;
+
+ return 0;
+}
+
+void brcmf_btsdio_detach(struct brcmf_bus *bus_if)
+{
+ struct brcmf_bt_dev *btdev = bus_if->bt_dev;
+
+ if (!btdev)
+ return;
+
+ if (btdev->bt_data)
+ btdev->bt_data = NULL;
+ if (btdev->bt_sdio_int_cb)
+ btdev->bt_sdio_int_cb = NULL;
+ if (bus_if->bt_dev) {
+ bus_if->bt_dev = NULL;
+ kfree(btdev);
+ }
+}
+
+u8 brcmf_btsdio_bus_count(struct brcmf_bus *bus_if)
+{
+ struct brcmf_bt_dev *btdev = bus_if->bt_dev;
+
+ if (!btdev)
+ return 0;
+
+ return btdev->use_count;
+}
+
+void *brcmf_bt_sdio_attach(void *btdata, void (*bt_int_fun)(void *data))
+{
+ int err;
+
+ if (!g_bus_if) {
+ brcmf_err("BTSDIO is not initialized\n");
+ return NULL;
+ }
+
+ err = brcmf_btsdio_attach(g_bus_if, btdata, bt_int_fun);
+ if (err) {
+ brcmf_err("BTSDIO attach failed, err=%d\n", err);
+ return NULL;
+ }
+
+ return (void *)g_bus_if;
+}
+EXPORT_SYMBOL(brcmf_bt_sdio_attach);
+
+int brcmf_get_wlan_info(struct brcmf_bus *bus_if, struct btsdio_info *bs_info)
+{
+ struct brcmf_if *ifp;
+
+ if (!bus_if || !bs_info)
+ return -EINVAL;
+
+ ifp = bus_if->drvr->iflist[0];
+
+ bs_info->bt_buf_reg_addr = SI_ENUM_BASE_DEFAULT + 0xC00 +
+ CHIPGCIREGOFFS(gci_input[6]);
+ bs_info->host_ctrl_reg_addr = SI_ENUM_BASE_DEFAULT + 0xC00 +
+ CHIPGCIREGOFFS(gci_output[3]);
+ bs_info->bt_ctrl_reg_addr = SI_ENUM_BASE_DEFAULT + 0xC00 +
+ CHIPGCIREGOFFS(gci_input[7]);
+ brcmf_dbg(INFO, "BT buf reg addr: 0x%x\n",
+ bs_info->bt_buf_reg_addr);
+ brcmf_dbg(INFO, "HOST ctrl reg addr: 0x%x\n",
+ bs_info->host_ctrl_reg_addr);
+ brcmf_dbg(INFO, "BT ctrl reg addr: 0x%x\n",
+ bs_info->bt_ctrl_reg_addr);
+ return 0;
+}
+EXPORT_SYMBOL(brcmf_get_wlan_info);
+
+u32 brcmf_bus_reg_read(struct brcmf_bus *bus_if, u32 addr)
+{
+ struct brcmf_sdio_dev *sdiodev;
+ int err = 0;
+ u32 val;
+
+ if (!bus_if)
+ return -EINVAL;
+
+ sdiodev = bus_if->bus_priv.sdio;
+
+ sdio_claim_host(sdiodev->func1);
+ val = brcmf_sdiod_readl(sdiodev, addr, &err);
+ if (err) {
+ brcmf_err("sdio reg read failed, err=%d\n", err);
+ sdio_release_host(sdiodev->func1);
+ return err;
+ }
+ sdio_release_host(sdiodev->func1);
+
+ return val;
+}
+EXPORT_SYMBOL(brcmf_bus_reg_read);
+
+void brcmf_bus_reg_write(struct brcmf_bus *bus_if, u32 addr, u32 val)
+{
+ struct brcmf_sdio_dev *sdiodev;
+ int err = 0;
+
+ if (!bus_if)
+ return;
+
+ sdiodev = bus_if->bus_priv.sdio;
+
+ sdio_claim_host(sdiodev->func1);
+ brcmf_sdiod_writel(sdiodev, addr, val, &err);
+ if (err)
+ brcmf_err("sdio reg write failed, err=%d\n", err);
+ sdio_release_host(sdiodev->func1);
+}
+EXPORT_SYMBOL(brcmf_bus_reg_write);
+
+int brcmf_membytes(struct brcmf_bus *bus_if, bool set, u32 address, u8 *data,
+ unsigned int size)
+{
+ struct brcmf_sdio_dev *sdiodev;
+ int err = 0;
+ u32 block1_offset;
+ u32 block2_addr;
+ u16 block1_size;
+ u16 block2_size;
+ u8 *block2_data;
+
+ if (!bus_if || !data)
+ return -EINVAL;
+
+ sdiodev = bus_if->bus_priv.sdio;
+ /* To avoid SDIO access crosses AXI 4k address boundaries crossing */
+ if (((address & SDIOD_ADDR_BOUND_MASK) + size) > SDIOD_ADDR_BOUND) {
+ brcmf_dbg(SDIO, "data cross 4K boundary\n");
+ /* The 1st 4k packet */
+ block1_offset = address & SDIOD_ADDR_BOUND_MASK;
+ block1_size = (SDIOD_ADDR_BOUND - block1_offset);
+ sdio_claim_host(sdiodev->func1);
+ err = brcmf_sdiod_ramrw(sdiodev, set, address,
+ data, block1_size);
+ if (err) {
+ brcmf_err("sdio memory access failed, err=%d\n", err);
+ sdio_release_host(sdiodev->func1);
+ return err;
+ }
+ /* The 2nd 4k packet */
+ block2_addr = address + block1_size;
+ block2_size = size - block1_size;
+ block2_data = data + block1_size;
+ err = brcmf_sdiod_ramrw(sdiodev, set, block2_addr,
+ block2_data, block2_size);
+ if (err)
+ brcmf_err("sdio memory access failed, err=%d\n", err);
+ sdio_release_host(sdiodev->func1);
+ } else {
+ sdio_claim_host(sdiodev->func1);
+ err = brcmf_sdiod_ramrw(sdiodev, set, address, data, size);
+ if (err)
+ brcmf_err("sdio memory access failed, err=%d\n", err);
+ sdio_release_host(sdiodev->func1);
+ }
+ return err;
+}
+EXPORT_SYMBOL(brcmf_membytes);
+
+/* Function to enable the Bus Clock
+ * This function is not callable from non-sleepable context
+ */
+int brcmf_bus_clk_enable(struct brcmf_bus *bus_if, enum bus_owner owner)
+{
+ struct brcmf_sdio_dev *sdiodev;
+ struct brcmf_bt_dev *btdev;
+ int err = 0;
+
+ if (!bus_if)
+ return -EINVAL;
+
+ btdev = bus_if->bt_dev;
+ sdiodev = bus_if->bus_priv.sdio;
+
+ sdio_claim_host(sdiodev->func1);
+ btdev->use_count++;
+ sdio_release_host(sdiodev->func1);
+ err = brcmf_sdio_sleep(sdiodev->bus, false);
+
+ return err;
+}
+EXPORT_SYMBOL(brcmf_bus_clk_enable);
+
+/* Function to disable the Bus Clock
+ * This function is not callable from non-sleepable context
+ */
+int brcmf_bus_clk_disable(struct brcmf_bus *bus_if, enum bus_owner owner)
+{
+ struct brcmf_sdio_dev *sdiodev;
+ struct brcmf_bt_dev *btdev;
+ int err = 0;
+
+ if (!bus_if)
+ return -EINVAL;
+
+ btdev = bus_if->bt_dev;
+ sdiodev = bus_if->bus_priv.sdio;
+
+ sdio_claim_host(sdiodev->func1);
+ if (btdev->use_count != 0)
+ btdev->use_count--;
+ sdio_release_host(sdiodev->func1);
+ err = brcmf_sdio_sleep(sdiodev->bus, true);
+
+ return err;
+}
+EXPORT_SYMBOL(brcmf_bus_clk_disable);
+
+/* Function to reset bt_use_count counter to zero.
+ * This function is not callable from non-sleepable context
+ */
+void brcmf_bus_reset_bt_use_count(struct brcmf_bus *bus_if)
+{
+ struct brcmf_sdio_dev *sdiodev;
+ struct brcmf_bt_dev *btdev;
+
+ if (!bus_if)
+ return;
+
+ btdev = bus_if->bt_dev;
+ sdiodev = bus_if->bus_priv.sdio;
+
+ sdio_claim_host(sdiodev->func1);
+ btdev->use_count = 0;
+ sdio_release_host(sdiodev->func1);
+}
+EXPORT_SYMBOL(brcmf_bus_reset_bt_use_count);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.h
new file mode 100644
index 000000000000..f0e6b38cf77f
--- /dev/null
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: ISC */
+/* Copyright 2019, Cypress Semiconductor Corporation or a subsidiary of
+ * Cypress Semiconductor Corporation. All rights reserved.
+ * This software, including source code, documentation and related
+ * materials ("Software"), is owned by Cypress Semiconductor
+ * Corporation or one of its subsidiaries ("Cypress") and is protected by
+ * and subject to worldwide patent protection (United States and foreign),
+ * United States copyright laws and international treaty provisions.
+ * Therefore, you may use this Software only as provided in the license
+ * agreement accompanying the software package from which you
+ * obtained this Software ("EULA"). If no EULA applies, Cypress hereby grants
+ * you a personal, nonexclusive, non-transferable license to copy, modify,
+ * and compile the Software source code solely for use in connection with
+ * Cypress's integrated circuit products. Any reproduction, modification,
+ * translation, compilation, or representation of this Software except as
+ * specified above is prohibited without the express written permission of
+ * Cypress.
+ * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress
+ * reserves the right to make changes to the Software without notice. Cypress
+ * does not assume any liability arising out of the application or use of the
+ * Software or any product or circuit described in the Software. Cypress does
+ * not authorize its products for use in any products where a malfunction or
+ * failure of the Cypress product may reasonably be expected to result in
+ * significant property damage, injury or death ("High Risk Product"). By
+ * including Cypress's product in a High Risk Product, the manufacturer
+ * of such system or application assumes all risk of such use and in doing
+ * so agrees to indemnify Cypress against all liability.
+ */
+
+#ifdef CONFIG_BRCMFMAC_BT_SHARED_SDIO
+int brcmf_btsdio_init(struct brcmf_bus *bus_if);
+void brcmf_btsdio_detach(struct brcmf_bus *bus_if);
+void brcmf_btsdio_int_handler(struct brcmf_bus *bus_if);
+u8 brcmf_btsdio_bus_count(struct brcmf_bus *bus_if);
+#else
+static inline
+u8 brcmf_btsdio_bus_count(struct brcmf_bus *bus_if)
+{
+ return 0;
+}
+#endif /* CONFIG_BRCMFMAC_BT_SHARED_SDIO */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index 18e3a4286a5d..09d733812c98 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -124,6 +124,19 @@ struct brcmf_bus_stats {
atomic_t pktcow_failed;
};
+/**
+ * struct brcmf_bt_dev - bt shared SDIO device.
+ *
+ * @ bt_data: bt internal structure data
+ * @ bt_sdio_int_cb: bt registered interrupt callback function
+ * @ bt_use_count: Counter that tracks whether BT is using the bus
+ */
+struct brcmf_bt_dev {
+ void *bt_data;
+ void (*bt_sdio_int_cb)(void *data);
+ u32 use_count; /* Counter for tracking if BT is using the bus */
+};
+
/**
* struct brcmf_bus - interface structure between common and bus layer
*
@@ -139,6 +152,7 @@ struct brcmf_bus_stats {
* @wowl_supported: is wowl supported by bus driver.
* @chiprev: revision of the dongle chip.
* @msgbuf: msgbuf protocol parameters provided by bus layer.
+ * @bt_dev: bt shared SDIO device
*/
struct brcmf_bus {
union {
@@ -162,6 +176,9 @@ struct brcmf_bus {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0))
bool allow_skborphan;
#endif
+#ifdef CONFIG_BRCMFMAC_BT_SHARED_SDIO
+ struct brcmf_bt_dev *bt_dev;
+#endif /* CONFIG_BRCMFMAC_BT_SHARED_SDIO */
};
/*
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 21221afb54cc..c1fb3fedf037 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -38,6 +38,7 @@
#include "common.h"
#include "bcdc.h"
#include "fwil.h"
+#include "bt_shared_sdio.h"
#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
@@ -950,6 +951,20 @@ static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
break;
case CLK_SDONLY:
+#ifdef CONFIG_BRCMFMAC_BT_SHARED_SDIO
+ /* If the request is to switch off backplane clock,
+ * confirm that BT is inactive before doing so.
+ * If this call had come from Non Watchdog context any way
+ * the Watchdog would switch off the clock again when
+ * nothing is to be done & BT has finished using the bus.
+ */
+ if (brcmf_btsdio_bus_count(bus->sdiodev->bus_if)) {
+ brcmf_dbg(SDIO, "BT is active, not switching off\n");
+ brcmf_sdio_wd_timer(bus, true);
+ break;
+ }
+
+#endif /* CONFIG_BRCMFMAC_BT_SHARED_SDIO */
/* Remove HT request, or bring up SD clock */
if (bus->clkstate == CLK_NONE)
brcmf_sdio_sdclk(bus, true);
@@ -961,6 +976,19 @@ static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
break;
case CLK_NONE:
+#ifdef CONFIG_BRCMFMAC_BT_SHARED_SDIO
+ /* If the request is to switch off backplane clock,
+ * confirm that BT is inactive before doing so.
+ * If this call had come from non-watchdog context any way
+ * the watchdog would switch off the clock again when
+ * nothing is to be done & BT has finished using the bus.
+ */
+ if (brcmf_btsdio_bus_count(bus->sdiodev->bus_if)) {
+ brcmf_dbg(SDIO, "BT is active, not switching off\n");
+ break;
+ }
+#endif /* CONFIG_BRCMFMAC_BT_SHARED_SDIO */
+
/* Make sure to remove HT request */
if (bus->clkstate == CLK_AVAIL)
brcmf_sdio_htclk(bus, false, false);
@@ -985,6 +1013,29 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
(sleep ? "SLEEP" : "WAKE"),
(bus->sleeping ? "SLEEP" : "WAKE"));
+#ifdef CONFIG_BRCMFMAC_BT_SHARED_SDIO
+ /* The following is the assumption based on which the hook is placed.
+ * From WLAN driver, either from the active contexts OR from the
+ * watchdog contexts, we will be attempting to go to sleep. At that
+ * moment if we see that BT is still actively using the bus, we will
+ * return -EBUSY from here, and the bus sleep state would not have
+ * changed, so the caller can then schedule the watchdog again
+ * which will come and attempt to sleep at a later point.
+ *
+ * In case if BT is the only one and is the last user, we don't switch
+ * off the clock immediately, we allow the WLAN to decide when to sleep
+ * i.e from the watchdog.
+ * Now if the watchdog becomes active and attempts to switch off the
+ * clock and if another WLAN context is active they are any way
+ * serialized with sdlock.
+ */
+ if (brcmf_btsdio_bus_count(bus->sdiodev->bus_if)) {
+ brcmf_dbg(SDIO, "Cannot sleep when BT is active\n");
+ err = -EBUSY;
+ goto done;
+ }
+#endif /* CONFIG_BRCMFMAC_BT_SHARED_SDIO */
+
/* If SR is enabled control bus state with KSO */
if (bus->sr_enabled) {
/* Done if we're already in the requested state */
@@ -2843,6 +2894,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
atomic_set(&bus->fcstate,
!!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)));
intstatus |= (newstatus & bus->hostintmask);
+#ifdef CONFIG_BRCMFMAC_BT_SHARED_SDIO
+ brcmf_btsdio_int_handler(bus->sdiodev->bus_if);
+#endif /* CONFIG_BRCMFMAC_BT_SHARED_SDIO */
}
/* Handle host mailbox indication */
@@ -3935,7 +3989,8 @@ static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
#endif /* DEBUG */
/* On idle timeout clear activity flag and/or turn off clock */
- if (!bus->dpc_triggered) {
+ if (!bus->dpc_triggered &&
+ brcmf_btsdio_bus_count(bus->sdiodev->bus_if) == 0) {
rmb();
if ((!bus->dpc_running) && (bus->idletime > 0) &&
(bus->clkstate == CLK_AVAIL)) {
@@ -4596,6 +4651,14 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
goto claim;
}
+#ifdef CONFIG_BRCMFMAC_BT_SHARED_SDIO
+ err = brcmf_btsdio_init(bus_if);
+ if (err) {
+ brcmf_err("brcmf_btsdio_init failed\n");
+ goto free;
+ }
+#endif /* CONFIG_BRCMFMAC_BT_SHARED_SDIO */
+
/* Attach to the common layer, reserve hdr space */
err = brcmf_attach(sdiod->dev, !bus->sdiodev->ulp);
if (err != 0) {
@@ -4822,6 +4885,9 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
}
if (bus->sdiodev->settings)
brcmf_release_module_param(bus->sdiodev->settings);
+#ifdef CONFIG_BRCMFMAC_BT_SHARED_SDIO
+ brcmf_btsdio_detach(bus->sdiodev->bus_if);
+#endif /* CONFIG_BRCMFMAC_BT_SHARED_SDIO */
kfree(bus->rxbuf);
kfree(bus->hdrbuf);
--
2.17.1

View File

@@ -0,0 +1,79 @@
From c47267fd331ea3fbde18512c2886730ba368bd66 Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Mon, 18 May 2020 23:13:34 -0500
Subject: [PATCH 083/179] brcmfmac: add CYW43439 SR related changes
Because SR and chip related behvior are same as 43430a1, we align all
43439 code flow with 43430a1.
This commit should be squashed into previous 43439 support commit.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 5 ++++-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 3 ++-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 +--
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 6829ca086695..186b5bee33b4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -659,6 +659,7 @@ static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize,
*srsize = (32 * 1024);
break;
case BRCM_CC_43430_CHIP_ID:
+ case CY_CC_43439_CHIP_ID:
/* assume sr for now as we can not check
* firmware sr capability at this point.
*/
@@ -1285,7 +1286,8 @@ brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)
brcmf_chip_resetcore(core, 0, 0, 0);
/* disable bank #3 remap for this device */
- if (chip->pub.chip == BRCM_CC_43430_CHIP_ID) {
+ if (chip->pub.chip == BRCM_CC_43430_CHIP_ID ||
+ chip->pub.chip == CY_CC_43439_CHIP_ID) {
sr = container_of(core, struct brcmf_core_priv, pub);
brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3);
brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0);
@@ -1442,6 +1444,7 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
reg = chip->ops->read32(chip->ctx, addr);
return (reg & pmu_cc3_mask) != 0;
case BRCM_CC_43430_CHIP_ID:
+ case CY_CC_43439_CHIP_ID:
addr = CORE_CC_REG(base, sr_control1);
reg = chip->ops->read32(chip->ctx, addr);
return reg != 0;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 94fa06749631..f0c603ba64b8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -248,7 +248,8 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
brcmf_feat_firmware_capabilities(ifp);
memset(&gscan_cfg, 0, sizeof(gscan_cfg));
if (drvr->bus_if->chip != BRCM_CC_43430_CHIP_ID &&
- drvr->bus_if->chip != BRCM_CC_4345_CHIP_ID)
+ drvr->bus_if->chip != BRCM_CC_4345_CHIP_ID &&
+ drvr->bus_if->chip != CY_CC_43439_CHIP_ID)
brcmf_feat_iovar_data_set(ifp, BRCMF_FEAT_GSCAN,
"pfn_gscan_cfg",
&gscan_cfg, sizeof(gscan_cfg));
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index c1fb3fedf037..96d16a99ab67 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -669,8 +669,7 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359),
- BRCMF_FW_ENTRY(CY_CC_43430_CHIP_ID, 0xFFFFFFE0, 43439),
- BRCMF_FW_ENTRY(CY_CC_43439_CHIP_ID, 0xFFFFFFE0, 43439),
+ BRCMF_FW_ENTRY(CY_CC_43439_CHIP_ID, 0xFFFFFFFF, 43439),
BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373),
BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012),
BRCMF_FW_ENTRY(CY_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752)
--
2.17.1

View File

@@ -0,0 +1,29 @@
From f5757ad1fc68803adc0fb97d05d9d9f78fffa37c Mon Sep 17 00:00:00 2001
From: Double Lo <double.lo@cypress.com>
Date: Mon, 22 Jun 2020 18:43:56 -0500
Subject: [PATCH 084/179] brcmfmac: add support for CYW43439 with blank OTP
Without OTP programmed, the chip ID is 43430 with revision 5.
Add support for such chips.
Signed-off-by: Double Lo <double.lo@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 96d16a99ab67..95f3c7e2a100 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -664,6 +664,7 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0),
BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x0000001E, 43430A1),
BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFC, 43430B0),
+ BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFE0, 43439),
BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0x00000200, 43456),
BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455),
BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
--
2.17.1

View File

@@ -0,0 +1,55 @@
From 1b09fc6411658347e621233572582fb93e1c7c8e Mon Sep 17 00:00:00 2001
From: Double Lo <double.lo@cypress.com>
Date: Mon, 6 Jul 2020 04:10:49 -0500
Subject: [PATCH 085/179] brcmfmac: support 43439 Cypress Vendor and Device ID
To add 43439 Cypress Vendor and Device ID:
43439 Cypress VID : 0x04b4
43439 Cypress DID : 0xbd3d
Signed-off-by: Double Lo <double.lo@cypress.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 ++++
include/linux/mmc/sdio_ids.h | 3 +++
2 files changed, 7 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 089039d4134e..b8d5931673a1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -971,6 +971,9 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
#define BRCMF_SDIO_DEVICE(dev_id) \
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, dev_id)}
+#define CYF_SDIO_DEVICE(dev_id) \
+ {SDIO_DEVICE(SDIO_VENDOR_ID_CYPRESS, dev_id)}
+
/* devices we support, null terminated */
static const struct sdio_device_id brcmf_sdmmc_ids[] = {
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43143),
@@ -995,6 +998,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43012),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43752),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_89359),
+ CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_43439),
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index 4e62dfaca878..657b8005f082 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -78,6 +78,9 @@
#define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf
#define SDIO_DEVICE_ID_BROADCOM_CYPRESS_43752 0xaae8
+#define SDIO_VENDOR_ID_CYPRESS 0x04b4
+#define SDIO_DEVICE_ID_CYPRESS_43439 0xbd3d
+
#define SDIO_VENDOR_ID_MARVELL 0x02df
#define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103
#define SDIO_DEVICE_ID_MARVELL_8688_WLAN 0x9104
--
2.17.1

View File

@@ -0,0 +1,33 @@
From ba08274412b062d11a716610624d491b851bc9b3 Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Date: Fri, 16 Jul 2021 01:46:23 -0500
Subject: [PATCH 086/179] brcmfmac: fix P2P device discovery failure
Commit 2de64ca7c9fa ("brcmfmac: p2p: Deal with set but unused
variables") removed the setting of vif for p2p device discovery in
brcmf_p2p_scan_prep(), causing the discovery failure.
Add back the setting to brcmf_p2p_scan_prep() to fix this.
Fixes: 2de64ca7c9fa ("brcmfmac: p2p: Deal with set but unused variables")
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index a614d0cf583e..783d4d776dc8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -940,6 +940,8 @@ int brcmf_p2p_scan_prep(struct wiphy *wiphy,
if (err)
return err;
+ vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
+
/* override .run_escan() callback. */
cfg->escan_info.run = brcmf_p2p_run_escan;
}
--
2.17.1

View File

@@ -0,0 +1,44 @@
From 2529049f56361da5d5349aa609fff0d0a4c5bb46 Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Thu, 15 Jul 2021 05:26:23 -0500
Subject: [PATCH 087/179] brcmfmac: Add SDIO verdor/device id for CYW89459 in
header file
- Add more SDIO vendor and device ids for supporting CYW89459.
- Rename 89359 to 89459 for device id 0x4355.
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
---
include/linux/mmc/sdio_ids.h | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index 657b8005f082..64d43a61249c 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -63,7 +63,7 @@
#define SDIO_DEVICE_ID_BROADCOM_4339 0x4339
#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345
#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
-#define SDIO_DEVICE_ID_BROADCOM_CYPRESS_89359 0x4355
+#define SDIO_DEVICE_ID_BROADCOM_CYPRESS_89459 0x4355
#define SDIO_DEVICE_ID_BROADCOM_4356 0x4356
#define SDIO_DEVICE_ID_BROADCOM_4359 0x4359
#define SDIO_DEVICE_ID_BROADCOM_CYPRESS_43439 0xa9af
@@ -78,8 +78,11 @@
#define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf
#define SDIO_DEVICE_ID_BROADCOM_CYPRESS_43752 0xaae8
-#define SDIO_VENDOR_ID_CYPRESS 0x04b4
-#define SDIO_DEVICE_ID_CYPRESS_43439 0xbd3d
+#define SDIO_VENDOR_ID_CYPRESS 0x04b4
+#define SDIO_DEVICE_ID_CYPRESS_54590 0xbd3a
+#define SDIO_DEVICE_ID_CYPRESS_54591 0xbd3b
+#define SDIO_DEVICE_ID_CYPRESS_54594 0xbd3c
+#define SDIO_DEVICE_ID_CYPRESS_43439 0xbd3d
#define SDIO_VENDOR_ID_MARVELL 0x02df
#define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103
--
2.17.1

View File

@@ -0,0 +1,115 @@
From ca1b98f96ab08aa7e4228714b62cb8f9785efc8c Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Thu, 15 Jul 2021 21:16:09 -0500
Subject: [PATCH 088/179] brcmfmac: Add CYW89459 HW ID and modify sdio F2 block
size/watermark
- Add 4359d0 HW ID for supporting 89459 SDIO.
- Modifying SDIO FUNC2 block size/watermark and mes watermark
suggested by chip team.
- Add more SDIO vendor and device ids for supporting CYW89459
commercial products.
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/bcmsdh.c | 12 +++++++++-
.../broadcom/brcm80211/brcmfmac/sdio.c | 24 ++++++++++++++++++-
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index b8d5931673a1..dee4fa033179 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -47,6 +47,7 @@
#define SDIO_4373_FUNC2_BLOCKSIZE 256
#define SDIO_435X_FUNC2_BLOCKSIZE 256
#define SDIO_4329_FUNC2_BLOCKSIZE 128
+#define SDIO_89459_FUNC2_BLOCKSIZE 256
/* Maximum milliseconds to wait for F2 to come up */
#define SDIO_WAIT_F2RDY 3000
@@ -926,6 +927,12 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
case SDIO_DEVICE_ID_BROADCOM_4329:
f2_blksz = SDIO_4329_FUNC2_BLOCKSIZE;
break;
+ case SDIO_DEVICE_ID_BROADCOM_CYPRESS_89459:
+ case SDIO_DEVICE_ID_CYPRESS_54590:
+ case SDIO_DEVICE_ID_CYPRESS_54591:
+ case SDIO_DEVICE_ID_CYPRESS_54594:
+ f2_blksz = SDIO_89459_FUNC2_BLOCKSIZE;
+ break;
default:
break;
}
@@ -997,8 +1004,11 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_4373),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43012),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_43752),
- BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_89359),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_CYPRESS_89459),
CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_43439),
+ CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_54590),
+ CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_54591),
+ CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_54594),
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 95f3c7e2a100..cb1cc5b7bfab 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -65,6 +65,10 @@
#define CY_435X_F2_WATERMARK 0x40
#define CY_435X_F1_MESBUSYCTRL (CY_435X_F2_WATERMARK | \
SBSDIO_MESBUSYCTRL_ENAB)
+#define CY_89459_F2_WATERMARK 0x40
+#define CY_89459_MES_WATERMARK 0x40
+#define CY_89459_MESBUSYCTRL (CY_89459_MES_WATERMARK | \
+ SBSDIO_MESBUSYCTRL_ENAB)
#ifdef DEBUG
@@ -641,6 +645,7 @@ CY_FW_DEF(4359, "cyfmac4359-sdio");
CY_FW_DEF(4373, "cyfmac4373-sdio");
CY_FW_DEF(43012, "cyfmac43012-sdio");
BRCMF_FW_CLM_DEF(43752, "brcmfmac43752-sdio");
+CY_FW_DEF(89459, "cyfmac54591-sdio");
/* firmware config files */
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.txt");
@@ -673,7 +678,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(CY_CC_43439_CHIP_ID, 0xFFFFFFFF, 43439),
BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373),
BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012),
- BRCMF_FW_ENTRY(CY_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752)
+ BRCMF_FW_ENTRY(CY_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752),
+ BRCMF_FW_ENTRY(CY_CC_89459_CHIP_ID, 0xFFFFFFFF, 89459)
};
#define TXCTL_CREDITS 2
@@ -4599,6 +4605,22 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_MESBUSYCTRL,
CY_435X_F1_MESBUSYCTRL, &err);
break;
+ case SDIO_DEVICE_ID_BROADCOM_CYPRESS_89459:
+ case SDIO_DEVICE_ID_CYPRESS_54590:
+ case SDIO_DEVICE_ID_CYPRESS_54591:
+ case SDIO_DEVICE_ID_CYPRESS_54594:
+ brcmf_dbg(INFO, "set F2/MES watermark to 0x%x*4 / 0x%x bytes for 89459\n",
+ CY_89459_F2_WATERMARK, CY_89459_MESBUSYCTRL);
+ brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK,
+ CY_89459_F2_WATERMARK, &err);
+ devctl = brcmf_sdiod_readb(sdiod, SBSDIO_DEVICE_CTL,
+ &err);
+ devctl |= SBSDIO_DEVCTL_F2WM_ENAB;
+ brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl,
+ &err);
+ brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_MESBUSYCTRL,
+ CY_89459_MESBUSYCTRL, &err);
+ break;
default:
brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK,
DEFAULT_F2_WATERMARK, &err);
--
2.17.1

View File

@@ -0,0 +1,136 @@
From 0ef987e14c7451a3cd961cdc10ff305bf92d80c2 Mon Sep 17 00:00:00 2001
From: Prasanna Kerekoppa <prasanna.kerekoppa@infineon.com>
Date: Thu, 22 Jul 2021 18:01:32 -0500
Subject: [PATCH 089/179] brcmfmac: Fix AP interface delete issue
Fixes the ap interface delete issue. Fix is to make sure interface is created with supported version.
Patch has been verified by creating and deleting AP interface.
Signed-off-by: Prasanna Kerekoppa <prasanna.kerekoppa@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 101 ++++++++++++++++--
1 file changed, 90 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 5acc7fbfcee2..7388cbe609e2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -710,24 +710,103 @@ static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr)
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
{
+ struct wl_interface_create_v1 iface_v1;
+ struct wl_interface_create_v2 iface_v2;
+ struct wl_interface_create_v3 iface_v3;
+ u32 iface_create_ver;
struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_mbss_ssid_le mbss_ssid_le;
int bsscfgidx;
int err;
- memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
- bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
- if (bsscfgidx < 0)
- return bsscfgidx;
+ /* interface_create version 1 */
+ memset(&iface_v1, 0, sizeof(iface_v1));
+ iface_v1.ver = WL_INTERFACE_CREATE_VER_1;
+ iface_v1.flags = WL_INTERFACE_CREATE_AP |
+ WL_INTERFACE_MAC_USE;
- mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
- mbss_ssid_le.SSID_len = cpu_to_le32(5);
- sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
+ brcmf_set_vif_sta_macaddr(ifp, iface_v1.mac_addr);
- err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
- sizeof(mbss_ssid_le));
- if (err < 0)
- bphy_err(drvr, "setting ssid failed %d\n", err);
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
+ &iface_v1,
+ sizeof(iface_v1));
+ if (err) {
+ brcmf_info("failed to create interface(v1), err=%d\n",
+ err);
+ } else {
+ brcmf_dbg(INFO, "interface created(v1)\n");
+ return 0;
+ }
+
+ /* interface_create version 2 */
+ memset(&iface_v2, 0, sizeof(iface_v2));
+ iface_v2.ver = WL_INTERFACE_CREATE_VER_2;
+ iface_v2.flags = WL_INTERFACE_MAC_USE;
+ iface_v2.iftype = WL_INTERFACE_CREATE_AP;
+
+ brcmf_set_vif_sta_macaddr(ifp, iface_v2.mac_addr);
+
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
+ &iface_v2,
+ sizeof(iface_v2));
+ if (err) {
+ brcmf_info("failed to create interface(v2), err=%d\n",
+ err);
+ } else {
+ brcmf_dbg(INFO, "interface created(v2)\n");
+ return 0;
+ }
+
+ /* interface_create version 3+ */
+ /* get supported version from firmware side */
+ iface_create_ver = 0;
+ err = brcmf_fil_bsscfg_int_get(ifp, "interface_create",
+ &iface_create_ver);
+ if (err) {
+ brcmf_err("fail to get supported version, err=%d\n", err);
+ return -EOPNOTSUPP;
+ }
+
+ switch (iface_create_ver) {
+ case WL_INTERFACE_CREATE_VER_3:
+ memset(&iface_v3, 0, sizeof(iface_v3));
+ iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
+ iface_v3.flags = WL_INTERFACE_MAC_USE;
+ iface_v3.iftype = WL_INTERFACE_CREATE_AP;
+ brcmf_set_vif_sta_macaddr(ifp, iface_v3.mac_addr);
+
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
+ &iface_v3,
+ sizeof(iface_v3));
+
+ if (!err)
+ brcmf_dbg(INFO, "interface created(v3)\n");
+ break;
+ default:
+ brcmf_err("not support interface create(v%d)\n",
+ iface_create_ver);
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ if (err) {
+ brcmf_info("Does not support interface_create (%d)\n",
+ err);
+ memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
+ bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
+ if (bsscfgidx < 0)
+ return bsscfgidx;
+
+ mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
+ mbss_ssid_le.SSID_len = cpu_to_le32(5);
+ sprintf(mbss_ssid_le.SSID, "ssid%d", bsscfgidx);
+
+ err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
+ sizeof(mbss_ssid_le));
+
+ if (err < 0)
+ bphy_err(drvr, "setting ssid failed %d\n", err);
+ }
return err;
}
--
2.17.1

View File

@@ -0,0 +1,72 @@
From 3b95b79bb76c41d0b1b0cecefbc8fe87237e55e8 Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Fri, 6 Aug 2021 05:05:25 -0500
Subject: [PATCH 090/179] brcmfmac: Revise channel info for WPA3 external SAE
Revise the returned value of dcmd "BRCMF_C_GET_CHANNEL"
to get the hw_channel from firmware "channel_info" structure.
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 27 ++++++++++++-------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 7388cbe609e2..30cac551bae5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5512,6 +5512,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct brcmf_mf_params_le *mf_params;
u32 mf_params_len;
s32 timeout;
+ u32 hw_channel;
brcmf_dbg(TRACE, "Enter\n");
@@ -5572,13 +5573,16 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
/* Add the channel. Use the one specified as parameter if any or
* the current one (got from the firmware) otherwise
*/
- if (chan)
+ if (chan) {
freq = chan->center_freq;
- else
+ chan_nr = ieee80211_frequency_to_channel(freq);
+ af_params->channel = cpu_to_le32(chan_nr);
+ } else {
brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
- &freq);
- chan_nr = ieee80211_frequency_to_channel(freq);
- af_params->channel = cpu_to_le32(chan_nr);
+ &hw_channel);
+ af_params->channel = hw_channel;
+ }
+
af_params->dwell_time = cpu_to_le32(params->wait);
memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
le16_to_cpu(action_frame->len));
@@ -5611,13 +5615,16 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
mf_params->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
mf_params->frame_control = mgmt->frame_control;
- if (chan)
+ if (chan) {
freq = chan->center_freq;
- else
+ chan_nr = ieee80211_frequency_to_channel(freq);
+ mf_params->channel = cpu_to_le32(chan_nr);
+ } else {
brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
- &freq);
- chan_nr = ieee80211_frequency_to_channel(freq);
- mf_params->channel = cpu_to_le32(chan_nr);
+ &hw_channel);
+ mf_params->channel = hw_channel;
+ }
+
memcpy(&mf_params->da[0], &mgmt->da[0], ETH_ALEN);
memcpy(&mf_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
mf_params->packet_id = cpu_to_le32(*cookie);
--
2.17.1

View File

@@ -0,0 +1,30 @@
From 0fa8ea7bf78c193ad42b61fabb6edd97cbc07674 Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Mon, 9 Aug 2021 01:29:12 -0500
Subject: [PATCH 091/179] brcmfmac: Fix structure size for WPA3 external SAE
Add pmkid parameter in "brcmf_auth_req_status_le" structure to
align the buffer size defined in firmware "wl_auth_req_status"
structure.
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index afedb7627029..aa4450d3c824 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -562,6 +562,7 @@ struct brcmf_auth_req_status_le {
u8 peer_mac[ETH_ALEN];
__le32 ssid_len;
u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 pmkid[WLAN_PMKID_LEN];
};
/**
--
2.17.1

View File

@@ -0,0 +1,42 @@
From f6cfaf8c318129f6fbe9c578d46f2c36e4bd4f57 Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Tue, 17 Aug 2021 21:59:01 -0500
Subject: [PATCH 092/179] brcmfmac: support 54590/54594 PCIe device id
Add the device ids for 54590/54594 PCIe commercial product.
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 ++
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
2 files changed, 4 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 41c60b9bcd57..73605c51c4cc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -2591,6 +2591,8 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(CY_PCIE_89459_DEVICE_ID),
BRCMF_PCIE_DEVICE(CY_PCIE_89459_RAW_DEVICE_ID),
BRCMF_PCIE_DEVICE(CY_PCIE_54591_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(CY_PCIE_54590_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(CY_PCIE_54594_DEVICE_ID),
{ /* end: all zeroes */ }
};
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index 237925a13d38..9aff8cbf6fee 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -94,6 +94,8 @@
#define CY_PCIE_89459_DEVICE_ID 0x4415
#define CY_PCIE_89459_RAW_DEVICE_ID 0x4355
#define CY_PCIE_54591_DEVICE_ID 0x4417
+#define CY_PCIE_54590_DEVICE_ID 0x4416
+#define CY_PCIE_54594_DEVICE_ID 0x441a
/* brcmsmac IDs */
#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
--
2.17.1

View File

@@ -0,0 +1,104 @@
From 5fe1732c51facac10495ba5b8ea368a871053a25 Mon Sep 17 00:00:00 2001
From: Ian Lin <ian.lin-ee@infineon.com>
Date: Wed, 25 Aug 2021 23:19:24 -0500
Subject: [PATCH 093/179] Revert "non-upstream: make setting SDIO workqueue
WQ_HIGHPRI a module parameter"
This reverts commit 6e3e95205de5c5c84504efb2f5bb847fab2a0547.
Kernel.org do not accept to add parameter.
That fix is handle by new commit 41b637ba.
Signed-off-by: Ian Lin <ian.lin-ee@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/common.c | 5 -----
.../broadcom/brcm80211/brcmfmac/common.h | 2 --
.../broadcom/brcm80211/brcmfmac/sdio.c | 22 +++++++------------
3 files changed, 8 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 2825d6575dc1..32b67f20fb67 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -74,10 +74,6 @@ static int brcmf_eap_restrict;
module_param_named(eap_restrict, brcmf_eap_restrict, int, 0400);
MODULE_PARM_DESC(eap_restrict, "Block non-802.1X frames until auth finished");
-static int brcmf_sdio_wq_highpri;
-module_param_named(sdio_wq_highpri, brcmf_sdio_wq_highpri, int, 0);
-MODULE_PARM_DESC(sdio_wq_highpri, "SDIO workqueue is set to high priority");
-
static int brcmf_max_pm;
module_param_named(max_pm, brcmf_max_pm, int, 0);
MODULE_PARM_DESC(max_pm, "Use max power management mode by default");
@@ -485,7 +481,6 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
settings->roamoff = !!brcmf_roamoff;
settings->iapp = !!brcmf_iapp_enable;
settings->eap_restrict = !!brcmf_eap_restrict;
- settings->sdio_wq_highpri = !!brcmf_sdio_wq_highpri;
settings->default_pm = !!brcmf_max_pm ? PM_MAX : PM_FAST;
#ifdef DEBUG
settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index c0bf5867af5f..a86d23acd207 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -38,7 +38,6 @@ extern struct brcmf_mp_global_t brcmf_mp_global;
* @fcmode: FWS flow control.
* @roamoff: Firmware roaming off?
* @eap_restrict: Not allow data tx/rx until 802.1X auth succeeds
- * @sdio_wq_highpri: Tasks submitted to SDIO workqueue will run immediately.
* @default_pm: default power management (PM) mode.
* @ignore_probe_fail: Ignore probe failure.
* @country_codes: If available, pointer to struct for translating country codes
@@ -51,7 +50,6 @@ struct brcmf_mp_device {
bool roamoff;
bool iapp;
bool eap_restrict;
- bool sdio_wq_highpri;
int default_pm;
bool ignore_probe_fail;
struct brcmfmac_pd_cc *country_codes;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index cb1cc5b7bfab..b134a72e2f1f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4763,21 +4763,9 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
bus->txminmax = BRCMF_TXMINMAX;
bus->tx_seq = SDPCM_SEQ_WRAP - 1;
- /* attempt to attach to the dongle */
- if (!(brcmf_sdio_probe_attach(bus))) {
- brcmf_err("brcmf_sdio_probe_attach failed\n");
- goto fail;
- }
-
/* single-threaded workqueue */
- if (sdiodev->settings->sdio_wq_highpri) {
- wq = alloc_workqueue("brcmf_wq/%s",
- WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND,
- 1, dev_name(&sdiodev->func1->dev));
- } else {
- wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
- dev_name(&sdiodev->func1->dev));
- }
+ wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
+ dev_name(&sdiodev->func1->dev));
if (!wq) {
brcmf_err("insufficient memory to create txworkqueue\n");
goto fail;
@@ -4786,6 +4774,12 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
bus->brcmf_wq = wq;
+ /* attempt to attach to the dongle */
+ if (!(brcmf_sdio_probe_attach(bus))) {
+ brcmf_err("brcmf_sdio_probe_attach failed\n");
+ goto fail;
+ }
+
spin_lock_init(&bus->rxctl_lock);
spin_lock_init(&bus->txq_lock);
init_waitqueue_head(&bus->ctrl_wait);
--
2.17.1

View File

@@ -0,0 +1,48 @@
From 20768a08b77ba4ceaa6094a7bbca7973599b19dc Mon Sep 17 00:00:00 2001
From: Sean Anderson <sean.anderson@seco.com>
Date: Mon, 2 Aug 2021 13:09:04 -0400
Subject: [PATCH 094/179] brcmfmac: Set SDIO workqueue as WQ_HIGHPRI
commit 41b637bac0b0a90424793aa1ec265b24c4c50fb1 upstream.
This puts tasks submitted to the SDIO workqueue at the head of the queue
and runs them immediately. This gets higher RX throughput with the SDIO
bus.
This was originally submitted as [1]. The original author Wright Feng
reports
> throughput result with 43455(11ac) on 1 core 1.6 Ghz platform is
> Without WQ_HIGGPRI TX/RX: 293/301 (mbps)
> With WQ_HIGHPRI TX/RX: 293/321 (mbps)
I tested this with a 43364(11bgn) on a 1 core 800 MHz platform and got
Without WQ_HIGHPRI TX/RX: 16/19 (Mbits/sec)
With WQ_HIGHPRI TX/RX: 24/20 (MBits/sec)
[1] https://lore.kernel.org/linux-wireless/1584604406-15452-4-git-send-email-wright.feng@cypress.com/
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Reviewed-by: Arend van Spriel <aspriel@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210802170904.3116223-1-sean.anderson@seco.com
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index b134a72e2f1f..7e0aeb1434fd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4764,7 +4764,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
bus->tx_seq = SDPCM_SEQ_WRAP - 1;
/* single-threaded workqueue */
- wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
+ wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM | WQ_HIGHPRI,
dev_name(&sdiodev->func1->dev));
if (!wq) {
brcmf_err("insufficient memory to create txworkqueue\n");
--
2.17.1

View File

@@ -0,0 +1,53 @@
From 41ef0b69200e6656294c726ac8882b0d56d76ed9 Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Mon, 30 Aug 2021 04:14:35 -0500
Subject: [PATCH 095/179] brcmfmac: revise SoftAP channel setting
We need to update "chanspec" iovar for each SoftAP creation
because firmware will update the chanspec to current bsscfg
for each bss. If we do not update it then the wrong chanspec
will be shown on the result of 'wl -i [interface] status'
command. No need to handle channel resource reusing for mbss
mode by the host driver, it should be covered by firmware.
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 30cac551bae5..52b90c4b71b5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5185,17 +5185,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
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) {
- bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
- chanspec, err);
- goto exit;
- }
+
+ /* 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) {
+ bphy_err(drvr, "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) {
bphy_err(drvr, "BRCMF_C_UP error (%d)\n", err);
--
2.17.1

View File

@@ -0,0 +1,65 @@
From b7edf2ad70757a18706cb152763553cf98669627 Mon Sep 17 00:00:00 2001
From: Double Lo <Double.Lo@infineon.com>
Date: Tue, 4 May 2021 05:30:28 -0500
Subject: [PATCH 096/179] brcmfmac: Optimize CYW4373 SDIO current
Optimize the current by requesting HT_AVAIL clock instead of HT clock.
Signed-off-by: Double Lo <Double.Lo@infineon.com>
---
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 7e0aeb1434fd..da273eff93d2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -2540,6 +2540,14 @@ static bool brcmf_chip_is_ulp(struct brcmf_chip *ci)
return false;
}
+static bool brcmf_sdio_use_ht_avail(struct brcmf_chip *ci)
+{
+ if (ci->chip == CY_CC_4373_CHIP_ID)
+ return true;
+ else
+ return false;
+}
+
static void brcmf_sdio_bus_stop(struct device *dev)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -2576,7 +2584,8 @@ static void brcmf_sdio_bus_stop(struct device *dev)
&err);
if (!err) {
bpreq = saveclk;
- bpreq |= brcmf_chip_is_ulp(bus->ci) ?
+ bpreq |= (brcmf_sdio_use_ht_avail(bus->ci) ||
+ brcmf_chip_is_ulp(bus->ci)) ?
SBSDIO_HT_AVAIL_REQ : SBSDIO_FORCE_HT;
brcmf_sdiod_writeb(sdiodev,
SBSDIO_FUNC1_CHIPCLKCSR,
@@ -3707,7 +3716,8 @@ static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
brcmf_dbg(TRACE, "Enter\n");
- if (brcmf_chip_is_ulp(bus->ci)) {
+ if (brcmf_sdio_use_ht_avail(bus->ci) ||
+ brcmf_chip_is_ulp(bus->ci)) {
wakeupctrl = SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT;
chipclkcsr = SBSDIO_HT_AVAIL_REQ;
} else {
@@ -4510,7 +4520,8 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
saveclk = brcmf_sdiod_readb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, &err);
if (!err) {
bpreq = saveclk;
- bpreq |= brcmf_chip_is_ulp(bus->ci) ?
+ bpreq |= (brcmf_sdio_use_ht_avail(bus->ci) ||
+ brcmf_chip_is_ulp(bus->ci)) ?
SBSDIO_HT_AVAIL_REQ : SBSDIO_FORCE_HT;
brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR,
bpreq, &err);
--
2.17.1

View File

@@ -0,0 +1,45 @@
From bc427ef6fd49a05887bea580caeddd1bf4ab9b28 Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
Date: Wed, 22 Sep 2021 22:21:09 -0500
Subject: [PATCH 097/179] brcmfmac: use request_firmware_direct for loading
board-specific nvram
Loading a board-specific nvram file is optional. If the file is not
present, we will get a warning "Direct firmware load for ... failed with
error ...", have 60 seconds delay when
CONFIG_FW_LOADER_USER_HELPER_FALLBACK is enabled, and fall back to a
common one. However, users may treat this as a type of side effect and
the file is required.
Since it is optional, use request_firmware_direct() and leave an info
message in place to avoid the delay and confusion.
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index dcbe55b56e43..a9d122abf444 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -628,9 +628,12 @@ static int brcmf_fw_request_firmware(const struct firmware **fw,
if (!alt_path)
goto fallback;
- ret = request_firmware(fw, alt_path, fwctx->dev);
+ ret = request_firmware_direct(fw, alt_path, fwctx->dev);
kfree(alt_path);
- if (ret == 0)
+ if (ret)
+ brcmf_info("no board-specific nvram available (ret=%d), device will use %s\n",
+ ret, cur->path);
+ else
return ret;
}
--
2.17.1

View File

@@ -0,0 +1,44 @@
From 1fcaa9ff3d3819d83d5e63e34a3af79762e35efe Mon Sep 17 00:00:00 2001
From: Ting-Ying Li <tingying.li@cypress.com>
Date: Tue, 14 Sep 2021 04:33:27 -0500
Subject: [PATCH 098/179] brcmfmac: enable pmk catching for ext-sae wpa3 ap
Update pmkid in auth_status and enable
NL80211_EXT_FEATURE_AP_PMKSA_CACHING for ext-sae.
Signed-off-by: Ting-Ying Li <tingying.li@infineon.com>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 52b90c4b71b5..aea1d57ea218 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6052,6 +6052,9 @@ brcmf_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev,
auth_status.ssid_len = cpu_to_le32(min_t(u8, params->ssid.ssid_len,
IEEE80211_MAX_SSID_LEN));
memcpy(auth_status.ssid, params->ssid.ssid, auth_status.ssid_len);
+ memset(auth_status.pmkid, 0, WLAN_PMKID_LEN);
+ if (params->pmkid)
+ memcpy(auth_status.pmkid, params->pmkid, WLAN_PMKID_LEN);
ret = brcmf_fil_iovar_data_set(ifp, "auth_status", &auth_status,
sizeof(auth_status));
@@ -8003,8 +8006,12 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_SAE_OFFLOAD_AP);
}
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE_EXT))
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE_EXT)) {
wiphy->features |= NL80211_FEATURE_SAE;
+ wiphy_ext_feature_set(wiphy,
+ NL80211_EXT_FEATURE_AP_PMKSA_CACHING);
+ }
+
wiphy->mgmt_stypes = brcmf_txrx_stypes;
wiphy->max_remain_on_channel_duration = 5000;
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
--
2.17.1

View File

@@ -0,0 +1,29 @@
From 1b8b42f244aa1e829d338857d51a3c7a008fc826 Mon Sep 17 00:00:00 2001
From: Double Lo <Double.Lo@infineon.com>
Date: Fri, 8 Oct 2021 03:28:11 -0500
Subject: [PATCH 099/179] brcmfmac: fixes CYW4373 SDIO CMD53 error
Fixes CMD53 block write timeout issue with high throughput.
Signed-off-by: Double Lo <Double.Lo@infineon.com>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index dee4fa033179..48ff922a9989 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -44,7 +44,7 @@
#define SDIO_FUNC1_BLOCKSIZE 64
#define SDIO_FUNC2_BLOCKSIZE 512
-#define SDIO_4373_FUNC2_BLOCKSIZE 256
+#define SDIO_4373_FUNC2_BLOCKSIZE 128
#define SDIO_435X_FUNC2_BLOCKSIZE 256
#define SDIO_4329_FUNC2_BLOCKSIZE 128
#define SDIO_89459_FUNC2_BLOCKSIZE 256
--
2.17.1

View File

@@ -0,0 +1,206 @@
From cc9f70a9ed54bd4d32515c19eebda3f41af5ad8f Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Wed, 24 Oct 2018 03:46:25 -0500
Subject: [PATCH 100/179] brcmfmac: add PCIe mailbox support for core revision
64 or greater
The mailbox interrupt and mask registers have changed since PCIe2 core
rev 64. Add the corresponding support for new Broadcom/Cypress Wi-Fi
chips.
Signed-off-by: Wright Feng <wright.feng@infineon.com>
Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/pcie.c | 112 +++++++++++++-----
1 file changed, 82 insertions(+), 30 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 73605c51c4cc..de9788c68231 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -94,6 +94,9 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(CY_CC_89459_CHIP_ID, 0xFFFFFFFF, 4355),
};
+#define BRCMF_PCIE_REV_GE64(dev) (brcmf_chip_get_core((dev)->ci, \
+ BCMA_CORE_PCIE2)->rev >= 64)
+
#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
#define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024)
@@ -116,8 +119,10 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
#define BRCMF_PCIE_REG_LINK_STATUS_CTRL 0xBC
#define BRCMF_PCIE_PCIE2REG_INTMASK 0x24
-#define BRCMF_PCIE_PCIE2REG_MAILBOXINT 0x48
-#define BRCMF_PCIE_PCIE2REG_MAILBOXMASK 0x4C
+#define BRCMF_PCIE_PCIE2REG_MAILBOXINT(dev) (BRCMF_PCIE_REV_GE64(dev) ? \
+ 0xC30 : 0x48)
+#define BRCMF_PCIE_PCIE2REG_MAILBOXMASK(dev) (BRCMF_PCIE_REV_GE64(dev) ? \
+ 0xC34 : 0x4C)
#define BRCMF_PCIE_PCIE2REG_CONFIGADDR 0x120
#define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0 0x140
@@ -133,23 +138,60 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
#define BRCMF_PCIE_MB_INT_FN0_0 0x0100
#define BRCMF_PCIE_MB_INT_FN0_1 0x0200
-#define BRCMF_PCIE_MB_INT_D2H0_DB0 0x10000
-#define BRCMF_PCIE_MB_INT_D2H0_DB1 0x20000
-#define BRCMF_PCIE_MB_INT_D2H1_DB0 0x40000
-#define BRCMF_PCIE_MB_INT_D2H1_DB1 0x80000
-#define BRCMF_PCIE_MB_INT_D2H2_DB0 0x100000
-#define BRCMF_PCIE_MB_INT_D2H2_DB1 0x200000
-#define BRCMF_PCIE_MB_INT_D2H3_DB0 0x400000
-#define BRCMF_PCIE_MB_INT_D2H3_DB1 0x800000
-
-#define BRCMF_PCIE_MB_INT_D2H_DB (BRCMF_PCIE_MB_INT_D2H0_DB0 | \
- BRCMF_PCIE_MB_INT_D2H0_DB1 | \
- BRCMF_PCIE_MB_INT_D2H1_DB0 | \
- BRCMF_PCIE_MB_INT_D2H1_DB1 | \
- BRCMF_PCIE_MB_INT_D2H2_DB0 | \
- BRCMF_PCIE_MB_INT_D2H2_DB1 | \
- BRCMF_PCIE_MB_INT_D2H3_DB0 | \
- BRCMF_PCIE_MB_INT_D2H3_DB1)
+#define BRCMF_PCIE_MB_INT_D2H0_DB0 0x10000
+#define BRCMF_PCIE_MB_INT_D2H0_DB1 0x20000
+#define BRCMF_PCIE_MB_INT_D2H1_DB0 0x40000
+#define BRCMF_PCIE_MB_INT_D2H1_DB1 0x80000
+#define BRCMF_PCIE_MB_INT_D2H2_DB0 0x100000
+#define BRCMF_PCIE_MB_INT_D2H2_DB1 0x200000
+#define BRCMF_PCIE_MB_INT_D2H3_DB0 0x400000
+#define BRCMF_PCIE_MB_INT_D2H3_DB1 0x800000
+#define BRCMF_PCIE_MB_INT_D2H_DB_ALL (BRCMF_PCIE_MB_INT_D2H0_DB0 | \
+ BRCMF_PCIE_MB_INT_D2H0_DB1 | \
+ BRCMF_PCIE_MB_INT_D2H1_DB0 | \
+ BRCMF_PCIE_MB_INT_D2H1_DB1 | \
+ BRCMF_PCIE_MB_INT_D2H2_DB0 | \
+ BRCMF_PCIE_MB_INT_D2H2_DB1 | \
+ BRCMF_PCIE_MB_INT_D2H3_DB0 | \
+ BRCMF_PCIE_MB_INT_D2H3_DB1)
+
+#define BRCMF_PCIE_MB_INT_D2H0_DB0_GE64 0x0001
+#define BRCMF_PCIE_MB_INT_D2H0_DB1_GE64 0x0002
+#define BRCMF_PCIE_MB_INT_D2H1_DB0_GE64 0x0004
+#define BRCMF_PCIE_MB_INT_D2H1_DB1_GE64 0x0008
+#define BRCMF_PCIE_MB_INT_D2H2_DB0_GE64 0x0010
+#define BRCMF_PCIE_MB_INT_D2H2_DB1_GE64 0x0020
+#define BRCMF_PCIE_MB_INT_D2H3_DB0_GE64 0x0040
+#define BRCMF_PCIE_MB_INT_D2H3_DB1_GE64 0x0080
+#define BRCMF_PCIE_MB_INT_D2H4_DB0_GE64 0x0100
+#define BRCMF_PCIE_MB_INT_D2H4_DB1_GE64 0x0200
+#define BRCMF_PCIE_MB_INT_D2H5_DB0_GE64 0x0400
+#define BRCMF_PCIE_MB_INT_D2H5_DB1_GE64 0x0800
+#define BRCMF_PCIE_MB_INT_D2H6_DB0_GE64 0x1000
+#define BRCMF_PCIE_MB_INT_D2H6_DB1_GE64 0x2000
+#define BRCMF_PCIE_MB_INT_D2H7_DB0_GE64 0x4000
+#define BRCMF_PCIE_MB_INT_D2H7_DB1_GE64 0x8000
+#define BRCMF_PCIE_MB_INT_D2H_DB_ALL_GE64 \
+ (BRCMF_PCIE_MB_INT_D2H0_DB0_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H0_DB1_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H1_DB0_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H1_DB1_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H2_DB0_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H2_DB1_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H3_DB0_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H3_DB1_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H4_DB0_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H4_DB1_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H5_DB0_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H5_DB1_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H6_DB0_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H6_DB1_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H7_DB0_GE64 | \
+ BRCMF_PCIE_MB_INT_D2H7_DB1_GE64)
+
+#define BRCMF_PCIE_MB_INT_D2H_DB(dev) (BRCMF_PCIE_REV_GE64(dev) ? \
+ BRCMF_PCIE_MB_INT_D2H_DB_ALL_GE64 : \
+ BRCMF_PCIE_MB_INT_D2H_DB_ALL)
#define BRCMF_PCIE_SHARED_VERSION_6 6
#define BRCMF_PCIE_SHARED_VERSION_7 7
@@ -1073,14 +1115,16 @@ static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo,
static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo)
{
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, 0);
+ brcmf_pcie_write_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXMASK(devinfo), 0);
}
static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo)
{
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
- BRCMF_PCIE_MB_INT_D2H_DB |
+ brcmf_pcie_write_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXMASK(devinfo),
+ BRCMF_PCIE_MB_INT_D2H_DB(devinfo) |
BRCMF_PCIE_MB_INT_FN0_0 |
BRCMF_PCIE_MB_INT_FN0_1);
}
@@ -1096,7 +1140,8 @@ static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg)
{
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)) {
+ if (brcmf_pcie_read_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXINT(devinfo))) {
brcmf_pcie_intr_disable(devinfo);
brcmf_dbg(PCIE, "Enter\n");
return IRQ_WAKE_THREAD;
@@ -1114,10 +1159,12 @@ static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
devinfo->in_irq = true;
- status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
+ status = brcmf_pcie_read_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXINT(devinfo));
brcmf_dbg(PCIE, "Enter %x\n", status);
if (status) {
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
+ brcmf_pcie_write_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXINT(devinfo),
status);
if (status & (BRCMF_PCIE_MB_INT_FN0_0 |
BRCMF_PCIE_MB_INT_FN0_1)) {
@@ -1125,7 +1172,7 @@ static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
brcmf_pcie_handle_mb_data(bus, d2h_mbdata);
}
- if (status & BRCMF_PCIE_MB_INT_D2H_DB) {
+ if (status & BRCMF_PCIE_MB_INT_D2H_DB(devinfo)) {
if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
brcmf_proto_msgbuf_rx_trigger(
&devinfo->pdev->dev);
@@ -1184,8 +1231,11 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
if (devinfo->in_irq)
brcmf_err(bus, "Still in IRQ (processing) !!!\n");
- status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status);
+ status = brcmf_pcie_read_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXINT(devinfo));
+ brcmf_pcie_write_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXINT(devinfo),
+ status);
devinfo->irq_allocated = false;
}
@@ -2049,9 +2099,11 @@ static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip)
devinfo->ci = chip;
brcmf_pcie_reset_device(devinfo);
- val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
+ val = brcmf_pcie_read_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXINT(devinfo));
if (val != 0xffffffff)
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
+ brcmf_pcie_write_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXINT(devinfo),
val);
return 0;
--
2.17.1

Some files were not shown because too many files have changed in this diff Show More