diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0001-non-upstream-add-sg-parameters-dts-parsing.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0001-non-upstream-add-sg-parameters-dts-parsing.patch new file mode 100644 index 000000000..cbba1ec03 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0001-non-upstream-add-sg-parameters-dts-parsing.patch @@ -0,0 +1,52 @@ +From 520405c6e198c757510573cad2965d982eb34de6 Mon Sep 17 00:00:00 2001 +From: Chi-Hsien Lin +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0002-brcmfmac-support-AP-isolation.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0002-brcmfmac-support-AP-isolation.patch new file mode 100644 index 000000000..7abfa4985 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0002-brcmfmac-support-AP-isolation.patch @@ -0,0 +1,58 @@ +From b29a8e3605a59e239a160580e0478cef9117b05d Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0003-non-upstream-make-firmware-eap_restrict-a-module-par.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0003-non-upstream-make-firmware-eap_restrict-a-module-par.patch new file mode 100644 index 000000000..c9dcfaf0f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0003-non-upstream-make-firmware-eap_restrict-a-module-par.patch @@ -0,0 +1,93 @@ +From 0c9dac2b21c1b225cbc625534617a27cf6f6a25a Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0004-non-upstream-support-wake-on-ping-packet.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0004-non-upstream-support-wake-on-ping-packet.patch new file mode 100644 index 000000000..02d8dbc00 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0004-non-upstream-support-wake-on-ping-packet.patch @@ -0,0 +1,431 @@ +From a3440f3441e9e60e289f87525ecf7d3e61044ebf Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +Signed-off-by: Double Lo +Signed-off-by: Chi-hsien Lin +--- + .../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 + #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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0005-non-upstream-remove-WOWL-configuration-in-disconnect.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0005-non-upstream-remove-WOWL-configuration-in-disconnect.patch new file mode 100644 index 000000000..aa6d1af6f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0005-non-upstream-remove-WOWL-configuration-in-disconnect.patch @@ -0,0 +1,32 @@ +From db294a675780b6ff7d27e3e9b836fc0c05012e83 Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0006-non-upstream-make-setting-SDIO-workqueue-WQ_HIGHPRI-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0006-non-upstream-make-setting-SDIO-workqueue-WQ_HIGHPRI-.patch new file mode 100644 index 000000000..e032363a6 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0006-non-upstream-make-setting-SDIO-workqueue-WQ_HIGHPRI-.patch @@ -0,0 +1,105 @@ +From 120f714bc5e261a6e7da2a319321f7ff08fcfae2 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0007-non-upstream-avoid-network-disconnection-during-susp.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0007-non-upstream-avoid-network-disconnection-during-susp.patch new file mode 100644 index 000000000..7615c3669 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0007-non-upstream-avoid-network-disconnection-during-susp.patch @@ -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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0008-non-upstream-Changes-to-improve-USB-Tx-throughput.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0008-non-upstream-Changes-to-improve-USB-Tx-throughput.patch new file mode 100644 index 000000000..7a6a36bc3 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0008-non-upstream-Changes-to-improve-USB-Tx-throughput.patch @@ -0,0 +1,34 @@ +From 671bc68ac0d6d1e97bb0838746632e0ecefa2205 Mon Sep 17 00:00:00 2001 +From: Raveendran Somu +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0009-brcmfmac-introduce-module-parameter-to-configure-def.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0009-brcmfmac-introduce-module-parameter-to-configure-def.patch new file mode 100644 index 000000000..1e674a877 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0009-brcmfmac-introduce-module-parameter-to-configure-def.patch @@ -0,0 +1,93 @@ +From 03f45fcc1fb766a2193415a203695802eb3c8796 Mon Sep 17 00:00:00 2001 +From: Chi-Hsien Lin +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 +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0010-non-upstream-configure-wowl-parameters-in-suspend-fu.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0010-non-upstream-configure-wowl-parameters-in-suspend-fu.patch new file mode 100644 index 000000000..5d0e7b4da --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0010-non-upstream-configure-wowl-parameters-in-suspend-fu.patch @@ -0,0 +1,34 @@ +From 12405072670b9c03cebe7f84ac9c88aac4cdbee1 Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0011-non-upstream-disable-command-decode-in-sdio_aos-for-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0011-non-upstream-disable-command-decode-in-sdio_aos-for-.patch new file mode 100644 index 000000000..89cd591f0 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0011-non-upstream-disable-command-decode-in-sdio_aos-for-.patch @@ -0,0 +1,39 @@ +From be124487a2a863febd90c34af548c349a849017f Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0012-brcmfmac-increase-default-max-WOWL-patterns-to-16.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0012-brcmfmac-increase-default-max-WOWL-patterns-to-16.patch new file mode 100644 index 000000000..eaea973a0 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0012-brcmfmac-increase-default-max-WOWL-patterns-to-16.patch @@ -0,0 +1,29 @@ +From 51292423ac0230e75ed6fa2691b7dfed72f7e6a6 Mon Sep 17 00:00:00 2001 +From: Ryohei Kondo +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0013-non-upstream-Enable-Process-and-forward-PHY_TEMP-eve.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0013-non-upstream-Enable-Process-and-forward-PHY_TEMP-eve.patch new file mode 100644 index 000000000..66ff65dd2 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0013-non-upstream-Enable-Process-and-forward-PHY_TEMP-eve.patch @@ -0,0 +1,180 @@ +From 806187583bf02d23b736b2440c71ab559a0264a4 Mon Sep 17 00:00:00 2001 +From: Robert Trask +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0014-non-upstream-fix-continuous-802.1x-tx-pending-timeou.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0014-non-upstream-fix-continuous-802.1x-tx-pending-timeou.patch new file mode 100644 index 000000000..b17e70614 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0014-non-upstream-fix-continuous-802.1x-tx-pending-timeou.patch @@ -0,0 +1,90 @@ +From e93069267e235b26c023fbbc09218329e28ff382 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0015-non-upstream-add-sleep-in-bus-suspend-and-cfg80211-r.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0015-non-upstream-add-sleep-in-bus-suspend-and-cfg80211-r.patch new file mode 100644 index 000000000..d191116fe --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0015-non-upstream-add-sleep-in-bus-suspend-and-cfg80211-r.patch @@ -0,0 +1,262 @@ +From cac47a7fb2ced35fd58ff3854a7559caf38aa434 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0016-brcmfmac-add-CYW43570-PCIE-device.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0016-brcmfmac-add-CYW43570-PCIE-device.patch new file mode 100644 index 000000000..f4134da29 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0016-brcmfmac-add-CYW43570-PCIE-device.patch @@ -0,0 +1,42 @@ +From b28085ad33e1a80db199e54b523f843fc5b5a822 Mon Sep 17 00:00:00 2001 +From: Soontak Lee +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 +Signed-off-by: Chi-Hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0017-non-upstream-fix-scheduling-while-atomic-issue-when-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0017-non-upstream-fix-scheduling-while-atomic-issue-when-.patch new file mode 100644 index 000000000..63bbac97e --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0017-non-upstream-fix-scheduling-while-atomic-issue-when-.patch @@ -0,0 +1,80 @@ +From 3d94471b71ece64a341b9a4b8b7b10c96699a982 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-Hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0018-brcmfmac-Support-89459-pcie.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0018-brcmfmac-Support-89459-pcie.patch new file mode 100644 index 000000000..61b9bee2d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0018-brcmfmac-Support-89459-pcie.patch @@ -0,0 +1,91 @@ +From 2a695534367cad12511f74f665a347cb410af9aa Mon Sep 17 00:00:00 2001 +From: "alep@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 +Signed-off-by: Joseph chuang +Signed-off-by: Chi-Hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0019-brcmfmac-Support-multiple-AP-interfaces-and-fix-STA-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0019-brcmfmac-Support-multiple-AP-interfaces-and-fix-STA-.patch new file mode 100644 index 000000000..65609b43a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0019-brcmfmac-Support-multiple-AP-interfaces-and-fix-STA-.patch @@ -0,0 +1,143 @@ +From 7a3070f758e4b4c8bbea195c7ba2eef1b3a816df Mon Sep 17 00:00:00 2001 +From: Soontak Lee +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 +Signed-off-by: Chi-Hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0020-non-upstream-Support-custom-PCIE-BAR-window-size.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0020-non-upstream-Support-custom-PCIE-BAR-window-size.patch new file mode 100644 index 000000000..cce308fc9 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0020-non-upstream-Support-custom-PCIE-BAR-window-size.patch @@ -0,0 +1,465 @@ +From f96ddedb3ec68bb591db842dfeffca698a5f2eba Mon Sep 17 00:00:00 2001 +From: Soontak Lee +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 +Signed-off-by: Chi-Hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0021-brcmfmac-support-for-virtual-interface-creation-from.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0021-brcmfmac-support-for-virtual-interface-creation-from.patch new file mode 100644 index 000000000..97405525c --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0021-brcmfmac-support-for-virtual-interface-creation-from.patch @@ -0,0 +1,104 @@ +From da21f93450c9ece85bed6eac4df041756d786cc1 Mon Sep 17 00:00:00 2001 +From: "Lo(Double)Hsiang Lo" +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 +Signed-off-by: Chi-Hsien Lin +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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0022-brcmfmac-increase-dcmd-maximum-buffer-size.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0022-brcmfmac-increase-dcmd-maximum-buffer-size.patch new file mode 100644 index 000000000..35f404991 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0022-brcmfmac-increase-dcmd-maximum-buffer-size.patch @@ -0,0 +1,40 @@ +From 67a30ebf25d750d9b58c876928a828fe17c3fd53 Mon Sep 17 00:00:00 2001 +From: "Lo(Double)Hsiang Lo" +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 +Signed-off-by: Chi-Hsien Lin +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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0023-brcmfmac-set-net-carrier-on-via-test-tool-for-AP-mod.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0023-brcmfmac-set-net-carrier-on-via-test-tool-for-AP-mod.patch new file mode 100644 index 000000000..12df029bc --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0023-brcmfmac-set-net-carrier-on-via-test-tool-for-AP-mod.patch @@ -0,0 +1,39 @@ +From 8bb3f53dd00b7d2f2d443a751f7af60ceae18ae5 Mon Sep 17 00:00:00 2001 +From: Kurt Lee/TAIPEI +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 +Signed-off-by: Chi-Hsien Lin +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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0024-nl80211-add-authorized-flag-back-to-ROAM-event.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0024-nl80211-add-authorized-flag-back-to-ROAM-event.patch new file mode 100644 index 000000000..c8be3be91 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0024-nl80211-add-authorized-flag-back-to-ROAM-event.patch @@ -0,0 +1,93 @@ +From 1bc5a46ef669755e9437abd6bf9e1e8213cdbd15 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0025-brcmfmac-set-authorized-flag-in-ROAM-event-for-offlo.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0025-brcmfmac-set-authorized-flag-in-ROAM-event-for-offlo.patch new file mode 100644 index 000000000..ddba60b6d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0025-brcmfmac-set-authorized-flag-in-ROAM-event-for-offlo.patch @@ -0,0 +1,48 @@ +From 22596bdaa5055c5637a8e738f0d613f8072b25fd Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0026-brcmfmac-set-authorized-flag-in-ROAM-event-for-PMK-c.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0026-brcmfmac-set-authorized-flag-in-ROAM-event-for-PMK-c.patch new file mode 100644 index 000000000..6e91a27cb --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0026-brcmfmac-set-authorized-flag-in-ROAM-event-for-PMK-c.patch @@ -0,0 +1,83 @@ +From 2b58c732ab3d125c6f15d235aea37e9a3a4c9707 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0027-nl80211-add-authorized-flag-to-CONNECT-event.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0027-nl80211-add-authorized-flag-to-CONNECT-event.patch new file mode 100644 index 000000000..b2aad4ee9 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0027-nl80211-add-authorized-flag-to-CONNECT-event.patch @@ -0,0 +1,65 @@ +From 4d5061baaed43b218abff4cb6601c67c9f334ac7 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0028-brcmfmac-set-authorized-flag-in-CONNECT-event-for-PM.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0028-brcmfmac-set-authorized-flag-in-CONNECT-event-for-PM.patch new file mode 100644 index 000000000..f73594e90 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0028-brcmfmac-set-authorized-flag-in-CONNECT-event-for-PM.patch @@ -0,0 +1,36 @@ +From 3133cf33a6b350fe50f65759d364b865352975ed Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0029-brcmfmac-add-support-for-Opportunistic-Key-Caching.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0029-brcmfmac-add-support-for-Opportunistic-Key-Caching.patch new file mode 100644 index 000000000..89e0d1553 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0029-brcmfmac-add-support-for-Opportunistic-Key-Caching.patch @@ -0,0 +1,108 @@ +From d0771ea001c37e2b4a3c490b0b93cfcdb8802646 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0030-brcmfmac-To-support-printing-USB-console-messages.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0030-brcmfmac-To-support-printing-USB-console-messages.patch new file mode 100644 index 000000000..9c600d7ee --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0030-brcmfmac-To-support-printing-USB-console-messages.patch @@ -0,0 +1,241 @@ +From 6b4c0c369438ca0dac0c68611f69d84984c9f704 Mon Sep 17 00:00:00 2001 +From: Raveendran Somu +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0031-non-upstream-Fix-no-P2P-IE-in-probe-requests-issue.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0031-non-upstream-Fix-no-P2P-IE-in-probe-requests-issue.patch new file mode 100644 index 000000000..7d373c99b --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0031-non-upstream-Fix-no-P2P-IE-in-probe-requests-issue.patch @@ -0,0 +1,61 @@ +From 4aa36126c355bcae29e168f583546bc65057d065 Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0032-brcmfmac-add-54591-PCIE-device.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0032-brcmfmac-add-54591-PCIE-device.patch new file mode 100644 index 000000000..db500db87 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0032-brcmfmac-add-54591-PCIE-device.patch @@ -0,0 +1,104 @@ +From c645a63417f552da7d1148a8677a1ed3a266bc91 Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0033-non-upstream-support-DS1-exit-firmware-re-download.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0033-non-upstream-support-DS1-exit-firmware-re-download.patch new file mode 100644 index 000000000..ddecf377f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0033-non-upstream-support-DS1-exit-firmware-re-download.patch @@ -0,0 +1,737 @@ +From 51033313d8c04180fd7260d95a9d61d7eadd5f52 Mon Sep 17 00:00:00 2001 +From: Praveen Babu C +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 +Signed-off-by: Naveen Gupta +[Merge from 4.14.77 to 5.4.18; set BRCMF_SDIO_MAX_ACCESS_ERRORS to 20] +Signed-off-by: Chi-hsien Lin +--- + .../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 + + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0034-non-upstream-fix-43012-insmod-after-rmmod-in-DS1-fai.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0034-non-upstream-fix-43012-insmod-after-rmmod-in-DS1-fai.patch new file mode 100644 index 000000000..7850f37c8 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0034-non-upstream-fix-43012-insmod-after-rmmod-in-DS1-fai.patch @@ -0,0 +1,455 @@ +From dee67966f2eda27fa16f3e991b402a511c1845ed Mon Sep 17 00:00:00 2001 +From: Nitin Bhaskar +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 +[Merge from 4.14.77 to 5.4.18] +Signed-off-by: Chi-hsien Lin +--- + .../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 + + #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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0035-non-upstream-fix-43012-driver-reload-failure-after-D.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0035-non-upstream-fix-43012-driver-reload-failure-after-D.patch new file mode 100644 index 000000000..bbfc65afb --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0035-non-upstream-fix-43012-driver-reload-failure-after-D.patch @@ -0,0 +1,69 @@ +From 5ee68395559714baa2229415fc7cc9cdede072e3 Mon Sep 17 00:00:00 2001 +From: David Weng +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 +[Merge from 4.14.77 to 5.4.18] +Signed-off-by: Chi-hsien Lin +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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0036-brcmfmac-reset-PMU-backplane-all-cores-in-CYW4373-du.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0036-brcmfmac-reset-PMU-backplane-all-cores-in-CYW4373-du.patch new file mode 100644 index 000000000..971d05791 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0036-brcmfmac-reset-PMU-backplane-all-cores-in-CYW4373-du.patch @@ -0,0 +1,60 @@ +From 5760bb605b430b71beb78a128cd1addca751c06e Mon Sep 17 00:00:00 2001 +From: Madhan Mohan R +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0037-non-upstream-calling-skb_orphan-before-sending-skb-t.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0037-non-upstream-calling-skb_orphan-before-sending-skb-t.patch new file mode 100644 index 000000000..1c7af2a01 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0037-non-upstream-calling-skb_orphan-before-sending-skb-t.patch @@ -0,0 +1,51 @@ +From d66c93b44fb5fba3db4c6d342233c79aed774fd4 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + #include + #include + #include +@@ -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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0038-non-upstream-workaround-for-4373-USB-WMM-5.2.27-test.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0038-non-upstream-workaround-for-4373-USB-WMM-5.2.27-test.patch new file mode 100644 index 000000000..492830f79 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0038-non-upstream-workaround-for-4373-USB-WMM-5.2.27-test.patch @@ -0,0 +1,158 @@ +From e5ed9db2bf5a899639039f015869b89419855d79 Mon Sep 17 00:00:00 2001 +From: Madhan Mohan R +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 +Signed-off-by: Wright Feng +Signed-off-by: Chi-hsien Lin +--- + .../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 + + /* 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0039-non-upstream-disable-command-decode-in-sdio_aos-for-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0039-non-upstream-disable-command-decode-in-sdio_aos-for-.patch new file mode 100644 index 000000000..c583dc770 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0039-non-upstream-disable-command-decode-in-sdio_aos-for-.patch @@ -0,0 +1,35 @@ +From db1bccb569b0a01567410d2d39d8a3cd9da2cd7c Mon Sep 17 00:00:00 2001 +From: Chi-Hsien Lin +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 +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0040-non-upstream-disable-command-decode-in-sdio_aos-for-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0040-non-upstream-disable-command-decode-in-sdio_aos-for-.patch new file mode 100644 index 000000000..f728496c0 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0040-non-upstream-disable-command-decode-in-sdio_aos-for-.patch @@ -0,0 +1,36 @@ +From 439e863b9433cc6f98c32d9159f04cd86a163224 Mon Sep 17 00:00:00 2001 +From: Chi-Hsien Lin +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0041-non-upstream-disable-command-decode-in-sdio_aos-for-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0041-non-upstream-disable-command-decode-in-sdio_aos-for-.patch new file mode 100644 index 000000000..0c3a7398f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0041-non-upstream-disable-command-decode-in-sdio_aos-for-.patch @@ -0,0 +1,36 @@ +From c7935ce4be334d9d4ca2766c1a38058e3d85d12a Mon Sep 17 00:00:00 2001 +From: Chi-Hsien Lin +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0042-brcmfmac-support-the-forwarding-packet.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0042-brcmfmac-support-the-forwarding-packet.patch new file mode 100644 index 000000000..237ff592a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0042-brcmfmac-support-the-forwarding-packet.patch @@ -0,0 +1,280 @@ +From 35180cab0299505ae12d8d377b6ef84e4fbe9dde Mon Sep 17 00:00:00 2001 +From: Jia-Shyr Chuang +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 +Signed-off-by: Ting-Ying Li +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0043-brcmfmac-add-a-variable-for-packet-forwarding-condit.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0043-brcmfmac-add-a-variable-for-packet-forwarding-condit.patch new file mode 100644 index 000000000..585beadef --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0043-brcmfmac-add-a-variable-for-packet-forwarding-condit.patch @@ -0,0 +1,80 @@ +From 6e02bc9d174e9212bd16a4f202c04a79e1e04e1a Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0044-brcmfmac-don-t-allow-arp-nd-offload-to-be-enabled-if.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0044-brcmfmac-don-t-allow-arp-nd-offload-to-be-enabled-if.patch new file mode 100644 index 000000000..2aeeb32db --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0044-brcmfmac-don-t-allow-arp-nd-offload-to-be-enabled-if.patch @@ -0,0 +1,84 @@ +From 52ad7ed2ac1a591bc370574f13d2c7955ea22a53 Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0045-non-upstream-ignore-FW-BADARG-error-when-removing-no.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0045-non-upstream-ignore-FW-BADARG-error-when-removing-no.patch new file mode 100644 index 000000000..55ee9fecf --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0045-non-upstream-ignore-FW-BADARG-error-when-removing-no.patch @@ -0,0 +1,49 @@ +From 2c09290d3db101e44d00a2ece31769aa8aa47eef Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0046-brcmfmac-Support-DPP-feature.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0046-brcmfmac-Support-DPP-feature.patch new file mode 100644 index 000000000..9313fcdce --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0046-brcmfmac-Support-DPP-feature.patch @@ -0,0 +1,359 @@ +From 657ccada6d16171aa5af30f7afd24deb2358a6fb Mon Sep 17 00:00:00 2001 +From: Kurt Lee +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0047-brcmfmac-move-firmware-path-to-cypress-folder.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0047-brcmfmac-move-firmware-path-to-cypress-folder.patch new file mode 100644 index 000000000..3e1b2d36b --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0047-brcmfmac-move-firmware-path-to-cypress-folder.patch @@ -0,0 +1,123 @@ +From 32df9a3f4ba1286602e297d40239818c1d293a50 Mon Sep 17 00:00:00 2001 +From: Double Lo +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-.bin/clm_blob/txt. + + +Signed-off-by: Double Lo +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0048-brcmfmac-add-support-for-sof-time-stammping-for-tx-p.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0048-brcmfmac-add-support-for-sof-time-stammping-for-tx-p.patch new file mode 100644 index 000000000..18ccea50e --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0048-brcmfmac-add-support-for-sof-time-stammping-for-tx-p.patch @@ -0,0 +1,81 @@ +From baaf9e70927f4e9839f5ead1e3dacb4c70bd1123 Mon Sep 17 00:00:00 2001 +From: Brian Henriquez +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 +--- + 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 + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0049-non-upstream-free-eventmask_msg-after-updating-event.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0049-non-upstream-free-eventmask_msg-after-updating-event.patch new file mode 100644 index 000000000..49db54091 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0049-non-upstream-free-eventmask_msg-after-updating-event.patch @@ -0,0 +1,50 @@ +From fb35041f347a1a96d573c121a10fcbae53b27f94 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 + [] 0xffffffff + +Signed-off-by: Wright Feng + +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0050-brcmfmac-fix-invalid-address-access-when-enabling-SC.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0050-brcmfmac-fix-invalid-address-access-when-enabling-SC.patch new file mode 100644 index 000000000..bd77536f6 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0050-brcmfmac-fix-invalid-address-access-when-enabling-SC.patch @@ -0,0 +1,98 @@ +From 5518040dff6a3287b8d5ac6b1d2707c2a86aeddf Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0051-brcmfmac-add-a-timer-to-read-console-periodically-in.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0051-brcmfmac-add-a-timer-to-read-console-periodically-in.patch new file mode 100644 index 000000000..a84cec0e3 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0051-brcmfmac-add-a-timer-to-read-console-periodically-in.patch @@ -0,0 +1,260 @@ +From 33cb664bde0b2ef35384720bcd3e018d98175d37 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + #include + #include ++#include ++#include + #include + + #include +@@ -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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0052-brcmfmac-return-error-when-getting-invalid-max_flowr.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0052-brcmfmac-return-error-when-getting-invalid-max_flowr.patch new file mode 100644 index 000000000..5bfa5a744 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0052-brcmfmac-return-error-when-getting-invalid-max_flowr.patch @@ -0,0 +1,36 @@ +From 54d419f1a1e74a5bfc1c9e91e9530dc03fbcd3ce Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0053-brcmfmac-Fix-to-add-skb-free-for-TIM-update-info-whe.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0053-brcmfmac-Fix-to-add-skb-free-for-TIM-update-info-whe.patch new file mode 100644 index 000000000..a7066883f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0053-brcmfmac-Fix-to-add-skb-free-for-TIM-update-info-whe.patch @@ -0,0 +1,83 @@ +From 34963d006498b5150e690a05127b2046edf2d02a Mon Sep 17 00:00:00 2001 +From: Wataru Gohda +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0054-brcmfmac-Fix-to-add-brcmf_clear_assoc_ies-when-rmmod.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0054-brcmfmac-Fix-to-add-brcmf_clear_assoc_ies-when-rmmod.patch new file mode 100644 index 000000000..1a6716f18 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0054-brcmfmac-Fix-to-add-brcmf_clear_assoc_ies-when-rmmod.patch @@ -0,0 +1,31 @@ +From cf0bf201b785121551405ff1d69e12cd7156a006 Mon Sep 17 00:00:00 2001 +From: Wataru Gohda +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0055-brcmfmac-dump-dongle-memory-when-attaching-failed.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0055-brcmfmac-dump-dongle-memory-when-attaching-failed.patch new file mode 100644 index 000000000..2768f93bd --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0055-brcmfmac-dump-dongle-memory-when-attaching-failed.patch @@ -0,0 +1,65 @@ +From 1b38a1cfc7823ec98ea9c95d604429b6c002823c Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0056-brcmfmac-update-address-mode-via-test-tool-for-AP-mo.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0056-brcmfmac-update-address-mode-via-test-tool-for-AP-mo.patch new file mode 100644 index 000000000..f4e864072 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0056-brcmfmac-update-address-mode-via-test-tool-for-AP-mo.patch @@ -0,0 +1,60 @@ +From fa62ff729a94c8527db2cbf21e51b21a3106ab75 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0057-brcmfmac-load-54591-firmware-for-chip-ID-0x4355.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0057-brcmfmac-load-54591-firmware-for-chip-ID-0x4355.patch new file mode 100644 index 000000000..8d53459c5 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0057-brcmfmac-load-54591-firmware-for-chip-ID-0x4355.patch @@ -0,0 +1,88 @@ +From 29810edb2edff2e95a9011f76d8b8a165f6a7db4 Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0058-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0058-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch new file mode 100644 index 000000000..051e6ea48 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0058-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch @@ -0,0 +1,137 @@ +From c9c1f37c5acd7fd3e214fe402886ec4410dae1ce Mon Sep 17 00:00:00 2001 +From: Kurt Lee +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 +Signed-off-by: Double Lo +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0059-brcmfmac-fix-SDIO-bus-errors-during-high-temp-tests.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0059-brcmfmac-fix-SDIO-bus-errors-during-high-temp-tests.patch new file mode 100644 index 000000000..8cce4a5a1 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0059-brcmfmac-fix-SDIO-bus-errors-during-high-temp-tests.patch @@ -0,0 +1,63 @@ +From 75634632240b400d1448753e4a617f4da5aa31ab Mon Sep 17 00:00:00 2001 +From: Raveendran Somu +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0060-brcmfmac-Add-dump_survey-cfg80211-ops-for-HostApd-Au.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0060-brcmfmac-Add-dump_survey-cfg80211-ops-for-HostApd-Au.patch new file mode 100644 index 000000000..c59880c81 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0060-brcmfmac-Add-dump_survey-cfg80211-ops-for-HostApd-Au.patch @@ -0,0 +1,349 @@ +From b2b2aa897a88b4d9405068a3edfd68c92dfbf745 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0061-revert-brcmfmac-set-state-of-hanger-slot-to-FREE-whe.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0061-revert-brcmfmac-set-state-of-hanger-slot-to-FREE-whe.patch new file mode 100644 index 000000000..fd8b1028a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0061-revert-brcmfmac-set-state-of-hanger-slot-to-FREE-whe.patch @@ -0,0 +1,40 @@ +From a17b92baec44ce27ca9df9e13d2a33707011474c Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0062-brcmfmac-correctly-remove-all-p2p-vif.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0062-brcmfmac-correctly-remove-all-p2p-vif.patch new file mode 100644 index 000000000..87908159d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0062-brcmfmac-correctly-remove-all-p2p-vif.patch @@ -0,0 +1,39 @@ +From 5a6b817fc45ca7eec69e4af1302f551fda0360f9 Mon Sep 17 00:00:00 2001 +From: Brian Henriquez +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0063-brcmfmac-fix-firmware-trap-while-dumping-obss-stats.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0063-brcmfmac-fix-firmware-trap-while-dumping-obss-stats.patch new file mode 100644 index 000000000..f8413b459 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0063-brcmfmac-fix-firmware-trap-while-dumping-obss-stats.patch @@ -0,0 +1,138 @@ +From f1ba291a15f975f33a8079c9048e37ddd1938e5d Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0064-brcmfmac-add-creating-station-interface-support.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0064-brcmfmac-add-creating-station-interface-support.patch new file mode 100644 index 000000000..4d3a03c1a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0064-brcmfmac-add-creating-station-interface-support.patch @@ -0,0 +1,193 @@ +From 85ad35189b57ebe05de3b87a05d170f9bb613ab3 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0065-brcmfmac-support-station-interface-creation-version-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0065-brcmfmac-support-station-interface-creation-version-.patch new file mode 100644 index 000000000..8385202bc --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0065-brcmfmac-support-station-interface-creation-version-.patch @@ -0,0 +1,232 @@ +From 36d29fdfdd46ec717b40976214a84089cb6553d6 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0066-brcmfmac-To-fix-crash-when-platform-does-not-contain.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0066-brcmfmac-To-fix-crash-when-platform-does-not-contain.patch new file mode 100644 index 000000000..83c0347b8 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0066-brcmfmac-To-fix-crash-when-platform-does-not-contain.patch @@ -0,0 +1,37 @@ +From ba08f9de18f048636239d33116f4d966a2709d27 Mon Sep 17 00:00:00 2001 +From: Prasanna Kerekoppa +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 : [] lr : [] pstate: 40000145 26 +[ 298.921283] sp : ffff00002835baa0 + +Signed-off-by: Prasanna Kerekoppa +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0067-brcmfmac-Remove-the-call-to-dtim_assoc-IOVAR.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0067-brcmfmac-Remove-the-call-to-dtim_assoc-IOVAR.patch new file mode 100644 index 000000000..3e45b40da --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0067-brcmfmac-Remove-the-call-to-dtim_assoc-IOVAR.patch @@ -0,0 +1,71 @@ +From 629d4869b02725c86f09945e49f8b6c240d83c7b Mon Sep 17 00:00:00 2001 +From: Ramesh Rangavittal +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0068-brcmfmac-fix-CERT-P2P-5.1.10-failure.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0068-brcmfmac-fix-CERT-P2P-5.1.10-failure.patch new file mode 100644 index 000000000..10aa62b5b --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0068-brcmfmac-fix-CERT-P2P-5.1.10-failure.patch @@ -0,0 +1,40 @@ +From 61466ea09dadfdbf1124f6c69c32b30cfee4e70b Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0069-brcmfmac-Fix-for-when-connect-request-is-not-success.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0069-brcmfmac-Fix-for-when-connect-request-is-not-success.patch new file mode 100644 index 000000000..596fca17e --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0069-brcmfmac-Fix-for-when-connect-request-is-not-success.patch @@ -0,0 +1,84 @@ +From b258a24902ae911624661546cfb1f796efe9e95d Mon Sep 17 00:00:00 2001 +From: Wataru Gohda +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 +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0070-brcmfmac-Avoiding-Connection-delay.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0070-brcmfmac-Avoiding-Connection-delay.patch new file mode 100644 index 000000000..5172a432b --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0070-brcmfmac-Avoiding-Connection-delay.patch @@ -0,0 +1,41 @@ +From dc52908e2202056876d5bb2b87a9f8ca58248fdc Mon Sep 17 00:00:00 2001 +From: Prasanna Kerekoppa +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0071-non-upstream-Revert-brcm80211-select-WANT_DEV_COREDU.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0071-non-upstream-Revert-brcm80211-select-WANT_DEV_COREDU.patch new file mode 100644 index 000000000..0d19dbfcb --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0071-non-upstream-Revert-brcm80211-select-WANT_DEV_COREDU.patch @@ -0,0 +1,37 @@ +From 470b94ce0942df49af724ff66a3bf2f7ca9f36ab Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0072-brcmfmac-Fix-connecting-enterprise-AP-failure.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0072-brcmfmac-Fix-connecting-enterprise-AP-failure.patch new file mode 100644 index 000000000..c487531c2 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0072-brcmfmac-Fix-connecting-enterprise-AP-failure.patch @@ -0,0 +1,39 @@ +From 86a3bcaa6e42d5d7aea4342a3cfaf4ef016f3714 Mon Sep 17 00:00:00 2001 +From: Kurt Lee +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0073-brcmfmac-Fix-for-skbuf-allocation-failure-in-memory-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0073-brcmfmac-Fix-for-skbuf-allocation-failure-in-memory-.patch new file mode 100644 index 000000000..cbd16eec7 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0073-brcmfmac-Fix-for-skbuf-allocation-failure-in-memory-.patch @@ -0,0 +1,42 @@ +From 56ef76e7bb4dd6074b9586cc3be42b9d6affb25e Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0074-brcmfmac-Update-SSID-of-hidden-AP-while-informing-it.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0074-brcmfmac-Update-SSID-of-hidden-AP-while-informing-it.patch new file mode 100644 index 000000000..fb822cb36 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0074-brcmfmac-Update-SSID-of-hidden-AP-while-informing-it.patch @@ -0,0 +1,52 @@ +From cab3dd40c7694ba1aec2f4ab1d5953787fd23d2f Mon Sep 17 00:00:00 2001 +From: Syed Rafiuddeen +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0075-brcmfmac-Fix-PCIE-suspend-resume-issue.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0075-brcmfmac-Fix-PCIE-suspend-resume-issue.patch new file mode 100644 index 000000000..7f1620829 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0075-brcmfmac-Fix-PCIE-suspend-resume-issue.patch @@ -0,0 +1,459 @@ +From 1439760bd15d8ebb64f29712e68b518f81f9d158 Mon Sep 17 00:00:00 2001 +From: Prasanna Kerekoppa +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0076-brcmfmac-disable-mpc-when-power_save-is-disabled.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0076-brcmfmac-disable-mpc-when-power_save-is-disabled.patch new file mode 100644 index 000000000..dc932eaae --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0076-brcmfmac-disable-mpc-when-power_save-is-disabled.patch @@ -0,0 +1,107 @@ +From e31bda91b203333903b66d82a308d07e275e03bd Mon Sep 17 00:00:00 2001 +From: Divya Madhyan +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0077-brcmfmac-Fix-authentication-latency-caused-by-OBSS-s.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0077-brcmfmac-Fix-authentication-latency-caused-by-OBSS-s.patch new file mode 100644 index 000000000..9fe323896 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0077-brcmfmac-Fix-authentication-latency-caused-by-OBSS-s.patch @@ -0,0 +1,41 @@ +From fa8b1ad5399495accb517311ccf1536022b25ae4 Mon Sep 17 00:00:00 2001 +From: Ramesh Rangavittal +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0078-brcmfmac-support-external-SAE-authentication-in-stat.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0078-brcmfmac-support-external-SAE-authentication-in-stat.patch new file mode 100644 index 000000000..1a5c9b7ab --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0078-brcmfmac-support-external-SAE-authentication-in-stat.patch @@ -0,0 +1,588 @@ +From 3b967b04b13612c5886f97588b8d747f30498d37 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +Signed-off-by: Chi-hsien Lin +--- + .../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(¶ms, 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, ¶ms, 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0079-brcmfmac-fix-sdio-watchdog-timer-start-fail-issue.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0079-brcmfmac-fix-sdio-watchdog-timer-start-fail-issue.patch new file mode 100644 index 000000000..38f22a11e --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0079-brcmfmac-fix-sdio-watchdog-timer-start-fail-issue.patch @@ -0,0 +1,46 @@ +From e1990521f370bf646b58c83115efd989763132d6 Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0080-brcmfmac-Frameburst-vendor-command-addition.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0080-brcmfmac-Frameburst-vendor-command-addition.patch new file mode 100644 index 000000000..cd83f34b6 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0080-brcmfmac-Frameburst-vendor-command-addition.patch @@ -0,0 +1,147 @@ +From 6a5c92be8baaa0d6b44f47ac8a2232503c2ac67f Mon Sep 17 00:00:00 2001 +From: Divya Madhyan +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 +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0081-brcmfmac-add-support-for-CYW43439-SDIO-chipset.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0081-brcmfmac-add-support-for-CYW43439-SDIO-chipset.patch new file mode 100644 index 000000000..a1f42a5ca --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0081-brcmfmac-add-support-for-CYW43439-SDIO-chipset.patch @@ -0,0 +1,88 @@ +From e7c2474c59499879dc85649a285c62b637de0615 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 + +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0082-brcmfmac-add-BT-shared-SDIO-support.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0082-brcmfmac-add-BT-shared-SDIO-support.patch new file mode 100644 index 000000000..c756e6a3d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0082-brcmfmac-add-BT-shared-SDIO-support.patch @@ -0,0 +1,622 @@ +From 1421a6cf03dec762a6aa45955b77087838e3388f Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Ian Lin + +--- + .../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 ++#include ++#include ++#include ++#include ++#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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0083-brcmfmac-add-CYW43439-SR-related-changes.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0083-brcmfmac-add-CYW43439-SR-related-changes.patch new file mode 100644 index 000000000..2115d4f5a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0083-brcmfmac-add-CYW43439-SR-related-changes.patch @@ -0,0 +1,79 @@ +From c47267fd331ea3fbde18512c2886730ba368bd66 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 + +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0084-brcmfmac-add-support-for-CYW43439-with-blank-OTP.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0084-brcmfmac-add-support-for-CYW43439-with-blank-OTP.patch new file mode 100644 index 000000000..c86840638 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0084-brcmfmac-add-support-for-CYW43439-with-blank-OTP.patch @@ -0,0 +1,29 @@ +From f5757ad1fc68803adc0fb97d05d9d9f78fffa37c Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0085-brcmfmac-support-43439-Cypress-Vendor-and-Device-ID.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0085-brcmfmac-support-43439-Cypress-Vendor-and-Device-ID.patch new file mode 100644 index 000000000..c93a5cbf9 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0085-brcmfmac-support-43439-Cypress-Vendor-and-Device-ID.patch @@ -0,0 +1,55 @@ +From 1b09fc6411658347e621233572582fb93e1c7c8e Mon Sep 17 00:00:00 2001 +From: Double Lo +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 + +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0086-brcmfmac-fix-P2P-device-discovery-failure.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0086-brcmfmac-fix-P2P-device-discovery-failure.patch new file mode 100644 index 000000000..baf4cfc76 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0086-brcmfmac-fix-P2P-device-discovery-failure.patch @@ -0,0 +1,33 @@ +From ba08274412b062d11a716610624d491b851bc9b3 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0087-brcmfmac-Add-SDIO-verdor-device-id-for-CYW89459-in-h.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0087-brcmfmac-Add-SDIO-verdor-device-id-for-CYW89459-in-h.patch new file mode 100644 index 000000000..0f46a4284 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0087-brcmfmac-Add-SDIO-verdor-device-id-for-CYW89459-in-h.patch @@ -0,0 +1,44 @@ +From 2529049f56361da5d5349aa609fff0d0a4c5bb46 Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0088-brcmfmac-Add-CYW89459-HW-ID-and-modify-sdio-F2-block.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0088-brcmfmac-Add-CYW89459-HW-ID-and-modify-sdio-F2-block.patch new file mode 100644 index 000000000..476311474 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0088-brcmfmac-Add-CYW89459-HW-ID-and-modify-sdio-F2-block.patch @@ -0,0 +1,115 @@ +From ca1b98f96ab08aa7e4228714b62cb8f9785efc8c Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0089-brcmfmac-Fix-AP-interface-delete-issue.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0089-brcmfmac-Fix-AP-interface-delete-issue.patch new file mode 100644 index 000000000..7b85dceab --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0089-brcmfmac-Fix-AP-interface-delete-issue.patch @@ -0,0 +1,136 @@ +From 0ef987e14c7451a3cd961cdc10ff305bf92d80c2 Mon Sep 17 00:00:00 2001 +From: Prasanna Kerekoppa +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0090-brcmfmac-Revise-channel-info-for-WPA3-external-SAE.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0090-brcmfmac-Revise-channel-info-for-WPA3-external-SAE.patch new file mode 100644 index 000000000..e39c3366a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0090-brcmfmac-Revise-channel-info-for-WPA3-external-SAE.patch @@ -0,0 +1,72 @@ +From 3b95b79bb76c41d0b1b0cecefbc8fe87237e55e8 Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0091-brcmfmac-Fix-structure-size-for-WPA3-external-SAE.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0091-brcmfmac-Fix-structure-size-for-WPA3-external-SAE.patch new file mode 100644 index 000000000..0132c6460 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0091-brcmfmac-Fix-structure-size-for-WPA3-external-SAE.patch @@ -0,0 +1,30 @@ +From 0fa8ea7bf78c193ad42b61fabb6edd97cbc07674 Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0092-brcmfmac-support-54590-54594-PCIe-device-id.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0092-brcmfmac-support-54590-54594-PCIe-device-id.patch new file mode 100644 index 000000000..eb0e909e4 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0092-brcmfmac-support-54590-54594-PCIe-device-id.patch @@ -0,0 +1,42 @@ +From f6cfaf8c318129f6fbe9c578d46f2c36e4bd4f57 Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0093-Revert-non-upstream-make-setting-SDIO-workqueue-WQ_H.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0093-Revert-non-upstream-make-setting-SDIO-workqueue-WQ_H.patch new file mode 100644 index 000000000..812a6967a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0093-Revert-non-upstream-make-setting-SDIO-workqueue-WQ_H.patch @@ -0,0 +1,104 @@ +From 5fe1732c51facac10495ba5b8ea368a871053a25 Mon Sep 17 00:00:00 2001 +From: Ian Lin +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0094-brcmfmac-Set-SDIO-workqueue-as-WQ_HIGHPRI.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0094-brcmfmac-Set-SDIO-workqueue-as-WQ_HIGHPRI.patch new file mode 100644 index 000000000..a263ca09e --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0094-brcmfmac-Set-SDIO-workqueue-as-WQ_HIGHPRI.patch @@ -0,0 +1,48 @@ +From 20768a08b77ba4ceaa6094a7bbca7973599b19dc Mon Sep 17 00:00:00 2001 +From: Sean Anderson +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 +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0095-brcmfmac-revise-SoftAP-channel-setting.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0095-brcmfmac-revise-SoftAP-channel-setting.patch new file mode 100644 index 000000000..09363758f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0095-brcmfmac-revise-SoftAP-channel-setting.patch @@ -0,0 +1,53 @@ +From 41ef0b69200e6656294c726ac8882b0d56d76ed9 Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0096-brcmfmac-Optimize-CYW4373-SDIO-current.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0096-brcmfmac-Optimize-CYW4373-SDIO-current.patch new file mode 100644 index 000000000..d55ce6131 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0096-brcmfmac-Optimize-CYW4373-SDIO-current.patch @@ -0,0 +1,65 @@ +From b7edf2ad70757a18706cb152763553cf98669627 Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0097-brcmfmac-use-request_firmware_direct-for-loading-boa.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0097-brcmfmac-use-request_firmware_direct-for-loading-boa.patch new file mode 100644 index 000000000..bbe0f9a10 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0097-brcmfmac-use-request_firmware_direct-for-loading-boa.patch @@ -0,0 +1,45 @@ +From bc427ef6fd49a05887bea580caeddd1bf4ab9b28 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +Signed-off-by: Ting-Ying Li +Signed-off-by: Chi-hsien Lin +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0098-brcmfmac-enable-pmk-catching-for-ext-sae-wpa3-ap.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0098-brcmfmac-enable-pmk-catching-for-ext-sae-wpa3-ap.patch new file mode 100644 index 000000000..618396558 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0098-brcmfmac-enable-pmk-catching-for-ext-sae-wpa3-ap.patch @@ -0,0 +1,44 @@ +From 1fcaa9ff3d3819d83d5e63e34a3af79762e35efe Mon Sep 17 00:00:00 2001 +From: Ting-Ying Li +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 +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0099-brcmfmac-fixes-CYW4373-SDIO-CMD53-error.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0099-brcmfmac-fixes-CYW4373-SDIO-CMD53-error.patch new file mode 100644 index 000000000..2cba6b18c --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0099-brcmfmac-fixes-CYW4373-SDIO-CMD53-error.patch @@ -0,0 +1,29 @@ +From 1b8b42f244aa1e829d338857d51a3c7a008fc826 Mon Sep 17 00:00:00 2001 +From: Double Lo +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 +--- + 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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0100-brcmfmac-add-PCIe-mailbox-support-for-core-revision-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0100-brcmfmac-add-PCIe-mailbox-support-for-core-revision-.patch new file mode 100644 index 000000000..448a895e6 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0100-brcmfmac-add-PCIe-mailbox-support-for-core-revision-.patch @@ -0,0 +1,206 @@ +From cc9f70a9ed54bd4d32515c19eebda3f41af5ad8f Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Chung-Hsien Hsu +--- + .../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 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0101-brcmfmac-add-support-for-TRX-firmware-download.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0101-brcmfmac-add-support-for-TRX-firmware-download.patch new file mode 100644 index 000000000..3a92c008f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0101-brcmfmac-add-support-for-TRX-firmware-download.patch @@ -0,0 +1,143 @@ +From 1334e07200e20b878312e19f5210b2960a07b10f Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Tue, 28 Apr 2020 21:20:06 -0500 +Subject: [PATCH 101/179] brcmfmac: add support for TRX firmware download + +Add support to download TRX firmware for PCIe and SDIO. + +Signed-off-by: Chung-Hsien Hsu +--- + .../broadcom/brcm80211/brcmfmac/pcie.c | 12 +++++- + .../broadcom/brcm80211/brcmfmac/sdio.c | 20 +++++++--- + .../broadcom/brcm80211/brcmfmac/trxhdr.h | 38 +++++++++++++++++++ + 3 files changed, 63 insertions(+), 7 deletions(-) + create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/trxhdr.h + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index de9788c68231..71cc14ca0909 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -42,6 +42,7 @@ + #include "core.h" + #include "common.h" + #include "cfg80211.h" ++#include "trxhdr.h" + + + enum brcmf_pcie_state { +@@ -1926,6 +1927,8 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + u32 nvram_len) + { + struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); ++ struct trx_header_le *trx = (struct trx_header_le *)fw->data; ++ u32 fw_size; + u32 sharedram_addr; + u32 sharedram_addr_written; + u32 loop_counter; +@@ -1939,8 +1942,13 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + return err; + + brcmf_dbg(PCIE, "Download FW %s\n", devinfo->fw_name); +- memcpy_toio(devinfo->tcm + devinfo->ci->rambase, +- (void *)fw->data, fw->size); ++ address = devinfo->ci->rambase; ++ fw_size = fw->size; ++ if (trx->magic == cpu_to_le32(TRX_MAGIC)) { ++ address -= sizeof(struct trx_header_le); ++ fw_size = le32_to_cpu(trx->len); ++ } ++ brcmf_pcie_copy_mem_todev(devinfo, address, (void *)fw->data, fw_size); + + resetintr = get_unaligned_le32(fw->data); + release_firmware(fw); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index da273eff93d2..406569b0bea4 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -39,6 +39,7 @@ + #include "bcdc.h" + #include "fwil.h" + #include "bt_shared_sdio.h" ++#include "trxhdr.h" + + #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) + #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) +@@ -3617,17 +3618,26 @@ brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr, + static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus, + const struct firmware *fw) + { ++ struct trx_header_le *trx = (struct trx_header_le *)fw->data; ++ u32 fw_size; ++ u32 address; + int err; + + brcmf_dbg(TRACE, "Enter\n"); + +- err = brcmf_sdiod_ramrw(bus->sdiodev, true, bus->ci->rambase, +- (u8 *)fw->data, fw->size); ++ address = bus->ci->rambase; ++ fw_size = fw->size; ++ if (trx->magic == cpu_to_le32(TRX_MAGIC)) { ++ address -= sizeof(struct trx_header_le); ++ fw_size = le32_to_cpu(trx->len); ++ } ++ err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, ++ (u8 *)fw->data, fw_size); + if (err) + brcmf_err("error %d on writing %d membytes at 0x%08x\n", +- err, (int)fw->size, bus->ci->rambase); +- else if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase, +- (u8 *)fw->data, fw->size)) ++ err, (int)fw_size, address); ++ else if (!brcmf_sdio_verifymemory(bus->sdiodev, address, ++ (u8 *)fw->data, fw_size)) + err = -EIO; + + return err; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/trxhdr.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/trxhdr.h +new file mode 100644 +index 000000000000..0411c7c7ffb9 +--- /dev/null ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/trxhdr.h +@@ -0,0 +1,38 @@ ++/* SPDX-License-Identifier: ISC */ ++/* Copyright (c) 2020 Cypress Semiconductor Corporation */ ++ ++#ifndef BRCMFMAC_TRXHDR_H ++#define BRCMFMAC_TRXHDR_H ++ ++/* Bootloader makes special use of trx header "offsets" array */ ++enum { ++ TRX_OFFSET_SIGN_INFO_IDX = 0, ++ TRX_OFFSET_DATA_FOR_SIGN1_IDX = 1, ++ TRX_OFFSET_DATA_FOR_SIGN2_IDX = 2, ++ TRX_OFFSET_ROOT_MODULUS_IDX = 3, ++ TRX_OFFSET_ROOT_EXPONENT_IDX = 67, ++ TRX_OFFSET_CONT_MODULUS_IDX = 68, ++ TRX_OFFSET_CONT_EXPONENT_IDX = 132, ++ TRX_OFFSET_HASH_FW_IDX = 133, ++ TRX_OFFSET_FW_LEN_IDX = 149, ++ TRX_OFFSET_TR_RST_IDX = 150, ++ TRX_OFFSET_FW_VER_FOR_ANTIROOLBACK_IDX = 151, ++ TRX_OFFSET_IV_IDX = 152, ++ TRX_OFFSET_NONCE_IDX = 160, ++ TRX_OFFSET_SIGN_INFO2_IDX = 168, ++ TRX_OFFSET_MAX_IDX ++}; ++ ++#define TRX_MAGIC 0x30524448 /* "HDR0" */ ++#define TRX_VERSION 4 /* Version 4 */ ++#define TRX_MAX_OFFSET TRX_OFFSET_MAX_IDX /* Max number of file offsets */ ++ ++struct trx_header_le { ++ __le32 magic; /* "HDR0" */ ++ __le32 len; /* Length of file including header */ ++ __le32 crc32; /* CRC from flag_version to end of file */ ++ __le32 flag_version; /* 0:15 flags, 16:31 version */ ++ __le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions */ ++}; ++ ++#endif /* BRCMFMAC_TRXHDR_H */ +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0102-brcmfmac-add-Cypress-PCIe-vendor-ID.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0102-brcmfmac-add-Cypress-PCIe-vendor-ID.patch new file mode 100644 index 000000000..5d136e586 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0102-brcmfmac-add-Cypress-PCIe-vendor-ID.patch @@ -0,0 +1,27 @@ +From 07a6e43fc286f67252dc2c7719f93ea1bb88a511 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Wed, 29 Apr 2020 17:40:42 -0500 +Subject: [PATCH 102/179] brcmfmac: add Cypress PCIe vendor ID + +Add Cypress PCIe vendor ID 0x12be. + +Signed-off-by: Chung-Hsien Hsu +--- + drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 + + 1 file changed, 1 insertion(+) + +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 9aff8cbf6fee..61ae748d9125 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -14,6 +14,7 @@ + #define BRCM_USB_VENDOR_ID_LINKSYS 0x13b1 + #define CY_USB_VENDOR_ID_CYPRESS 0x04b4 + #define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM ++#define CY_PCIE_VENDOR_ID_CYPRESS 0x12be + + /* Chipcommon Core Chip IDs */ + #define BRCM_CC_43143_CHIP_ID 43143 +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0103-brcmfmac-add-support-for-CYW55560-PCIe-chipset.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0103-brcmfmac-add-support-for-CYW55560-PCIe-chipset.patch new file mode 100644 index 000000000..d33581980 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0103-brcmfmac-add-support-for-CYW55560-PCIe-chipset.patch @@ -0,0 +1,822 @@ +From 1f27834146b57065ee5d91f4e3f5f1523b951d0d Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Wed, 13 May 2020 14:18:02 -0500 +Subject: [PATCH 103/179] brcmfmac: add support for CYW55560 PCIe chipset + +CYW55560 is a 2x2 dual-band 802.11a/b/g/n/ac/ax chipset with 20/40/80MHz +channel support. It's a WLAN+BT combo device with WLAN secure boot +support. + +Signed-off-by: Chung-Hsien Hsu +--- + .../broadcom/brcm80211/brcmfmac/chip.c | 195 +++++++++++++++++- + .../broadcom/brcm80211/brcmfmac/chip.h | 34 +++ + .../broadcom/brcm80211/brcmfmac/firmware.c | 15 +- + .../broadcom/brcm80211/brcmfmac/firmware.h | 8 +- + .../broadcom/brcm80211/brcmfmac/pcie.c | 191 ++++++++++++++++- + .../broadcom/brcm80211/include/brcm_hw_ids.h | 4 +- + .../broadcom/brcm80211/include/brcmu_utils.h | 13 ++ + 7 files changed, 444 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +index 186b5bee33b4..d055cd43ddeb 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -233,6 +233,32 @@ struct sbsocramregs { + /* Minimum PMU resource mask for 4373 */ + #define CY_4373_PMU_MIN_RES_MASK 0xFCAFF7F + ++/* CYW55560 dedicated space and RAM base */ ++#define CYW55560_TCAM_SIZE 0x800 ++#define CYW55560_TRXHDR_SIZE 0x2b4 ++#define CYW55560_RAM_BASE (0x370000 + \ ++ CYW55560_TCAM_SIZE + CYW55560_TRXHDR_SIZE) ++ ++#define BRCMF_BLHS_POLL_INTERVAL 10 /* msec */ ++#define BRCMF_BLHS_D2H_READY_TIMEOUT 100 /* msec */ ++#define BRCMF_BLHS_D2H_TRXHDR_PARSE_DONE_TIMEOUT 50 /* msec */ ++#define BRCMF_BLHS_D2H_VALDN_DONE_TIMEOUT 250 /* msec */ ++ ++/* Bootloader handshake flags - dongle to host */ ++#define BRCMF_BLHS_D2H_START BIT(0) ++#define BRCMF_BLHS_D2H_READY BIT(1) ++#define BRCMF_BLHS_D2H_STEADY BIT(2) ++#define BRCMF_BLHS_D2H_TRXHDR_PARSE_DONE BIT(3) ++#define BRCMF_BLHS_D2H_VALDN_START BIT(4) ++#define BRCMF_BLHS_D2H_VALDN_RESULT BIT(5) ++#define BRCMF_BLHS_D2H_VALDN_DONE BIT(6) ++ ++/* Bootloader handshake flags - host to dongle */ ++#define BRCMF_BLHS_H2D_DL_FW_START BIT(0) ++#define BRCMF_BLHS_H2D_DL_FW_DONE BIT(1) ++#define BRCMF_BLHS_H2D_DL_NVRAM_DONE BIT(2) ++#define BRCMF_BLHS_H2D_BL_RESET_ON_ERROR BIT(3) ++ + struct brcmf_core_priv { + struct brcmf_core pub; + u32 wrapbase; +@@ -752,6 +778,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) + return 0x170000; + case CY_CC_89459_CHIP_ID: + return ((ci->pub.chiprev < 9) ? 0x180000 : 0x160000); ++ case CY_CC_55560_CHIP_ID: ++ return CYW55560_RAM_BASE; + default: + brcmf_err("unknown chip: %s\n", ci->pub.name); + break; +@@ -770,6 +798,9 @@ int brcmf_chip_get_raminfo(struct brcmf_chip *pub) + if (mem) { + mem_core = container_of(mem, struct brcmf_core_priv, pub); + ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core); ++ if (ci->pub.chip == CY_CC_55560_CHIP_ID) ++ ci->pub.ramsize -= (CYW55560_TCAM_SIZE + ++ CYW55560_TRXHDR_SIZE); + ci->pub.rambase = brcmf_chip_tcm_rambase(ci); + if (ci->pub.rambase == INVALID_RAMBASE) { + brcmf_err("RAM base not provided with ARM CR4 core\n"); +@@ -973,6 +1004,144 @@ u32 brcmf_chip_enum_base(u16 devid) + return SI_ENUM_BASE_DEFAULT; + } + ++static void brcmf_blhs_init(struct brcmf_chip *pub) ++{ ++ struct brcmf_chip_priv *chip; ++ u32 addr; ++ ++ chip = container_of(pub, struct brcmf_chip_priv, pub); ++ addr = pub->blhs->h2d; ++ pub->blhs->write(chip->ctx, addr, 0); ++} ++ ++static int brcmf_blhs_is_bootloader_ready(struct brcmf_chip_priv *chip) ++{ ++ u32 regdata; ++ u32 addr; ++ ++ addr = chip->pub.blhs->d2h; ++ SPINWAIT_MS((chip->pub.blhs->read(chip->ctx, addr) & ++ BRCMF_BLHS_D2H_READY) == 0, ++ BRCMF_BLHS_D2H_READY_TIMEOUT, BRCMF_BLHS_POLL_INTERVAL); ++ ++ regdata = chip->pub.blhs->read(chip->ctx, addr); ++ if (!(regdata & BRCMF_BLHS_D2H_READY)) { ++ brcmf_err("Timeout waiting for bootloader ready\n"); ++ return -EPERM; ++ } ++ ++ return 0; ++} ++ ++static int brcmf_blhs_prep_fw_download(struct brcmf_chip *pub) ++{ ++ struct brcmf_chip_priv *chip; ++ u32 addr; ++ int err; ++ ++ /* Host indication for bootloader to start the init */ ++ brcmf_blhs_init(pub); ++ ++ chip = container_of(pub, struct brcmf_chip_priv, pub); ++ err = brcmf_blhs_is_bootloader_ready(chip); ++ if (err) ++ return err; ++ ++ /* Host notification about FW download start */ ++ addr = pub->blhs->h2d; ++ pub->blhs->write(chip->ctx, addr, BRCMF_BLHS_H2D_DL_FW_START); ++ ++ return 0; ++} ++ ++static int brcmf_blhs_post_fw_download(struct brcmf_chip *pub) ++{ ++ struct brcmf_chip_priv *chip; ++ u32 addr; ++ u32 regdata; ++ ++ chip = container_of(pub, struct brcmf_chip_priv, pub); ++ addr = pub->blhs->h2d; ++ pub->blhs->write(chip->ctx, addr, BRCMF_BLHS_H2D_DL_FW_DONE); ++ addr = pub->blhs->d2h; ++ SPINWAIT_MS((pub->blhs->read(chip->ctx, addr) & ++ BRCMF_BLHS_D2H_TRXHDR_PARSE_DONE) == 0, ++ BRCMF_BLHS_D2H_TRXHDR_PARSE_DONE_TIMEOUT, ++ BRCMF_BLHS_POLL_INTERVAL); ++ ++ regdata = pub->blhs->read(chip->ctx, addr); ++ if (!(regdata & BRCMF_BLHS_D2H_TRXHDR_PARSE_DONE)) { ++ brcmf_err("TRX header parsing failed\n"); ++ ++ /* Host indication for bootloader to get reset on error */ ++ addr = pub->blhs->h2d; ++ regdata = pub->blhs->read(chip->ctx, addr); ++ regdata |= BRCMF_BLHS_H2D_BL_RESET_ON_ERROR; ++ pub->blhs->write(chip->ctx, addr, regdata); ++ ++ return -EPERM; ++ } ++ ++ return 0; ++} ++ ++static void brcmf_blhs_post_nvram_download(struct brcmf_chip *pub) ++{ ++ struct brcmf_chip_priv *chip; ++ u32 addr; ++ u32 regdata; ++ ++ chip = container_of(pub, struct brcmf_chip_priv, pub); ++ addr = pub->blhs->h2d; ++ regdata = pub->blhs->read(chip->ctx, addr); ++ regdata |= BRCMF_BLHS_H2D_DL_NVRAM_DONE; ++ pub->blhs->write(chip->ctx, addr, regdata); ++} ++ ++static int brcmf_blhs_chk_validation(struct brcmf_chip *pub) ++{ ++ struct brcmf_chip_priv *chip; ++ u32 addr; ++ u32 regdata; ++ ++ chip = container_of(pub, struct brcmf_chip_priv, pub); ++ addr = pub->blhs->d2h; ++ SPINWAIT_MS((pub->blhs->read(chip->ctx, addr) & ++ BRCMF_BLHS_D2H_VALDN_DONE) == 0, ++ BRCMF_BLHS_D2H_VALDN_DONE_TIMEOUT, ++ BRCMF_BLHS_POLL_INTERVAL); ++ ++ regdata = pub->blhs->read(chip->ctx, addr); ++ if (!(regdata & BRCMF_BLHS_D2H_VALDN_DONE) || ++ !(regdata & BRCMF_BLHS_D2H_VALDN_RESULT)) { ++ brcmf_err("TRX image validation check failed\n"); ++ ++ /* Host notification for bootloader to get reset on error */ ++ addr = pub->blhs->h2d; ++ regdata = pub->blhs->read(chip->ctx, addr); ++ regdata |= BRCMF_BLHS_H2D_BL_RESET_ON_ERROR; ++ pub->blhs->write(chip->ctx, addr, regdata); ++ ++ return -EPERM; ++ } ++ ++ return 0; ++} ++ ++static int brcmf_blhs_post_watchdog_reset(struct brcmf_chip *pub) ++{ ++ struct brcmf_chip_priv *chip; ++ int err; ++ ++ /* Host indication for bootloader to start the init */ ++ brcmf_blhs_init(pub); ++ ++ chip = container_of(pub, struct brcmf_chip_priv, pub); ++ err = brcmf_blhs_is_bootloader_ready(chip); ++ ++ return err; ++} ++ + static int brcmf_chip_recognition(struct brcmf_chip_priv *ci) + { + struct brcmf_core *core; +@@ -1124,6 +1293,7 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx, u16 devid, + const struct brcmf_buscore_ops *ops) + { + struct brcmf_chip_priv *chip; ++ struct brcmf_blhs *blhs; + int err = 0; + + if (WARN_ON(!ops->read32)) +@@ -1151,6 +1321,26 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx, u16 devid, + if (err < 0) + goto fail; + ++ blhs = NULL; ++ if (chip->ops->blhs_attach) { ++ err = chip->ops->blhs_attach(chip->ctx, &blhs, ++ BRCMF_BLHS_D2H_READY, ++ BRCMF_BLHS_D2H_READY_TIMEOUT, ++ BRCMF_BLHS_POLL_INTERVAL); ++ if (err < 0) ++ goto fail; ++ ++ if (blhs) { ++ blhs->init = brcmf_blhs_init; ++ blhs->prep_fwdl = brcmf_blhs_prep_fw_download; ++ blhs->post_fwdl = brcmf_blhs_post_fw_download; ++ blhs->post_nvramdl = brcmf_blhs_post_nvram_download; ++ blhs->chk_validation = brcmf_blhs_chk_validation; ++ blhs->post_wdreset = brcmf_blhs_post_watchdog_reset; ++ } ++ } ++ chip->pub.blhs = blhs; ++ + err = brcmf_chip_recognition(chip); + if (err < 0) + goto fail; +@@ -1177,6 +1367,7 @@ void brcmf_chip_detach(struct brcmf_chip *pub) + list_del(&core->list); + kfree(core); + } ++ kfree(pub->blhs); + kfree(chip); + } + +@@ -1317,7 +1508,8 @@ brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip) + { + struct brcmf_core *core; + +- brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4); ++ if (!chip->pub.blhs) ++ brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4); + + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211); + brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET | +@@ -1620,4 +1812,3 @@ void brcmf_chip_reset_watchdog(struct brcmf_chip *pub) + break; + } + } +- +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +index 2ba72ec12675..4629201de715 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +@@ -13,6 +13,8 @@ + #define CORE_GCI_REG(base, field) \ + ((base) + offsetof(struct chipgciregs, field)) + ++struct brcmf_blhs; ++ + /** + * struct brcmf_chip - chip level information. + * +@@ -27,6 +29,7 @@ + * @ramsize: amount of RAM on chip including retention. + * @srsize: amount of retention RAM on chip. + * @name: string representation of the chip identifier. ++ * @blhs: bootlooder handshake handle. + */ + struct brcmf_chip { + u32 chip; +@@ -40,6 +43,7 @@ struct brcmf_chip { + u32 ramsize; + u32 srsize; + char name[12]; ++ struct brcmf_blhs *blhs; + }; + + /** +@@ -64,6 +68,7 @@ struct brcmf_core { + * @setup: bus-specific core setup. + * @active: chip becomes active. + * The callback should use the provided @rstvec when non-zero. ++ * @blhs_attach: attach bootloader handshake handle + */ + struct brcmf_buscore_ops { + u32 (*read32)(void *ctx, u32 addr); +@@ -72,6 +77,35 @@ struct brcmf_buscore_ops { + int (*reset)(void *ctx, struct brcmf_chip *chip); + int (*setup)(void *ctx, struct brcmf_chip *chip); + void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); ++ int (*blhs_attach)(void *ctx, struct brcmf_blhs **blhs, u32 flag, ++ uint timeout, uint interval); ++}; ++ ++/** ++ * struct brcmf_blhs - bootloader handshake handle related information. ++ * ++ * @d2h: offset of dongle to host register for the handshake. ++ * @h2d: offset of host to dongle register for the handshake. ++ * @init: bootloader handshake initialization. ++ * @prep_fwdl: handshake before firmware download. ++ * @post_fwdl: handshake after firmware download. ++ * @post_nvramdl: handshake after nvram download. ++ * @chk_validation: handshake for firmware validation check. ++ * @post_wdreset: handshake after watchdog reset. ++ * @read: read value with register offset for the handshake. ++ * @write: write value with register offset for the handshake. ++ */ ++struct brcmf_blhs { ++ u32 d2h; ++ u32 h2d; ++ void (*init)(struct brcmf_chip *pub); ++ int (*prep_fwdl)(struct brcmf_chip *pub); ++ int (*post_fwdl)(struct brcmf_chip *pub); ++ void (*post_nvramdl)(struct brcmf_chip *pub); ++ int (*chk_validation)(struct brcmf_chip *pub); ++ int (*post_wdreset)(struct brcmf_chip *pub); ++ u32 (*read)(void *ctx, u32 addr); ++ void (*write)(void *ctx, u32 addr, u32 value); + }; + + int brcmf_chip_get_raminfo(struct brcmf_chip *pub); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +index a9d122abf444..db951ef79088 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -508,7 +508,8 @@ static void brcmf_fw_free_request(struct brcmf_fw_request *req) + int i; + + for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) { +- if (item->type == BRCMF_FW_TYPE_BINARY) ++ if (item->type == BRCMF_FW_TYPE_BINARY || ++ item->type == BRCMF_FW_TYPE_TRXSE) + release_firmware(item->binary); + else if (item->type == BRCMF_FW_TYPE_NVRAM) + brcmf_fw_nvram_free(item->nv_data.data); +@@ -579,6 +580,7 @@ static int brcmf_fw_complete_request(const struct firmware *fw, + ret = brcmf_fw_request_nvram_done(fw, fwctx); + break; + case BRCMF_FW_TYPE_BINARY: ++ case BRCMF_FW_TYPE_TRXSE: + if (fw) + cur->binary = fw; + else +@@ -644,8 +646,19 @@ static int brcmf_fw_request_firmware(const struct firmware **fw, + static void brcmf_fw_request_done(const struct firmware *fw, void *ctx) + { + struct brcmf_fw *fwctx = ctx; ++ struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos]; ++ char alt_path[BRCMF_FW_NAME_LEN]; + int ret; + ++ if (!fw && cur->type == BRCMF_FW_TYPE_TRXSE) { ++ strlcpy(alt_path, cur->path, BRCMF_FW_NAME_LEN); ++ /* strip 'se' from .trxse at the end */ ++ alt_path[strlen(alt_path) - 2] = 0; ++ ret = request_firmware(&fw, alt_path, fwctx->dev); ++ if (!ret) ++ cur->path = alt_path; ++ } ++ + ret = brcmf_fw_complete_request(fw, fwctx); + + while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +index f0748500b345..ee6d5429ea16 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +@@ -46,6 +46,11 @@ static const char BRCM_ ## fw_name ## _FIRMWARE_BASENAME[] = \ + CY_FW_DEFAULT_PATH fw_base; \ + MODULE_FIRMWARE(CY_FW_DEFAULT_PATH fw_base ".bin") + ++#define CY_FW_TRXSE_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 ".trxse") ++ + #define BRCMF_FW_ENTRY(chipid, mask, name) \ + { chipid, mask, BRCM_ ## name ## _FIRMWARE_BASENAME } + +@@ -53,7 +58,8 @@ void brcmf_fw_nvram_free(void *nvram); + + enum brcmf_fw_type { + BRCMF_FW_TYPE_BINARY, +- BRCMF_FW_TYPE_NVRAM ++ BRCMF_FW_TYPE_NVRAM, ++ BRCMF_FW_TYPE_TRXSE + }; + + struct brcmf_fw_item { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index 71cc14ca0909..8048a48cdb93 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -64,6 +64,7 @@ BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); + BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); + BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); + CY_FW_DEF(4355, "cyfmac54591-pcie"); ++CY_FW_TRXSE_DEF(55560, "cyfmac55560-pcie"); + + /* firmware config files */ + MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt"); +@@ -93,6 +94,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_55560_CHIP_ID, 0xFFFFFFFF, 55560), + }; + + #define BRCMF_PCIE_REV_GE64(dev) (brcmf_chip_get_core((dev)->ci, \ +@@ -108,7 +110,8 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + #define BRCMF_PCIE_BAR0_WRAPPERBASE 0x70 + + #define BRCMF_PCIE_BAR0_WRAPBASE_DMP_OFFSET 0x1000 +-#define BRCMF_PCIE_BARO_PCIE_ENUM_OFFSET 0x2000 ++#define BRCMF_PCIE_BAR0_PCIE_ENUM_OFFSET 0x2000 ++#define BRCMF_CYW55560_PCIE_BAR0_PCIE_ENUM_OFFSET 0x3000 + + #define BRCMF_PCIE_ARMCR4REG_BANKIDX 0x40 + #define BRCMF_PCIE_ARMCR4REG_BANKPDA 0x4C +@@ -128,6 +131,8 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + #define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124 + #define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0 0x140 + #define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1 0x144 ++#define BRCMF_PCIE_PCIE2REG_DAR_D2H_MSG_0 0xA80 ++#define BRCMF_PCIE_PCIE2REG_DAR_H2D_MSG_0 0xA90 + + #define BRCMF_PCIE2_INTA 0x01 + #define BRCMF_PCIE2_INTB 0x02 +@@ -260,18 +265,32 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + #define BRCMF_PCIE_CFGREG_MSI_ADDR_L 0x5C + #define BRCMF_PCIE_CFGREG_MSI_ADDR_H 0x60 + #define BRCMF_PCIE_CFGREG_MSI_DATA 0x64 ++#define BRCMF_PCIE_CFGREG_REVID 0x6C + #define BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL 0xBC + #define BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL2 0xDC + #define BRCMF_PCIE_CFGREG_RBAR_CTRL 0x228 + #define BRCMF_PCIE_CFGREG_PML1_SUB_CTRL1 0x248 + #define BRCMF_PCIE_CFGREG_REG_BAR2_CONFIG 0x4E0 + #define BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG 0x4F4 ++#define BRCMF_PCIE_CFGREG_REVID_SECURE_MODE BIT(31) + #define BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB 3 + + /* Magic number at a magic location to find RAM size */ + #define BRCMF_RAMSIZE_MAGIC 0x534d4152 /* SMAR */ + #define BRCMF_RAMSIZE_OFFSET 0x6c + ++#define BRCMF_ENTROPY_SEED_LEN 64u ++#define BRCMF_ENTROPY_NONCE_LEN 16u ++#define BRCMF_ENTROPY_HOST_LEN (BRCMF_ENTROPY_SEED_LEN + \ ++ BRCMF_ENTROPY_NONCE_LEN) ++#define BRCMF_NVRAM_OFFSET_TCM 4u ++#define BRCMF_NVRAM_COMPRS_FACTOR 4u ++#define BRCMF_NVRAM_RNG_SIGNATURE 0xFEEDC0DEu ++ ++struct brcmf_rand_metadata { ++ u32 signature; ++ u32 count; ++}; + + struct brcmf_pcie_console { + u32 base_addr; +@@ -879,9 +898,15 @@ static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo) + val); + + /* Watchdog reset */ ++ if (devinfo->ci->blhs) ++ devinfo->ci->blhs->init(devinfo->ci); + brcmf_pcie_select_core(devinfo, BCMA_CORE_CHIPCOMMON); + WRITECC32(devinfo, watchdog, 4); + msleep(100); ++ if (devinfo->ci->blhs) ++ if (devinfo->ci->blhs->post_wdreset(devinfo->ci)) ++ return; ++ + + /* Restore ASPM */ + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); +@@ -922,6 +947,9 @@ static void brcmf_pcie_attach(struct brcmf_pciedev_info *devinfo) + + static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) + { ++ struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); ++ int err = 0; ++ + if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) { + brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX, +@@ -933,7 +961,14 @@ static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKPDA, + 0); + } +- return 0; ++ ++ if (devinfo->ci->blhs) { ++ err = devinfo->ci->blhs->prep_fwdl(devinfo->ci); ++ if (err) ++ brcmf_err(bus, "FW download preparation failed"); ++ } ++ ++ return err; + } + + +@@ -947,8 +982,13 @@ static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo, + brcmf_chip_resetcore(core, 0, 0, 0); + } + +- if (!brcmf_chip_set_active(devinfo->ci, resetintr)) +- return -EINVAL; ++ if (devinfo->ci->blhs) { ++ devinfo->ci->blhs->post_nvramdl(devinfo->ci); ++ } else { ++ if (!brcmf_chip_set_active(devinfo->ci, resetintr)) ++ return -EINVAL; ++ } ++ + return 0; + } + +@@ -1846,6 +1886,28 @@ brcmf_pcie_adjust_ramsize(struct brcmf_pciedev_info *devinfo, u8 *data, + } + + ++static void ++brcmf_pcie_write_rand(struct brcmf_pciedev_info *devinfo, u32 nvram_csm) ++{ ++ struct brcmf_rand_metadata rand_data; ++ u8 rand_buf[BRCMF_ENTROPY_HOST_LEN]; ++ u32 count = BRCMF_ENTROPY_HOST_LEN; ++ u32 address; ++ ++ address = devinfo->ci->rambase + ++ (devinfo->ci->ramsize - BRCMF_NVRAM_OFFSET_TCM) - ++ ((nvram_csm & 0xffff) * BRCMF_NVRAM_COMPRS_FACTOR) - ++ sizeof(rand_data); ++ memset(rand_buf, 0, BRCMF_ENTROPY_HOST_LEN); ++ rand_data.signature = cpu_to_le32(BRCMF_NVRAM_RNG_SIGNATURE); ++ rand_data.count = cpu_to_le32(count); ++ brcmf_pcie_copy_mem_todev(devinfo, address, &rand_data, ++ sizeof(rand_data)); ++ address -= count; ++ get_random_bytes(rand_buf, count); ++ brcmf_pcie_copy_mem_todev(devinfo, address, rand_buf, count); ++} ++ + static int + brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, + u32 sharedram_addr) +@@ -1935,6 +1997,8 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + int err; + u32 address; + u32 resetintr; ++ u32 nvram_lenw; ++ u32 nvram_csm; + + brcmf_dbg(PCIE, "Halt ARM.\n"); + err = brcmf_pcie_enter_download_state(devinfo); +@@ -1953,22 +2017,53 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + resetintr = get_unaligned_le32(fw->data); + release_firmware(fw); + +- /* reset last 4 bytes of RAM address. to be used for shared +- * area. This identifies when FW is running +- */ +- brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, 0); ++ if (devinfo->ci->blhs) { ++ err = devinfo->ci->blhs->post_fwdl(devinfo->ci); ++ if (err) { ++ brcmf_err(bus, "FW download failed, err=%d\n", err); ++ return err; ++ } ++ ++ err = devinfo->ci->blhs->chk_validation(devinfo->ci); ++ if (err) { ++ brcmf_err(bus, "FW valication failed, err=%d\n", err); ++ return err; ++ } ++ } else { ++ /* reset last 4 bytes of RAM address. to be used for shared ++ * area. This identifies when FW is running ++ */ ++ brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, 0); ++ } + + if (nvram) { + brcmf_dbg(PCIE, "Download NVRAM %s\n", devinfo->nvram_name); + address = devinfo->ci->rambase + devinfo->ci->ramsize - + nvram_len; +- memcpy_toio(devinfo->tcm + address, nvram, nvram_len); ++ ++ if (devinfo->ci->blhs) ++ address -= 4; ++ brcmf_pcie_copy_mem_todev(devinfo, address, nvram, nvram_len); ++ ++ /* Convert nvram_len to words to determine the length token */ ++ nvram_lenw = nvram_len / 4; ++ nvram_csm = (~nvram_lenw << 16) | (nvram_lenw & 0x0000FFFF); + brcmf_fw_nvram_free(nvram); + } else { ++ nvram_csm = 0; + brcmf_dbg(PCIE, "No matching NVRAM file found %s\n", + devinfo->nvram_name); + } + ++ if (devinfo->ci->chip == CY_CC_55560_CHIP_ID) { ++ /* Write the length token to the last word of RAM address */ ++ brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, ++ cpu_to_le32(nvram_csm)); ++ ++ /* Write random numbers to TCM for randomizing heap address */ ++ brcmf_pcie_write_rand(devinfo, nvram_csm); ++ } ++ + sharedram_addr_written = brcmf_pcie_read_ram32(devinfo, + devinfo->ci->ramsize - + 4); +@@ -2062,6 +2157,21 @@ static void brcmf_pcie_release_resource(struct brcmf_pciedev_info *devinfo) + pci_disable_device(devinfo->pdev); + } + ++static u32 brcmf_pcie_buscore_blhs_read(void *ctx, u32 reg_offset) ++{ ++ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; ++ ++ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); ++ return brcmf_pcie_read_reg32(devinfo, reg_offset); ++} ++ ++static void brcmf_pcie_buscore_blhs_write(void *ctx, u32 reg_offset, u32 value) ++{ ++ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; ++ ++ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); ++ brcmf_pcie_write_reg32(devinfo, reg_offset, value); ++} + + static u32 brcmf_pcie_buscore_prep_addr(const struct pci_dev *pdev, u32 addr) + { +@@ -2127,12 +2237,63 @@ static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip, + } + + ++static int brcmf_pcie_buscore_blhs_attach(void *ctx, struct brcmf_blhs **blhs, ++ u32 flag, uint timeout, uint interval) ++{ ++ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; ++ struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); ++ struct brcmf_blhs *blhsh; ++ u32 regdata; ++ u32 pcie_enum; ++ u32 addr; ++ ++ if (devinfo->pdev->vendor != CY_PCIE_VENDOR_ID_CYPRESS) ++ return 0; ++ ++ pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_CFGREG_REVID, ®data); ++ if (regdata & BRCMF_PCIE_CFGREG_REVID_SECURE_MODE) { ++ blhsh = kzalloc(sizeof(*blhsh), GFP_KERNEL); ++ if (!blhsh) ++ return -ENOMEM; ++ ++ blhsh->d2h = BRCMF_PCIE_PCIE2REG_DAR_D2H_MSG_0; ++ blhsh->h2d = BRCMF_PCIE_PCIE2REG_DAR_H2D_MSG_0; ++ blhsh->read = brcmf_pcie_buscore_blhs_read; ++ blhsh->write = brcmf_pcie_buscore_blhs_write; ++ ++ /* Host indication for bootloarder to start the init */ ++ if (devinfo->pdev->device == CY_PCIE_55560_DEVICE_ID) ++ pcie_enum = BRCMF_CYW55560_PCIE_BAR0_PCIE_ENUM_OFFSET; ++ else ++ pcie_enum = BRCMF_PCIE_BAR0_PCIE_ENUM_OFFSET; ++ ++ pci_read_config_dword(devinfo->pdev, PCI_BASE_ADDRESS_0, ++ ®data); ++ addr = regdata + pcie_enum + blhsh->h2d; ++ brcmf_pcie_buscore_write32(ctx, addr, 0); ++ ++ addr = regdata + pcie_enum + blhsh->d2h; ++ SPINWAIT_MS((brcmf_pcie_buscore_read32(ctx, addr) & flag) == 0, ++ timeout, interval); ++ regdata = brcmf_pcie_buscore_read32(ctx, addr); ++ if (!(regdata & flag)) { ++ brcmf_err(bus, "Timeout waiting for bootloader ready\n"); ++ kfree(blhsh); ++ return -EPERM; ++ } ++ *blhs = blhsh; ++ } ++ ++ return 0; ++} ++ + static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { + .prepare = brcmf_pcie_buscoreprep, + .reset = brcmf_pcie_buscore_reset, + .activate = brcmf_pcie_buscore_activate, + .read32 = brcmf_pcie_buscore_read32, + .write32 = brcmf_pcie_buscore_write32, ++ .blhs_attach = brcmf_pcie_buscore_blhs_attach, + }; + + #define BRCMF_PCIE_FW_CODE 0 +@@ -2245,6 +2406,9 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo) + }; + u32 chip; + ++ if (devinfo->ci->blhs) ++ fwnames[BRCMF_PCIE_FW_CODE].extension = ".trxse"; ++ + chip = devinfo->ci->chip; + fwreq = brcmf_fw_alloc_request(chip, devinfo->ci->chiprev, + brcmf_pcie_fwnames, +@@ -2253,7 +2417,10 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo) + if (!fwreq) + return NULL; + +- fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; ++ if (devinfo->ci->blhs) ++ fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_TRXSE; ++ else ++ fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; + fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; + fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; + fwreq->board_type = devinfo->settings->board_type; +@@ -2625,6 +2792,9 @@ static const struct dev_pm_ops brcmf_pciedrvr_pm = { + BRCM_PCIE_VENDOR_ID_BROADCOM, dev_id,\ + subvend, subdev, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } + ++#define BRCMF_PCIE_DEVICE_CY(dev_id) { CY_PCIE_VENDOR_ID_CYPRESS, dev_id,\ ++ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } ++ + static const struct pci_device_id brcmf_pcie_devid_table[] = { + BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID), + BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355), +@@ -2653,6 +2823,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { + BRCMF_PCIE_DEVICE(CY_PCIE_54591_DEVICE_ID), + BRCMF_PCIE_DEVICE(CY_PCIE_54590_DEVICE_ID), + BRCMF_PCIE_DEVICE(CY_PCIE_54594_DEVICE_ID), ++ BRCMF_PCIE_DEVICE_CY(CY_PCIE_55560_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 61ae748d9125..518661d4f7a1 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -57,8 +57,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_89459_CHIP_ID 0x4355 +- ++#define CY_CC_55560_CHIP_ID 0xd908 + + /* USB Device IDs */ + #define BRCM_USB_43143_DEVICE_ID 0xbd1e +@@ -97,6 +96,7 @@ + #define CY_PCIE_54591_DEVICE_ID 0x4417 + #define CY_PCIE_54590_DEVICE_ID 0x4416 + #define CY_PCIE_54594_DEVICE_ID 0x441a ++#define CY_PCIE_55560_DEVICE_ID 0xbd31 + + /* brcmsmac IDs */ + #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_utils.h +index 946532328667..48791ac87496 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_utils.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_utils.h +@@ -21,6 +21,19 @@ + } \ + } + ++/* Spin at most 'ms' milliseconds with polling interval 'interval' milliseconds ++ * while 'exp' is true. Caller should explicitly test 'exp' when this completes ++ * and take appropriate error action if 'exp' is still true. ++ */ ++#define SPINWAIT_MS(exp, ms, interval) { \ ++ typeof(interval) interval_ = (interval); \ ++ uint countdown = (ms) + (interval_ - 1U); \ ++ while ((exp) && (countdown >= interval_)) { \ ++ msleep(interval_); \ ++ countdown -= interval_; \ ++ } \ ++} ++ + /* osl multi-precedence packet queue */ + #define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ + #define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0104-brcmfmac-add-bootloader-console-buffer-support-for-P.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0104-brcmfmac-add-bootloader-console-buffer-support-for-P.patch new file mode 100644 index 000000000..d0770e905 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0104-brcmfmac-add-bootloader-console-buffer-support-for-P.patch @@ -0,0 +1,152 @@ +From 45881a2ec73125fc378ace0ff4e490924190414e Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Wed, 13 May 2020 20:57:10 -0500 +Subject: [PATCH 104/179] brcmfmac: add bootloader console buffer support for + PCIe + +Console buffer is required for capturing key prints/logs generated by +dongle. This patch adds console buffer support for bootloader handshake +for PCIe. + +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Wright Feng +--- + .../broadcom/brcm80211/brcmfmac/pcie.c | 57 ++++++++++++++++++- + 1 file changed, 54 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index 8048a48cdb93..ce527ab411b0 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -100,6 +100,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + #define BRCMF_PCIE_REV_GE64(dev) (brcmf_chip_get_core((dev)->ci, \ + BCMA_CORE_PCIE2)->rev >= 64) + ++#define BRCMF_PCIE_READ_SHARED_TIMEOUT 5000 /* msec */ + #define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */ + + #define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024) +@@ -433,6 +434,9 @@ static void brcmf_pcie_setup(struct device *dev, int ret, + struct brcmf_fw_request *fwreq); + static struct brcmf_fw_request * + brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo); ++static void brcmf_pcie_bus_console_init(struct brcmf_pciedev_info *devinfo); ++static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo, ++ bool error); + + static void + brcmf_pcie_fwcon_timer(struct brcmf_pciedev_info *devinfo, bool active); +@@ -945,6 +949,34 @@ static void brcmf_pcie_attach(struct brcmf_pciedev_info *devinfo) + } + + ++static int brcmf_pcie_bus_readshared(struct brcmf_pciedev_info *devinfo, ++ u32 nvram_csm) ++{ ++ struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); ++ u32 loop_counter; ++ u32 addr_le; ++ u32 addr = 0; ++ ++ loop_counter = BRCMF_PCIE_READ_SHARED_TIMEOUT / 50; ++ while ((addr == 0 || addr == nvram_csm) && (loop_counter)) { ++ msleep(50); ++ addr_le = brcmf_pcie_read_ram32(devinfo, ++ devinfo->ci->ramsize - 4); ++ addr = le32_to_cpu(addr_le); ++ loop_counter--; ++ } ++ if (addr == 0 || addr == nvram_csm || addr < devinfo->ci->rambase || ++ addr >= devinfo->ci->rambase + devinfo->ci->ramsize) { ++ brcmf_err(bus, "Invalid shared RAM address 0x%08x\n", addr); ++ return -ENODEV; ++ } ++ devinfo->shared.tcm_base_address = addr; ++ brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", addr); ++ ++ brcmf_pcie_bus_console_init(devinfo); ++ return 0; ++} ++ + static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) + { + struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); +@@ -964,8 +996,13 @@ static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) + + if (devinfo->ci->blhs) { + err = devinfo->ci->blhs->prep_fwdl(devinfo->ci); +- if (err) ++ if (err) { + brcmf_err(bus, "FW download preparation failed"); ++ return err; ++ } ++ ++ if (!brcmf_pcie_bus_readshared(devinfo, 0)) ++ brcmf_pcie_bus_console_read(devinfo, false); + } + + return err; +@@ -983,6 +1020,7 @@ static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo, + } + + if (devinfo->ci->blhs) { ++ brcmf_pcie_bus_console_read(devinfo, false); + devinfo->ci->blhs->post_nvramdl(devinfo->ci); + } else { + if (!brcmf_chip_set_active(devinfo->ci, resetintr)) +@@ -1087,6 +1125,7 @@ static void brcmf_pcie_bus_console_init(struct brcmf_pciedev_info *devinfo) + { + struct brcmf_pcie_shared_info *shared; + struct brcmf_pcie_console *console; ++ u32 buf_addr; + u32 addr; + + shared = &devinfo->shared; +@@ -1095,7 +1134,12 @@ static void brcmf_pcie_bus_console_init(struct brcmf_pciedev_info *devinfo) + console->base_addr = brcmf_pcie_read_tcm32(devinfo, addr); + + addr = console->base_addr + BRCMF_CONSOLE_BUFADDR_OFFSET; +- console->buf_addr = brcmf_pcie_read_tcm32(devinfo, addr); ++ buf_addr = brcmf_pcie_read_tcm32(devinfo, addr); ++ /* reset console index when buffer address is updated */ ++ if (console->buf_addr != buf_addr) { ++ console->buf_addr = buf_addr; ++ console->read_idx = 0; ++ } + addr = console->base_addr + BRCMF_CONSOLE_BUFSIZE_OFFSET; + console->bufsize = brcmf_pcie_read_tcm32(devinfo, addr); + +@@ -2018,6 +2062,7 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + release_firmware(fw); + + if (devinfo->ci->blhs) { ++ brcmf_pcie_bus_console_read(devinfo, false); + err = devinfo->ci->blhs->post_fwdl(devinfo->ci); + if (err) { + brcmf_err(bus, "FW download failed, err=%d\n", err); +@@ -2072,6 +2117,9 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + if (err) + return err; + ++ if (!brcmf_pcie_bus_readshared(devinfo, nvram_csm)) ++ brcmf_pcie_bus_console_read(devinfo, false); ++ + brcmf_dbg(PCIE, "Wait for FW init\n"); + sharedram_addr = sharedram_addr_written; + loop_counter = BRCMF_PCIE_FW_UP_TIMEOUT / 50; +@@ -2341,8 +2389,11 @@ static void brcmf_pcie_setup(struct device *dev, int ret, + brcmf_pcie_adjust_ramsize(devinfo, (u8 *)fw->data, fw->size); + + ret = brcmf_pcie_download_fw_nvram(devinfo, fw, nvram, nvram_len); +- if (ret) ++ if (ret) { ++ if (devinfo->ci->blhs && !brcmf_pcie_bus_readshared(devinfo, 0)) ++ brcmf_pcie_bus_console_read(devinfo, true); + goto fail; ++ } + + devinfo->state = BRCMFMAC_PCIE_STATE_UP; + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0105-brcmfmac-support-4373-pcie.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0105-brcmfmac-support-4373-pcie.patch new file mode 100644 index 000000000..5ab8ffe6d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0105-brcmfmac-support-4373-pcie.patch @@ -0,0 +1,62 @@ +From 4491b637f53057f3454a83a737ad0cbe077b5f45 Mon Sep 17 00:00:00 2001 +From: Ian Lin +Date: Mon, 15 Nov 2021 20:07:37 -0600 +Subject: [PATCH 105/179] brcmfmac: support 4373 pcie + +Add 4373 pcie device id + +Signed-off-by: Ian Lin +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 6 ++++++ + .../net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 4 ++++ + 2 files changed, 10 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index ce527ab411b0..1c7dcefafea1 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -65,6 +65,7 @@ BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); + BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); + CY_FW_DEF(4355, "cyfmac54591-pcie"); + CY_FW_TRXSE_DEF(55560, "cyfmac55560-pcie"); ++CY_FW_DEF(4373, "cyfmac4373-pcie"); + + /* firmware config files */ + MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt"); +@@ -95,6 +96,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + 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_55560_CHIP_ID, 0xFFFFFFFF, 55560), ++ BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373), + }; + + #define BRCMF_PCIE_REV_GE64(dev) (brcmf_chip_get_core((dev)->ci, \ +@@ -2875,6 +2877,10 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { + BRCMF_PCIE_DEVICE(CY_PCIE_54590_DEVICE_ID), + BRCMF_PCIE_DEVICE(CY_PCIE_54594_DEVICE_ID), + BRCMF_PCIE_DEVICE_CY(CY_PCIE_55560_DEVICE_ID), ++ BRCMF_PCIE_DEVICE(CY_PCIE_4373_RAW_DEVICE_ID), ++ BRCMF_PCIE_DEVICE(CY_PCIE_4373_DUAL_DEVICE_ID), ++ BRCMF_PCIE_DEVICE(CY_PCIE_4373_2G_DEVICE_ID), ++ BRCMF_PCIE_DEVICE(CY_PCIE_4373_5G_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 518661d4f7a1..9e4daf21887c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -97,6 +97,10 @@ + #define CY_PCIE_54590_DEVICE_ID 0x4416 + #define CY_PCIE_54594_DEVICE_ID 0x441a + #define CY_PCIE_55560_DEVICE_ID 0xbd31 ++#define CY_PCIE_4373_RAW_DEVICE_ID 0x4373 ++#define CY_PCIE_4373_DUAL_DEVICE_ID 0x4418 ++#define CY_PCIE_4373_2G_DEVICE_ID 0x4419 ++#define CY_PCIE_4373_5G_DEVICE_ID 0x441a + + /* brcmsmac IDs */ + #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0106-brcmfmac-extsae-supports-SAE-OKC-roam.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0106-brcmfmac-extsae-supports-SAE-OKC-roam.patch new file mode 100644 index 000000000..a6df12f11 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0106-brcmfmac-extsae-supports-SAE-OKC-roam.patch @@ -0,0 +1,55 @@ +From 79e97b90e4bd8b1750b7995024119e4b31c03fc5 Mon Sep 17 00:00:00 2001 +From: Darren Li +Date: Thu, 25 Nov 2021 22:15:31 -0600 +Subject: [PATCH 106/179] brcmfmac: extsae supports SAE OKC roam + +extsae supports SAE OKC roam + +Signed-off-by: Darren Li Darren.Li@infineon.com +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 22 +++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index aea1d57ea218..adbc5212c4f4 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2157,6 +2157,17 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + brcmf_dbg(INFO, "get okc_enable (%d)\n", okc_enable); + profile->is_okc = okc_enable; + } ++ } else if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE && ++ (val == WPA3_AUTH_SAE_PSK)) { ++ brcmf_dbg(INFO, "not using SAE 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)) +@@ -4358,6 +4369,17 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, + + err = brcmf_update_pmklist(cfg, ifp); + ++ if (pmksa->pmk_len) { ++ if (ifp->vif->profile.is_okc) { ++ err = brcmf_fil_iovar_data_set(ifp, "okc_info_pmk", pmksa->pmk, ++ pmksa->pmk_len); ++ if (err < 0) ++ bphy_err(drvr, "okc_info_pmk iovar failed: ret=%d\n", err); ++ } else { ++ brcmf_set_pmk(ifp, pmksa->pmk, pmksa->pmk_len); ++ } ++ } ++ + brcmf_dbg(TRACE, "Exit\n"); + return err; + } +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0107-nl80211-add-roaming-offload-support.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0107-nl80211-add-roaming-offload-support.patch new file mode 100644 index 000000000..10f5cbbbb --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0107-nl80211-add-roaming-offload-support.patch @@ -0,0 +1,44 @@ +From 30d41451716f2f47214c6d18633941a29f4d20b3 Mon Sep 17 00:00:00 2001 +From: Carella Chen +Date: Thu, 18 Nov 2021 03:28:47 -0600 +Subject: [PATCH 107/179] nl80211: add roaming offload support + +Add NL80211_EXT_FEATURE_ROAM_OFFLOAD for roaming offload support. + +Signed-off-by: Carella Chen + +--- + include/uapi/linux/nl80211.h | 1 + + net/wireless/nl80211.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h +index 560f54bb492c..ee80ae025b44 100644 +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -6063,6 +6063,7 @@ enum nl80211_ext_feature_index { + NL80211_EXT_FEATURE_SECURE_RTT, + NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, + NL80211_EXT_FEATURE_BSS_COLOR, ++ NL80211_EXT_FEATURE_ROAM_OFFLOAD, + + /* add new features before the definition below */ + NUM_NL80211_EXT_FEATURES, +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 4e200f640a3b..a753c96c3659 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -14369,7 +14369,9 @@ static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info) + return -EOPNOTSUPP; + + if (!wiphy_ext_feature_isset(&rdev->wiphy, +- NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X)) ++ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X) && ++ !wiphy_ext_feature_isset(&rdev->wiphy, ++ NL80211_EXT_FEATURE_ROAM_OFFLOAD)) + return -EOPNOTSUPP; + + if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK]) +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0108-brcm80211-add-FT-11r-OKC-roaming-offload-support.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0108-brcm80211-add-FT-11r-OKC-roaming-offload-support.patch new file mode 100644 index 000000000..554282776 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0108-brcm80211-add-FT-11r-OKC-roaming-offload-support.patch @@ -0,0 +1,142 @@ +From 1895aa97bbcb983e7e412a9741946ef4c03bed44 Mon Sep 17 00:00:00 2001 +From: Carella Chen +Date: Thu, 18 Nov 2021 03:31:46 -0600 +Subject: [PATCH 108/179] brcm80211: add FT(11r) / OKC roaming offload support + +Add roaming offload support for FT and OKC scenarios. + +Signed-off-by: Carella Chen + +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 23 +++++++++++++++---- + .../broadcom/brcm80211/brcmfmac/cfg80211.h | 3 ++- + .../broadcom/brcm80211/brcmfmac/feature.c | 2 ++ + .../broadcom/brcm80211/brcmfmac/feature.h | 4 +++- + 4 files changed, 26 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index adbc5212c4f4..c078fabed5bd 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2077,6 +2077,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + val = WPA_AUTH_UNSPECIFIED; + if (sme->want_1x) + profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X; ++ else ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_ROAM; + break; + case WLAN_AKM_SUITE_PSK: + val = WPA_AUTH_PSK; +@@ -2092,11 +2094,15 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + val = WPA2_AUTH_UNSPECIFIED; + if (sme->want_1x) + profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X; ++ else ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_ROAM; + break; + case WLAN_AKM_SUITE_8021X_SHA256: + val = WPA2_AUTH_1X_SHA256; + if (sme->want_1x) + profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X; ++ else ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_ROAM; + break; + case WLAN_AKM_SUITE_PSK_SHA256: + val = WPA2_AUTH_PSK_SHA256; +@@ -2109,6 +2115,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + profile->is_ft = true; + if (sme->want_1x) + profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X; ++ else ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_ROAM; + break; + case WLAN_AKM_SUITE_FT_PSK: + val = WPA2_AUTH_PSK | WPA2_AUTH_FT; +@@ -2147,7 +2155,8 @@ 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) || ++ (profile->use_fwsup == BRCMF_PROFILE_FWSUP_ROAM)) { + brcmf_dbg(INFO, "using 1X offload\n"); + err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "okc_enable", + &okc_enable); +@@ -5989,7 +5998,9 @@ static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev, + /* 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)) ++ if (WARN_ON((ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X) && ++ (ifp->vif->profile.is_ft != true) && ++ (ifp->vif->profile.is_okc != true))) + return -EINVAL; + + if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN) +@@ -6607,7 +6618,8 @@ 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 && ++ if ((profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X || ++ profile->use_fwsup == BRCMF_PROFILE_FWSUP_ROAM) && + (brcmf_has_pmkid(roam_info.req_ie, roam_info.req_ie_len) || + profile->is_ft || profile->is_okc)) + roam_info.authorized = true; +@@ -8033,7 +8045,10 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + wiphy_ext_feature_set(wiphy, + NL80211_EXT_FEATURE_AP_PMKSA_CACHING); + } +- ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FBT) || ++ brcmf_feat_is_enabled(ifp, BRCMF_FEAT_OKC)) ++ wiphy_ext_feature_set(wiphy, ++ NL80211_EXT_FEATURE_ROAM_OFFLOAD); + 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 cb1455059d84..95713e78f2f7 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -134,7 +134,8 @@ enum brcmf_profile_fwsup { + BRCMF_PROFILE_FWSUP_NONE, + BRCMF_PROFILE_FWSUP_PSK, + BRCMF_PROFILE_FWSUP_1X, +- BRCMF_PROFILE_FWSUP_SAE ++ BRCMF_PROFILE_FWSUP_SAE, ++ BRCMF_PROFILE_FWSUP_ROAM + }; + + /** +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +index f0c603ba64b8..f6e1f664c595 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -43,6 +43,8 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = { + { BRCMF_FEAT_SAE, "sae " }, + { BRCMF_FEAT_FWAUTH, "idauth" }, + { BRCMF_FEAT_SAE_EXT, "sae_ext " }, ++ { BRCMF_FEAT_FBT, "fbt " }, ++ { BRCMF_FEAT_OKC, "okc" }, + }; + + #ifdef DEBUG +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +index bc6753e928f4..6f9f9e0b60b5 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +@@ -55,7 +55,9 @@ + BRCMF_FEAT_DEF(SAE) \ + BRCMF_FEAT_DEF(FWAUTH) \ + BRCMF_FEAT_DEF(DUMP_OBSS) \ +- BRCMF_FEAT_DEF(SAE_EXT) ++ BRCMF_FEAT_DEF(SAE_EXT) \ ++ BRCMF_FEAT_DEF(FBT) \ ++ BRCMF_FEAT_DEF(OKC) + + /* + * Quirks: +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0109-brcmfmac-support-extsae-with-psk-1x-offloading.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0109-brcmfmac-support-extsae-with-psk-1x-offloading.patch new file mode 100644 index 000000000..eeb495eff --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0109-brcmfmac-support-extsae-with-psk-1x-offloading.patch @@ -0,0 +1,51 @@ +From 0eb94725c3adb88c048285e9eff933bc870baeb3 Mon Sep 17 00:00:00 2001 +From: Chien-Chia Chen +Date: Thu, 18 Nov 2021 03:22:26 -0600 +Subject: [PATCH 109/179] brcmfmac: support extsae with psk / 1x offloading + +support sae executed in wpa_supplicant and offload 4-way handshake offload. + +Signed-off-by: Chien-Chia Chen + +--- + .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index c078fabed5bd..69f0ea8ab2c3 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2138,6 +2138,10 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + if (sme->crypto.sae_pwd) { + brcmf_dbg(INFO, "using SAE offload\n"); + profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE; ++ } else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP) && ++ brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE_EXT)) { ++ brcmf_dbg(INFO, "using EXTSAE with PSK offload\n"); ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK; + } + break; + case WLAN_AKM_SUITE_FT_OVER_SAE: +@@ -2463,7 +2467,8 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, + + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) { + if (sme->crypto.psk) { +- if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) { ++ if ((profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) && ++ (profile->use_fwsup != BRCMF_PROFILE_FWSUP_PSK)) { + if (WARN_ON(profile->use_fwsup != + BRCMF_PROFILE_FWSUP_NONE)) { + err = -EINVAL; +@@ -2485,7 +2490,8 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, + err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 0); + } + +- if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK) ++ if ((profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK) && ++ sme->crypto.psk) + err = brcmf_set_pmk(ifp, sme->crypto.psk, + BRCMF_WSEC_MAX_PSK_LEN); + else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) { +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0110-Disable-out-of-band-device-wake-based-DeepSleep-Stat.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0110-Disable-out-of-band-device-wake-based-DeepSleep-Stat.patch new file mode 100644 index 000000000..af78f32fa --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0110-Disable-out-of-band-device-wake-based-DeepSleep-Stat.patch @@ -0,0 +1,55 @@ +From c706811405c23dfcecdddfd5689d673601f3c383 Mon Sep 17 00:00:00 2001 +From: Wright Feng +Date: Wed, 5 Jan 2022 22:56:09 -0600 +Subject: [PATCH 110/179] Disable out-of-band device wake based DeepSleep State + Machine + +The out-of-band device wake is not supported in host side, so we disable +it via host cap if PCIE shared version is >= 6. This change also reduces +7.9mA current consumption in VBAT a(8.0mA to 0.1mA) fter loading the +driver in PM2 state. +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index 1c7dcefafea1..a1332df9d495 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -241,7 +241,8 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + + #define BRCMF_DEF_MAX_RXBUFPOST 255 + +-#define BRCMF_H2D_ENABLE_HOSTRDY 0x400 ++#define BRCMF_HOSTCAP_H2D_ENABLE_HOSTRDY 0x400 ++#define BRCMF_HOSTCAP_DS_NO_OOB_DW 0x1000 + + #define BRCMF_CONSOLE_BUFADDR_OFFSET 8 + #define BRCMF_CONSOLE_BUFSIZE_OFFSET 12 +@@ -2004,18 +2005,22 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, + if (shared->version >= BRCMF_PCIE_SHARED_VERSION_6) { + host_cap = shared->version; + ++ /* Disable OOB Device Wake based DeepSleep State Machine */ ++ host_cap |= BRCMF_HOSTCAP_DS_NO_OOB_DW; ++ + 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; ++ host_cap |= BRCMF_HOSTCAP_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; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0111-brcmfmac-Improve-the-delay-during-scan.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0111-brcmfmac-Improve-the-delay-during-scan.patch new file mode 100644 index 000000000..b267901ed --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0111-brcmfmac-Improve-the-delay-during-scan.patch @@ -0,0 +1,34 @@ +From f9989debd4c9816e768b2bc2232e87490b588121 Mon Sep 17 00:00:00 2001 +From: Kurt Lee +Date: Tue, 18 Jan 2022 21:57:37 -0600 +Subject: [PATCH 111/179] brcmfmac: Improve the delay during scan + +wpa_supplicant sends NL80211_CMD_GET_SURVEY command every after normal +scan, which causes brcmfmac surveying each channel again. + +Currently brcmfmac implments brcmf_cfg80211_dump_survey focusing on AP +mode, thus this change will return the request other than AP mode. + +Signed-off-by: Kurt Lee + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 69f0ea8ab2c3..8ef6032b37c4 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -8483,6 +8483,9 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, + + brcmf_dbg(TRACE, "Enter: channel idx=%d\n", idx); + ++ if (!brcmf_is_apmode(ifp->vif)) ++ return -ENOENT; ++ + /* 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))) { +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0112-brcmfmac-skip-6G-oob-scan-report.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0112-brcmfmac-skip-6G-oob-scan-report.patch new file mode 100644 index 000000000..43901931f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0112-brcmfmac-skip-6G-oob-scan-report.patch @@ -0,0 +1,47 @@ +From 47c6706338cedbba7a5fd3f6d25ec407d161db7c Mon Sep 17 00:00:00 2001 +From: Ian Lin +Date: Thu, 6 Jan 2022 21:15:23 -0600 +Subject: [PATCH 112/179] brcmfmac: skip 6G oob scan report + +WAR to skip 6G oob scan report before host could support 6E. + +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 ++++++++ + .../net/wireless/broadcom/brcm80211/include/brcmu_d11.h | 2 +- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 8ef6032b37c4..9bc23fbc3c92 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3670,6 +3670,14 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, + } + bss_info_le = &escan_result_le->bss_info_le; + ++ /* WAR to skip 6G scan results before 6E support is complete in host */ ++ if ((bss_info_le->chanspec & BRCMU_CHSPEC_D11AC_BND_MASK) == ++ BRCMU_CHSPEC_D11AC_BND_6G) { ++ bphy_err(drvr, "Currently skip 6G scan, chanspec 0x%04x\n", ++ bss_info_le->chanspec); ++ goto exit; ++ } ++ + if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le)) + goto exit; + +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h +index f6344023855c..9a54a046a795 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h +@@ -82,7 +82,7 @@ + #define BRCMU_CHSPEC_D11AC_BND_SHIFT 14 + #define BRCMU_CHSPEC_D11AC_BND_2G 0x0000 + #define BRCMU_CHSPEC_D11AC_BND_3G 0x4000 +-#define BRCMU_CHSPEC_D11AC_BND_4G 0x8000 ++#define BRCMU_CHSPEC_D11AC_BND_6G 0x8000 + #define BRCMU_CHSPEC_D11AC_BND_5G 0xc000 + + #define BRCMU_CHAN_BAND_2G 0 +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0113-Revert-brcmfmac-Improve-the-delay-during-scan.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0113-Revert-brcmfmac-Improve-the-delay-during-scan.patch new file mode 100644 index 000000000..b2daa320b --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0113-Revert-brcmfmac-Improve-the-delay-during-scan.patch @@ -0,0 +1,29 @@ +From 9d0a72ab9aebdfb89bc38259b6c7715be2ac6e4c Mon Sep 17 00:00:00 2001 +From: Kurt Lee +Date: Wed, 26 Jan 2022 03:27:41 -0600 +Subject: [PATCH 113/179] Revert "brcmfmac: Improve the delay during scan" + +This reverts commit df4722113f8d542e6f72ed5bddff639a487a7ba5. +After reviewed code, this change may affect auto channel selection in AP +mode, so revert this commit first and searching for better solution. +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 9bc23fbc3c92..63bdb5115237 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -8491,9 +8491,6 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, + + brcmf_dbg(TRACE, "Enter: channel idx=%d\n", idx); + +- if (!brcmf_is_apmode(ifp->vif)) +- return -ENOENT; +- + /* 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))) { +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0114-brcmfmac-Improve-the-delay-during-scan.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0114-brcmfmac-Improve-the-delay-during-scan.patch new file mode 100644 index 000000000..74419d499 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0114-brcmfmac-Improve-the-delay-during-scan.patch @@ -0,0 +1,34 @@ +From d09b32e7b4c1dcc5919ef757a0e20ed29135e181 Mon Sep 17 00:00:00 2001 +From: Kurt Lee +Date: Tue, 18 Jan 2022 21:57:37 -0600 +Subject: [PATCH 114/179] brcmfmac: Improve the delay during scan + +wpa_supplicant sends NL80211_CMD_GET_SURVEY command every after normal +scan, which causes brcmfmac surveying each channel again. + +Currently brcmfmac implments brcmf_cfg80211_dump_survey focusing on AP +mode, thus this change will return the request other than AP mode. + +Signed-off-by: Kurt Lee + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 63bdb5115237..9bc23fbc3c92 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -8491,6 +8491,9 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, + + brcmf_dbg(TRACE, "Enter: channel idx=%d\n", idx); + ++ if (!brcmf_is_apmode(ifp->vif)) ++ return -ENOENT; ++ + /* 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))) { +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0115-brcmfmac-add-FW-AP-selection-mod-param.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0115-brcmfmac-add-FW-AP-selection-mod-param.patch new file mode 100644 index 000000000..7637765c9 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0115-brcmfmac-add-FW-AP-selection-mod-param.patch @@ -0,0 +1,193 @@ +From 2e7a5f62fa1ea2c06e7b5b39f675a344cc82832e Mon Sep 17 00:00:00 2001 +From: Suresh Sanaboina +Date: Fri, 11 Feb 2022 07:25:48 -0600 +Subject: [PATCH 115/179] brcmfmac: add FW AP selection mod param + +wpa_supplicant provides bssid_hint & freq_hint which can be used +by the firmware. fw_ap_select variable determines whether FW selects +the AP or the user space selects the target AP within the given ESS. + + +Signed-off-by: Suresh Sanaboina +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 90 +++++++++++++++++-- + .../broadcom/brcm80211/brcmfmac/common.c | 5 ++ + .../broadcom/brcm80211/brcmfmac/common.h | 2 + + 3 files changed, 92 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 9bc23fbc3c92..028873bfee04 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -39,6 +39,7 @@ + #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */ + #define WME_OUI_TYPE 2 + #define WPS_OUI_TYPE 4 ++#define WFA_OUI_TYPE_MBO_OCE 0x16 + + #define VS_IE_FIXED_HDR_LEN 6 + #define WPA_IE_VERSION_LEN 2 +@@ -314,6 +315,41 @@ struct wl_interface_create_v3 { + u8 data[]; /* Optional for specific data */ + }; + ++static bool ++wl_cfgoce_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len, ++ const u8 *oui, u32 oui_len, u8 type); ++ ++/* Check whether the given IE looks like WFA OCE IE. */ ++#define wl_cfgoce_is_oce_ie(ie, tlvs, len) \ ++ wl_cfgoce_has_ie(ie, tlvs, len, \ ++ (const u8 *)WFA_OUI, TLV_OUI_LEN, WFA_OUI_TYPE_MBO_OCE) ++ ++/* Is any of the tlvs the expected entry? If ++ * not update the tlvs buffer pointer/length. ++ */ ++static bool ++wl_cfgoce_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len, ++ const u8 *oui, u32 oui_len, u8 type) ++{ ++ /* If the contents match the OUI and the type */ ++ if (ie[TLV_LEN_OFF] >= oui_len + 1 && ++ !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) && ++ type == ie[TLV_BODY_OFF + oui_len]) { ++ return true; ++ } ++ ++ if (!tlvs) ++ return false; ++ /* point to the next ie */ ++ ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN; ++ /* calculate the length of the rest of the buffer */ ++ *tlvs_len -= (int)(ie - *tlvs); ++ /* update the pointer to the start of the buffer */ ++ *tlvs = ie; ++ ++ return false; ++} ++ + static u8 nl80211_band_to_fwil(enum nl80211_band band) + { + switch (band) { +@@ -2353,6 +2389,43 @@ static void brcmf_set_join_pref(struct brcmf_if *ifp, + bphy_err(drvr, "Set join_pref error (%d)\n", err); + } + ++static bool ++wl_cfg80211_is_oce_ap(struct brcmf_if *ifp, ++ struct wiphy *wiphy, const u8 *bssid_hint) ++{ ++ struct brcmf_pub *drvr = ifp->drvr; ++ const struct brcmf_tlv *ie; ++ const struct cfg80211_bss_ies *ies; ++ struct cfg80211_bss *bss; ++ const u8 *parse = NULL; ++ u32 len; ++ ++ bss = cfg80211_get_bss(wiphy, NULL, bssid_hint, 0, 0, ++ IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); ++ if (!bss) { ++ bphy_err(drvr, "Unable to find AP in the cache"); ++ return false; ++ } ++ ++ if (rcu_access_pointer(bss->ies)) { ++ ies = rcu_access_pointer(bss->ies); ++ parse = ies->data; ++ len = ies->len; ++ } else { ++ bphy_err(drvr, "ies is NULL"); ++ return false; ++ } ++ ++ while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) { ++ if (wl_cfgoce_is_oce_ie((const u8 *)ie, ++ (u8 const **)&parse, &len) == true) { ++ return true; ++ } ++ } ++ brcmf_dbg(TRACE, "OCE IE NOT found"); ++ return false; ++} ++ + static s32 + brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_connect_params *sme) +@@ -2372,6 +2445,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, + u16 chanspec; + s32 err = 0; + u32 ssid_len; ++ bool skip_hints = ifp->drvr->settings->fw_ap_select; + + brcmf_dbg(TRACE, "Enter\n"); + if (!check_vif_up(ifp->vif)) +@@ -2382,12 +2456,18 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, + return -EOPNOTSUPP; + } + +- if (sme->channel_hint) { +- chan = sme->channel_hint; +- } ++ /* override bssid_hint for oce networks */ ++ skip_hints = (skip_hints && ++ wl_cfg80211_is_oce_ap(ifp, wiphy, sme->bssid_hint)); ++ if (skip_hints) { ++ /* Let fw choose the best AP */ ++ brcmf_dbg(TRACE, "Skipping bssid & channel hint\n"); ++ } else { ++ if (sme->channel_hint) ++ chan = sme->channel_hint; + +- if (sme->bssid_hint) { +- sme->bssid = sme->bssid_hint; ++ if (sme->bssid_hint) ++ sme->bssid = sme->bssid_hint; + } + + if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +index 32b67f20fb67..dc45e2a7cf92 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -85,6 +85,10 @@ module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0); + MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); + #endif + ++static int brcmf_fw_ap_select; ++module_param_named(fw_ap_select, brcmf_fw_ap_select, int, 0400); ++MODULE_PARM_DESC(fw_ap_select, "Allow FW for AP selection"); ++ + static struct brcmfmac_platform_data *brcmfmac_pdata; + struct brcmf_mp_global_t brcmf_mp_global; + +@@ -485,6 +489,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, + #ifdef DEBUG + settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; + #endif ++ settings->fw_ap_select = !!brcmf_fw_ap_select; + + if (bus_type == BRCMF_BUSTYPE_SDIO) + settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +index a86d23acd207..d9f740a3e4e7 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -40,6 +40,7 @@ extern struct brcmf_mp_global_t brcmf_mp_global; + * @eap_restrict: Not allow data tx/rx until 802.1X auth succeeds + * @default_pm: default power management (PM) mode. + * @ignore_probe_fail: Ignore probe failure. ++ * @fw_ap_select: Allow FW to select AP. + * @country_codes: If available, pointer to struct for translating country codes + * @bus: Bus specific platform data. Only SDIO at the mmoment. + */ +@@ -52,6 +53,7 @@ struct brcmf_mp_device { + bool eap_restrict; + int default_pm; + bool ignore_probe_fail; ++ bool fw_ap_select; + struct brcmfmac_pd_cc *country_codes; + const char *board_type; + union { +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0116-Changing-info-messages-under-debug-BRCMF_INFO_VAL.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0116-Changing-info-messages-under-debug-BRCMF_INFO_VAL.patch new file mode 100644 index 000000000..0e19aad30 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0116-Changing-info-messages-under-debug-BRCMF_INFO_VAL.patch @@ -0,0 +1,53 @@ +From 6a8a0cc9b8d8c25b586e0c0e296096946b09aca3 Mon Sep 17 00:00:00 2001 +From: Prasanna Kerekoppa +Date: Wed, 23 Feb 2022 00:52:47 -0600 +Subject: [PATCH 116/179] Changing info messages under debug BRCMF_INFO_VAL. + +Signed-off-by: Prasanna's avatarPrasanna Kerekoppa +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 028873bfee04..55dd059446d3 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -672,7 +672,7 @@ static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr) + &iface_v1, + sizeof(iface_v1)); + if (err) { +- brcmf_info("failed to create interface(v1), err=%d\n", ++ brcmf_dbg(INFO, "failed to create interface(v1), err=%d\n", + err); + } else { + brcmf_dbg(INFO, "interface created(v1)\n"); +@@ -693,7 +693,7 @@ static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr) + &iface_v2, + sizeof(iface_v2)); + if (err) { +- brcmf_info("failed to create interface(v2), err=%d\n", ++ brcmf_dbg(INFO, "failed to create interface(v2), err=%d\n", + err); + } else { + brcmf_dbg(INFO, "interface created(v2)\n"); +@@ -767,7 +767,7 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) + &iface_v1, + sizeof(iface_v1)); + if (err) { +- brcmf_info("failed to create interface(v1), err=%d\n", ++ brcmf_dbg(INFO, "failed to create interface(v1), err=%d\n", + err); + } else { + brcmf_dbg(INFO, "interface created(v1)\n"); +@@ -786,7 +786,7 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) + &iface_v2, + sizeof(iface_v2)); + if (err) { +- brcmf_info("failed to create interface(v2), err=%d\n", ++ brcmf_dbg(INFO, "failed to create interface(v2), err=%d\n", + err); + } else { + brcmf_dbg(INFO, "interface created(v2)\n"); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0117-revert-brcmfmac-Set-timeout-value-when-configuring-p.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0117-revert-brcmfmac-Set-timeout-value-when-configuring-p.patch new file mode 100644 index 000000000..69cfab613 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0117-revert-brcmfmac-Set-timeout-value-when-configuring-p.patch @@ -0,0 +1,41 @@ +From 827a6d07f6f327cef9b364a8db8619fa1454fa28 Mon Sep 17 00:00:00 2001 +From: Ian Lin +Date: Mon, 14 Mar 2022 20:55:22 -0500 +Subject: [PATCH 117/179] revert "brcmfmac: Set timeout value when configuring + power save" + +This timeout value is the time STA stay awake before enter sleep. +Remove setting 2s and use fw default value 200ms +for better current consumption. +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 55dd059446d3..6a5fd621182a 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -89,8 +89,6 @@ + + #define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000) + +-#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) + +@@ -3398,11 +3396,6 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, + bphy_err(drvr, "error (%d)\n", err); + } + +- err = brcmf_fil_iovar_int_set(ifp, "pm2_sleep_ret", +- min_t(u32, timeout, BRCMF_PS_MAX_TIMEOUT_MS)); +- if (err) +- bphy_err(drvr, "Unable to set pm timeout, (%d)\n", err); +- + done: + brcmf_dbg(TRACE, "Exit\n"); + return err; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0118-brcmfmac-fixes-scan-invalid-channel-when-enable-host.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0118-brcmfmac-fixes-scan-invalid-channel-when-enable-host.patch new file mode 100644 index 000000000..5b954cc49 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0118-brcmfmac-fixes-scan-invalid-channel-when-enable-host.patch @@ -0,0 +1,121 @@ +From 4cd7f6e641e7e840caed63238486bc4aa745164d Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Fri, 25 Mar 2022 02:28:15 -0500 +Subject: [PATCH 118/179] brcmfmac: fixes scan invalid channel, when enable + hostapd + +The channels setting is restored unexpectedly cause by cfg80211 +regulatory restore mechanism. Remove disabled channels and make +sure the wiphybands is set during the interface up can solved the +issue. + +Signed-off-by: JasonHuang +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 41 ++++++++++++++++++- + .../broadcom/brcm80211/brcmfmac/common.c | 4 +- + 2 files 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 6a5fd621182a..46cb5c146f30 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -313,6 +313,7 @@ struct wl_interface_create_v3 { + u8 data[]; /* Optional for specific data */ + }; + ++static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg); + static bool + wl_cfgoce_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len, + const u8 *oui, u32 oui_len, u8 type); +@@ -1348,6 +1349,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, + ndev->ieee80211_ptr->iftype = type; + + brcmf_cfg80211_update_proto_addr_mode(&vif->wdev); ++ brcmf_setup_wiphybands(cfg); + + done: + brcmf_dbg(TRACE, "Exit\n"); +@@ -7411,14 +7413,14 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + struct brcmf_pub *drvr = cfg->pub; + struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); + struct ieee80211_supported_band *band; +- struct ieee80211_channel *channel; ++ struct ieee80211_channel *channel, *cur, *next; + struct brcmf_chanspec_list *list; + struct brcmu_chan ch; + int err; + u8 *pbuf; + u32 i, j; + u32 total; +- u32 chaninfo; ++ u32 chaninfo, n_2g = 0, n_5g = 0; + + pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); + +@@ -7527,6 +7529,40 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + } + } + ++ /* Remove disabled channels to avoid unexpected restore. */ ++ band = wiphy->bands[NL80211_BAND_2GHZ]; ++ if (band) { ++ n_2g = band->n_channels; ++ for (i = 0; i < band->n_channels; i++) { ++ cur = &band->channels[i]; ++ if (cur->flags == IEEE80211_CHAN_DISABLED) { ++ for (j = i; j < n_2g - 1; j++) { ++ cur = &band->channels[j]; ++ next = &band->channels[j + 1]; ++ memcpy(cur, next, sizeof(*cur)); ++ } ++ n_2g--; ++ } ++ } ++ wiphy->bands[NL80211_BAND_2GHZ]->n_channels = n_2g; ++ } ++ band = wiphy->bands[NL80211_BAND_5GHZ]; ++ if (band) { ++ n_5g = band->n_channels; ++ for (i = 0; i < band->n_channels; i++) { ++ cur = &band->channels[i]; ++ if (cur->flags == IEEE80211_CHAN_DISABLED) { ++ for (j = i; j < n_5g - 1; j++) { ++ cur = &band->channels[j]; ++ next = &band->channels[j + 1]; ++ memcpy(cur, next, sizeof(*cur)); ++ } ++ n_5g--; ++ } ++ } ++ wiphy->bands[NL80211_BAND_5GHZ]->n_channels = n_5g; ++ } ++ + fail_pbuf: + kfree(pbuf); + return err; +@@ -8291,6 +8327,7 @@ static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp) + the state fw and WPA_Supplicant state consistent + */ + brcmf_delay(500); ++ cfg->dongle_up = false; + } + + brcmf_abort_scanning(cfg); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +index dc45e2a7cf92..6e4a1d12b06e 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -395,7 +395,9 @@ 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); +- ++ err = brcmf_fil_iovar_int_set(ifp, "chanspec", 0x1001); ++ if (err < 0) ++ bphy_err(drvr, "Initial Channel failed %d\n", err); + /* add unicast packet filter */ + err = brcmf_pktfilter_add_remove(ifp->ndev, + BRCMF_UNICAST_FILTER_NUM, true); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0119-brcmfmac-do-not-disable-controller-in-apmode-stop.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0119-brcmfmac-do-not-disable-controller-in-apmode-stop.patch new file mode 100644 index 000000000..dcbd3eda1 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0119-brcmfmac-do-not-disable-controller-in-apmode-stop.patch @@ -0,0 +1,37 @@ +From a436ad4eba50e0eeecd0da11eee9a1b9f8c23321 Mon Sep 17 00:00:00 2001 +From: Ian Lin +Date: Thu, 31 Mar 2022 01:10:38 -0500 +Subject: [PATCH 119/179] brcmfmac: do not disable controller in apmode stop + +Wpa_supplicant will firstly call scan before start apmode. +In mbss case, controller will be disabled during stop apmode +so next time start apmpde will fail. +Fix by removing the disable flow. + +Signed-off-by: Ian Lin + + + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 46cb5c146f30..d0318ae360bf 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5473,11 +5473,6 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) + return 0; + } + +- if (ifp->vif->mbss) { +- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); +- return err; +- } +- + /* First BSS doesn't get a full reset */ + if (ifp->bsscfgidx == 0) + brcmf_fil_iovar_int_set(ifp, "closednet", 0); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0120-brcmfmac-support-11ax-and-6G-band.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0120-brcmfmac-support-11ax-and-6G-band.patch new file mode 100644 index 000000000..8ebad701f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0120-brcmfmac-support-11ax-and-6G-band.patch @@ -0,0 +1,904 @@ +From 740654442edccfa7a86218656d92e6ff028661e3 Mon Sep 17 00:00:00 2001 +From: "Lin Ian (CSSITB CSS ICW SW WFS)" +Date: Mon, 25 Apr 2022 02:40:06 +0000 +Subject: [PATCH 120/179] brcmfmac: support 11ax and 6G band + +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 244 +++++++++++++----- + .../broadcom/brcm80211/brcmfmac/p2p.c | 104 ++++---- + .../broadcom/brcm80211/brcmfmac/p2p.h | 5 +- + .../broadcom/brcm80211/brcmutil/d11.c | 19 +- + .../broadcom/brcm80211/include/brcmu_d11.h | 13 +- + .../broadcom/brcm80211/include/brcmu_wifi.h | 3 +- + 6 files changed, 263 insertions(+), 125 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index d0318ae360bf..107509118bc1 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -79,8 +79,10 @@ + #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */ + #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */ + +-#define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320 +-#define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400 ++#define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320 ++#define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400 ++#define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS_6E 80 ++#define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS_6E 130 + #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20 + + #define BRCMF_SCAN_CHANNEL_TIME 40 +@@ -179,6 +181,14 @@ static struct ieee80211_rate __wl_rates[] = { + .max_power = 30, \ + } + ++#define CHAN6G(_channel) { \ ++ .band = NL80211_BAND_6GHZ, \ ++ .center_freq = 5950 + (5 * (_channel)), \ ++ .hw_value = (_channel), \ ++ .max_antenna_gain = 0, \ ++ .max_power = 30, \ ++} ++ + static struct ieee80211_channel __wl_2ghz_channels[] = { + CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427), + CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447), +@@ -195,6 +205,23 @@ static struct ieee80211_channel __wl_5ghz_channels[] = { + CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165) + }; + ++static struct ieee80211_channel __wl_6ghz_channels[] = { ++ CHAN6G(1), CHAN6G(5), CHAN6G(9), CHAN6G(13), CHAN6G(17), ++ CHAN6G(21), CHAN6G(25), CHAN6G(29), CHAN6G(33), CHAN6G(37), ++ CHAN6G(41), CHAN6G(45), CHAN6G(49), CHAN6G(53), CHAN6G(57), ++ CHAN6G(61), CHAN6G(65), CHAN6G(69), CHAN6G(73), CHAN6G(77), ++ CHAN6G(81), CHAN6G(85), CHAN6G(89), CHAN6G(93), CHAN6G(97), ++ CHAN6G(101), CHAN6G(105), CHAN6G(109), CHAN6G(113), CHAN6G(117), ++ CHAN6G(121), CHAN6G(125), CHAN6G(129), CHAN6G(133), CHAN6G(137), ++ CHAN6G(141), CHAN6G(145), CHAN6G(149), CHAN6G(153), CHAN6G(157), ++ CHAN6G(161), CHAN6G(165), CHAN6G(169), CHAN6G(173), CHAN6G(177), ++ CHAN6G(181), CHAN6G(185), CHAN6G(189), CHAN6G(193), CHAN6G(197), ++ CHAN6G(201), CHAN6G(205), CHAN6G(209), CHAN6G(213), CHAN6G(217), ++ CHAN6G(221), CHAN6G(225), CHAN6G(229), CHAN6G(233) ++}; ++ ++struct ieee80211_sband_iftype_data sdata[NUM_NL80211_BANDS]; ++ + /* Band templates duplicated per wiphy. The channel info + * above is added to the band during setup. + */ +@@ -210,6 +237,12 @@ static const struct ieee80211_supported_band __wl_band_5ghz = { + .n_bitrates = wl_a_rates_size, + }; + ++static struct ieee80211_supported_band __wl_band_6ghz = { ++ .band = NL80211_BAND_6GHZ, ++ .bitrates = wl_a_rates, ++ .n_bitrates = wl_a_rates_size, ++}; ++ + /* This is to override regulatory domains defined in cfg80211 module (reg.c) + * By default world regulatory domain defined in reg.c puts the flags + * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165). +@@ -218,7 +251,7 @@ static const struct ieee80211_supported_band __wl_band_5ghz = { + * domain are to be done here. + */ + static const struct ieee80211_regdomain brcmf_regdom = { +- .n_reg_rules = 4, ++ .n_reg_rules = 5, + .alpha2 = "99", + .reg_rules = { + /* IEEE 802.11b/g, channels 1..11 */ +@@ -231,7 +264,10 @@ static const struct ieee80211_regdomain brcmf_regdom = { + /* IEEE 802.11a, channel 36..64 */ + REG_RULE(5150-10, 5350+10, 160, 6, 20, 0), + /* IEEE 802.11a, channel 100..165 */ +- REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), } ++ REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), ++ /* IEEE 802.11ax, 6E */ ++ REG_RULE(5935-10, 7115+10, 160, 6, 20, 0), ++ } + }; + + /* Note: brcmf_cipher_suites is an array of int defining which cipher suites +@@ -356,6 +392,8 @@ static u8 nl80211_band_to_fwil(enum nl80211_band band) + return WLC_BAND_2G; + case NL80211_BAND_5GHZ: + return WLC_BAND_5G; ++ case NL80211_BAND_6GHZ: ++ return WLC_BAND_6G; + default: + WARN_ON(1); + break; +@@ -429,6 +467,9 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf, + case NL80211_BAND_5GHZ: + ch_inf.band = BRCMU_CHAN_BAND_5G; + break; ++ case NL80211_BAND_6GHZ: ++ ch_inf.band = BRCMU_CHAN_BAND_6G; ++ break; + case NL80211_BAND_60GHZ: + default: + WARN_ON_ONCE(1); +@@ -444,6 +485,20 @@ u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, + { + struct brcmu_chan ch_inf; + ++ switch (ch->band) { ++ case NL80211_BAND_2GHZ: ++ ch_inf.band = BRCMU_CHAN_BAND_2G; ++ break; ++ case NL80211_BAND_5GHZ: ++ ch_inf.band = BRCMU_CHAN_BAND_5G; ++ break; ++ case NL80211_BAND_6GHZ: ++ ch_inf.band = BRCMU_CHAN_BAND_6G; ++ break; ++ case NL80211_BAND_60GHZ: ++ default: ++ WARN_ON_ONCE(1); ++ } + ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq); + ch_inf.bw = BRCMU_CHAN_BW_20; + d11inf->encchspec(&ch_inf); +@@ -2619,17 +2674,25 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, + + if (cfg->channel) { + ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1); +- + ext_join_params->assoc_le.chanspec_list[0] = + cpu_to_le16(chanspec); ++ + /* Increase dwell time to receive probe response or detect + * beacon from target AP at a noisy air only during connect + * command. + */ +- ext_join_params->scan_le.active_time = +- cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS); +- ext_join_params->scan_le.passive_time = +- cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS); ++ if (BRCMU_CHSPEC_IS6G(chanspec)) { ++ ext_join_params->scan_le.active_time = ++ cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS_6E); ++ ext_join_params->scan_le.passive_time = ++ cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS_6E); ++ } else { ++ ext_join_params->scan_le.active_time = ++ cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS); ++ ext_join_params->scan_le.passive_time = ++ cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS); ++ } ++ + /* To sync with presence period of VSDB GO send probe request + * more frequently. Probe request will be stopped when it gets + * probe response from target AP/GO. +@@ -3425,18 +3488,13 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, + return -EINVAL; + } + +- if (!bi->ctl_ch) { +- ch.chspec = le16_to_cpu(bi->chanspec); +- cfg->d11inf.decchspec(&ch); ++ ch.chspec = le16_to_cpu(bi->chanspec); ++ cfg->d11inf.decchspec(&ch); ++ if (!bi->ctl_ch) + bi->ctl_ch = ch.control_ch_num; +- } +- channel = bi->ctl_ch; +- +- if (channel <= CH_MAX_2G_CHANNEL) +- band = NL80211_BAND_2GHZ; +- else +- band = NL80211_BAND_5GHZ; + ++ channel = bi->ctl_ch; ++ band = BRCMU_CHAN_BAND_TO_NL80211(ch.band); + freq = ieee80211_channel_to_frequency(channel, band); + bss_data.chan = ieee80211_get_channel(wiphy, freq); + bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20; +@@ -3550,11 +3608,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg, + ch.chspec = le16_to_cpu(bi->chanspec); + cfg->d11inf.decchspec(&ch); + +- if (ch.band == BRCMU_CHAN_BAND_2G) +- band = wiphy->bands[NL80211_BAND_2GHZ]; +- else +- band = wiphy->bands[NL80211_BAND_5GHZ]; +- ++ band = wiphy->bands[BRCMU_CHAN_BAND_TO_NL80211(ch.band)]; + freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band); + cfg->channel = freq; + notify_channel = ieee80211_get_channel(wiphy, freq); +@@ -3745,14 +3799,6 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, + } + bss_info_le = &escan_result_le->bss_info_le; + +- /* WAR to skip 6G scan results before 6E support is complete in host */ +- if ((bss_info_le->chanspec & BRCMU_CHSPEC_D11AC_BND_MASK) == +- BRCMU_CHSPEC_D11AC_BND_6G) { +- bphy_err(drvr, "Currently skip 6G scan, chanspec 0x%04x\n", +- bss_info_le->chanspec); +- goto exit; +- } +- + if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le)) + goto exit; + +@@ -5706,7 +5752,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, vif); ++ af_params, vif, chan); + + cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack, + GFP_KERNEL); +@@ -5878,15 +5924,7 @@ static int brcmf_cfg80211_get_channel(struct wiphy *wiphy, + + ch.chspec = chanspec; + cfg->d11inf.decchspec(&ch); +- +- switch (ch.band) { +- case BRCMU_CHAN_BAND_2G: +- band = NL80211_BAND_2GHZ; +- break; +- case BRCMU_CHAN_BAND_5G: +- band = NL80211_BAND_5GHZ; +- break; +- } ++ band = BRCMU_CHAN_BAND_TO_NL80211(ch.band); + + switch (ch.bw) { + case BRCMU_CHAN_BW_80: +@@ -6684,11 +6722,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, + ch.chspec = le16_to_cpu(bi->chanspec); + cfg->d11inf.decchspec(&ch); + +- if (ch.band == BRCMU_CHAN_BAND_2G) +- band = wiphy->bands[NL80211_BAND_2GHZ]; +- else +- band = wiphy->bands[NL80211_BAND_5GHZ]; +- ++ band = wiphy->bands[BRCMU_CHAN_BAND_TO_NL80211(ch.band)]; + freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band); + notify_channel = ieee80211_get_channel(wiphy, freq); + +@@ -7130,9 +7164,7 @@ brcmf_notify_auth_frame_rx(struct brcmf_if *ifp, + 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); ++ BRCMU_CHAN_BAND_TO_NL80211(ch.band)); + + cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len, + NL80211_RXMGMT_FLAG_EXTERNAL_AUTH); +@@ -7686,6 +7718,10 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) + static void brcmf_update_ht_cap(struct ieee80211_supported_band *band, + u32 bw_cap[2], u32 nchain) + { ++ /* not allowed in 6G band */ ++ if (band->band == NL80211_BAND_6GHZ) ++ return; ++ + band->ht_cap.ht_supported = true; + if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) { + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; +@@ -7716,8 +7752,8 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band, + { + __le16 mcs_map; + +- /* not allowed in 2.4G band */ +- if (band->band == NL80211_BAND_2GHZ) ++ /* not allowed in 2.4G & 6G band */ ++ if (band->band == NL80211_BAND_2GHZ || band->band == NL80211_BAND_6GHZ) + return; + + band->vht_cap.vht_supported = true; +@@ -7752,6 +7788,64 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band, + } + } + ++static void brcmf_update_he_cap(struct ieee80211_supported_band *band, ++ struct ieee80211_sband_iftype_data *data) ++{ ++ int idx = 1; ++ struct ieee80211_sta_he_cap *he_cap = &data->he_cap; ++ struct ieee80211_he_cap_elem *he_cap_elem = &he_cap->he_cap_elem; ++ struct ieee80211_he_mcs_nss_supp *he_mcs = &he_cap->he_mcs_nss_supp; ++ ++ if (data == NULL) { ++ brcmf_dbg(INFO, "failed to allco mem\n"); ++ return; ++ } ++ ++ data->types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); ++ he_cap->has_he = true; ++ he_cap_elem->mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE; ++ if (band->band == NL80211_BAND_5GHZ) { ++ he_cap_elem->phy_cap_info[0] = ++ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | ++ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G | ++ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; ++ } ++ he_cap_elem->phy_cap_info[1] = ++ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; ++ he_cap_elem->phy_cap_info[2] = ++ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US; ++ he_cap_elem->phy_cap_info[3] = ++ IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; ++ he_cap_elem->phy_cap_info[4] = ++ IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | ++ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK | ++ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4; ++ he_cap_elem->phy_cap_info[5] = ++ IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2; ++ he_cap_elem->phy_cap_info[6] = ++ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | ++ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | ++ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | ++ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB | ++ IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB | ++ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT; ++ he_cap_elem->phy_cap_info[7] = ++ IEEE80211_HE_PHY_CAP7_MAX_NC_1; ++ he_cap_elem->phy_cap_info[8] = ++ IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | ++ IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU; ++ he_cap_elem->phy_cap_info[9] = ++ IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU | ++ IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU; ++ he_mcs->rx_mcs_80 = cpu_to_le16(0xfffa); ++ he_mcs->tx_mcs_80 = cpu_to_le16(0xfffa); ++ he_mcs->rx_mcs_160 = cpu_to_le16((0xfffa)); ++ he_mcs->tx_mcs_160 = cpu_to_le16((0xfffa)); ++ ++ band->n_iftype_data = idx; ++ band->iftype_data = data; ++} ++ + static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + { + struct brcmf_pub *drvr = cfg->pub; +@@ -7768,6 +7862,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + u32 txstreams = 0; + u32 txbf_bfe_cap = 0; + u32 txbf_bfr_cap = 0; ++ u32 he[2] = {0, 0}; + + (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode); + err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode); +@@ -7776,8 +7871,10 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + } else { + brcmf_get_bwcap(ifp, bw_cap); + } +- brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n", +- nmode, vhtmode, bw_cap[NL80211_BAND_2GHZ], ++ (void)brcmf_fil_iovar_data_get(ifp, "he", he, sizeof(he)); ++ ++ brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, he=%d, bw_cap=(%d, %d)\n", ++ nmode, vhtmode, he[0], bw_cap[NL80211_BAND_2GHZ], + bw_cap[NL80211_BAND_5GHZ]); + + err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain); +@@ -7819,6 +7916,8 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + if (vhtmode) + brcmf_update_vht_cap(band, bw_cap, nchain, txstreams, + txbf_bfe_cap, txbf_bfr_cap); ++ if (he[0]) ++ brcmf_update_he_cap(band, &sdata[band->band]); + } + + return 0; +@@ -8094,7 +8193,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + struct ieee80211_supported_band *band; + u16 max_interfaces = 0; + bool gscan; +- __le32 bandlist[3]; ++ __le32 bandlist[4]; + u32 n_bands; + int err, i; + +@@ -8225,6 +8324,23 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + band->n_channels = ARRAY_SIZE(__wl_5ghz_channels); + wiphy->bands[NL80211_BAND_5GHZ] = band; + } ++ if (bandlist[i] == cpu_to_le32(WLC_BAND_6G)) { ++ band = kmemdup(&__wl_band_6ghz, sizeof(__wl_band_6ghz), ++ GFP_KERNEL); ++ if (!band) ++ return -ENOMEM; ++ ++ band->channels = kmemdup(&__wl_6ghz_channels, ++ sizeof(__wl_6ghz_channels), ++ GFP_KERNEL); ++ if (!band->channels) { ++ kfree(band); ++ return -ENOMEM; ++ } ++ ++ band->n_channels = ARRAY_SIZE(__wl_6ghz_channels); ++ wiphy->bands[NL80211_BAND_6GHZ] = band; ++ } + } + + if (wiphy->bands[NL80211_BAND_5GHZ] && +@@ -8235,7 +8351,6 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + + wiphy_read_of_freq_limits(wiphy); +- + return 0; + } + +@@ -8751,6 +8866,11 @@ static void brcmf_free_wiphy(struct wiphy *wiphy) + kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels); + kfree(wiphy->bands[NL80211_BAND_5GHZ]); + } ++ if (wiphy->bands[NL80211_BAND_6GHZ]) { ++ kfree(wiphy->bands[NL80211_BAND_6GHZ]->channels); ++ kfree(wiphy->bands[NL80211_BAND_6GHZ]); ++ } ++ + #if IS_ENABLED(CONFIG_PM) + if (wiphy->wowlan != &brcmf_wowlan_support) + kfree(wiphy->wowlan); +@@ -8846,18 +8966,18 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, + else + ops->dump_survey = NULL; + +- err = wiphy_register(wiphy); +- if (err < 0) { +- bphy_err(drvr, "Could not register wiphy device (%d)\n", err); +- goto priv_out; +- } +- + err = brcmf_setup_wiphybands(cfg); + if (err) { + bphy_err(drvr, "Setting wiphy bands failed (%d)\n", err); + goto wiphy_unreg_out; + } + ++ err = wiphy_register(wiphy); ++ if (err < 0) { ++ bphy_err(drvr, "Could not register wiphy device (%d)\n", err); ++ goto priv_out; ++ } ++ + /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(), + * setup 40MHz in 2GHz band and enable OBSS scanning. + */ +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +index 783d4d776dc8..fe1d8d323fa7 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -63,6 +63,7 @@ + #define P2P_AF_TX_MAX_RETRY 5 + #define P2P_AF_MAX_WAIT_TIME msecs_to_jiffies(2000) + #define P2P_INVALID_CHANNEL -1 ++#define P2P_INVALID_CHANSPEC 0 + #define P2P_CHANNEL_SYNC_RETRY 5 + #define P2P_AF_FRM_SCAN_MAX_WAIT msecs_to_jiffies(450) + #define P2P_DEFAULT_SLEEP_TIME_VSDB 200 +@@ -923,6 +924,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 = 0; ++ struct brcmu_chan ch; + + if (brcmf_p2p_scan_is_p2p_request(request)) { + /* find my listen channel */ +@@ -931,7 +933,12 @@ int brcmf_p2p_scan_prep(struct wiphy *wiphy, + if (err < 0) + return err; + +- p2p->afx_hdl.my_listen_chan = err; ++ ch.band = BRCMU_CHAN_BAND_2G; ++ ch.bw = BRCMU_CHAN_BW_20; ++ ch.sb = BRCMU_CHAN_SB_NONE; ++ ch.chnum = err; ++ p2p->cfg->d11inf.encchspec(&ch); ++ p2p->afx_hdl.my_listen_chan = ch.chspec; + + clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status); + brcmf_dbg(INFO, "P2P: GO_NEG_PHASE status cleared\n"); +@@ -955,16 +962,15 @@ int brcmf_p2p_scan_prep(struct wiphy *wiphy, + * brcmf_p2p_discover_listen() - set firmware to discover listen state. + * + * @p2p: p2p device. +- * @channel: channel nr for discover listen. ++ * @chspec: chspec for discover listen. + * @duration: time in ms to stay on channel. + * + */ + static s32 +-brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) ++brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 chspec, u32 duration) + { + struct brcmf_pub *drvr = p2p->cfg->pub; + struct brcmf_cfg80211_vif *vif; +- struct brcmu_chan ch; + s32 err = 0; + + vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; +@@ -980,11 +986,8 @@ brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) + goto exit; + } + +- ch.chnum = channel; +- ch.bw = BRCMU_CHAN_BW_20; +- p2p->cfg->d11inf.encchspec(&ch); + err = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_LISTEN, +- ch.chspec, (u16)duration); ++ chspec, (u16)duration); + if (!err) { + set_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status); + p2p->remain_on_channel_cookie++; +@@ -1010,16 +1013,12 @@ int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_p2p_info *p2p = &cfg->p2p; + s32 err; +- u16 channel_nr; +- +- channel_nr = ieee80211_frequency_to_channel(channel->center_freq); +- brcmf_dbg(TRACE, "Enter, channel: %d, duration ms (%d)\n", channel_nr, +- duration); + + err = brcmf_p2p_enable_discovery(p2p); + if (err) + goto exit; +- err = brcmf_p2p_discover_listen(p2p, channel_nr, duration); ++ err = brcmf_p2p_discover_listen(p2p, ++ channel_to_chanspec(&cfg->d11inf, channel), duration); + if (err) + goto exit; + +@@ -1095,12 +1094,12 @@ void brcmf_p2p_cancel_remain_on_channel(struct brcmf_if *ifp) + * brcmf_p2p_act_frm_search() - search function for action frame. + * + * @p2p: p2p device. +- * @channel: channel on which action frame is to be trasmitted. ++ * @chspec: chspec on which action frame is to be trasmitted. + * + * search function to reach at common channel to send action frame. When + * channel is 0 then all social channels will be used to send af + */ +-static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) ++static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 chspec) + { + struct brcmf_pub *drvr = p2p->cfg->pub; + s32 err; +@@ -1111,7 +1110,7 @@ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) + + brcmf_dbg(TRACE, "Enter\n"); + +- if (channel) ++ if (chspec) + channel_cnt = AF_PEER_SEARCH_CNT; + else + channel_cnt = SOCIAL_CHAN_CNT; +@@ -1122,14 +1121,13 @@ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) + err = -ENOMEM; + goto exit; + } +- ch.bw = BRCMU_CHAN_BW_20; +- if (channel) { +- ch.chnum = channel; +- p2p->cfg->d11inf.encchspec(&ch); +- /* insert same channel to the chan_list */ ++ ++ if (chspec) { + for (i = 0; i < channel_cnt; i++) +- default_chan_list[i] = ch.chspec; ++ default_chan_list[i] = chspec; + } else { ++ ch.band = BRCMU_CHAN_BAND_2G; ++ ch.bw = BRCMU_CHAN_BW_20; + ch.chnum = SOCIAL_CHAN_1; + p2p->cfg->d11inf.encchspec(&ch); + default_chan_list[0] = ch.chspec; +@@ -1188,7 +1186,7 @@ static void brcmf_p2p_afx_handler(struct work_struct *work) + * @p2p: p2p device info struct. + * + */ +-static s32 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p) ++static u16 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p) + { + struct afx_hdl *afx_hdl = &p2p->afx_hdl; + struct brcmf_cfg80211_vif *pri_vif; +@@ -1201,14 +1199,14 @@ static s32 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p) + reinit_completion(&afx_hdl->act_frm_scan); + set_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status); + afx_hdl->is_active = true; +- afx_hdl->peer_chan = P2P_INVALID_CHANNEL; ++ afx_hdl->peer_chan = P2P_INVALID_CHANSPEC; + + /* Loop to wait until we find a peer's channel or the + * pending action frame tx is cancelled. + */ + retry = 0; + while ((retry < P2P_CHANNEL_SYNC_RETRY) && +- (afx_hdl->peer_chan == P2P_INVALID_CHANNEL)) { ++ (afx_hdl->peer_chan == P2P_INVALID_CHANSPEC)) { + afx_hdl->is_listen = false; + brcmf_dbg(TRACE, "Scheduling action frame for sending.. (%d)\n", + retry); +@@ -1216,13 +1214,13 @@ static s32 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p) + schedule_work(&afx_hdl->afx_work); + wait_for_completion_timeout(&afx_hdl->act_frm_scan, + P2P_AF_FRM_SCAN_MAX_WAIT); +- if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) || ++ if ((afx_hdl->peer_chan != P2P_INVALID_CHANSPEC) || + (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, + &p2p->status))) + break; + + if (afx_hdl->my_listen_chan) { +- brcmf_dbg(TRACE, "Scheduling listen peer, channel=%d\n", ++ brcmf_dbg(TRACE, "Scheduling listen peer, chanspec=0x%04x\n", + afx_hdl->my_listen_chan); + /* listen on my listen channel */ + afx_hdl->is_listen = true; +@@ -1230,7 +1228,7 @@ static s32 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p) + wait_for_completion_timeout(&afx_hdl->act_frm_scan, + P2P_AF_FRM_SCAN_MAX_WAIT); + } +- if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) || ++ if ((afx_hdl->peer_chan != P2P_INVALID_CHANSPEC) || + (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, + &p2p->status))) + break; +@@ -1244,7 +1242,7 @@ static s32 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p) + msleep(P2P_DEFAULT_SLEEP_TIME_VSDB); + } + +- brcmf_dbg(TRACE, "Completed search/listen peer_chan=%d\n", ++ brcmf_dbg(TRACE, "Completed search/listen peer_chan=0x%4x\n", + afx_hdl->peer_chan); + afx_hdl->is_active = false; + +@@ -1277,7 +1275,7 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg, + + if (bi == NULL) { + brcmf_dbg(TRACE, "ACTION FRAME SCAN Done\n"); +- if (afx_hdl->peer_chan == P2P_INVALID_CHANNEL) ++ if (afx_hdl->peer_chan == P2P_INVALID_CHANSPEC) + complete(&afx_hdl->act_frm_scan); + return true; + } +@@ -1293,13 +1291,8 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg, + p2p_dev_addr, sizeof(p2p_dev_addr)); + if ((err >= 0) && + (ether_addr_equal(p2p_dev_addr, afx_hdl->tx_dst_addr))) { +- if (!bi->ctl_ch) { +- ch.chspec = le16_to_cpu(bi->chanspec); +- cfg->d11inf.decchspec(&ch); +- bi->ctl_ch = ch.control_ch_num; +- } +- afx_hdl->peer_chan = bi->ctl_ch; +- brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n", ++ afx_hdl->peer_chan = le16_to_cpu(bi->chanspec); ++ brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, chanspec : 0x%04x\n", + afx_hdl->tx_dst_addr, afx_hdl->peer_chan); + complete(&afx_hdl->act_frm_scan); + } +@@ -1471,8 +1464,8 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, + if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, + &p2p->status) && + (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { +- afx_hdl->peer_chan = ch.control_ch_num; +- brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n", ++ afx_hdl->peer_chan = be16_to_cpu(rxframe->chanspec); ++ brcmf_dbg(INFO, "GON request: Peer found, chanspec=0x%04x\n", + afx_hdl->peer_chan); + complete(&afx_hdl->act_frm_scan); + } +@@ -1515,9 +1508,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, + 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); ++ BRCMU_CHAN_BAND_TO_NL80211(ch.band)); + + wdev = &ifp->vif->wdev; + cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len, 0); +@@ -1763,7 +1754,8 @@ static bool brcmf_p2p_check_dwell_overflow(u32 requested_dwell, + 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_cfg80211_vif *vif ++ struct brcmf_cfg80211_vif *vif, ++ struct ieee80211_channel *peer_listen_chan + ) + { + struct brcmf_p2p_info *p2p = &cfg->p2p; +@@ -1772,6 +1764,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, + struct brcmf_config_af_params config_af_params; + struct afx_hdl *afx_hdl = &p2p->afx_hdl; + struct brcmf_pub *drvr = cfg->pub; ++ struct brcmu_chan ch; + u16 action_frame_len; + bool ack = false; + u8 category; +@@ -1878,10 +1871,10 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, + 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); ++ afx_hdl->peer_listen_chan = channel_to_chanspec(&cfg->d11inf, peer_listen_chan); + + if (brcmf_p2p_af_searching_channel(p2p) == +- P2P_INVALID_CHANNEL) { ++ P2P_INVALID_CHANSPEC) { + bphy_err(drvr, "Couldn't find peer's channel.\n"); + goto exit; + } +@@ -1894,7 +1887,9 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, + brcmf_notify_escan_complete(cfg, ifp, true, true); + + /* update channel */ +- af_params->channel = cpu_to_le32(afx_hdl->peer_chan); ++ ch.chspec = afx_hdl->peer_chan; ++ cfg->d11inf.decchspec(&ch); ++ af_params->channel = cpu_to_le32(ch.control_ch_num); + } + dwell_jiffies = jiffies; + dwell_overflow = brcmf_p2p_check_dwell_overflow(requested_dwell, +@@ -1926,9 +1921,11 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, + * not keep the dwell time, go to listen state again to get next action + * response frame. + */ ++ ch.chspec = afx_hdl->my_listen_chan; ++ cfg->d11inf.decchspec(&ch); + if (ack && config_af_params.extra_listen && !p2p->block_gon_req_tx && + test_bit(BRCMF_P2P_STATUS_WAITING_NEXT_ACT_FRAME, &p2p->status) && +- p2p->af_sent_channel == afx_hdl->my_listen_chan) { ++ p2p->af_sent_channel == ch.control_ch_num) { + delta_ms = jiffies_to_msecs(jiffies - p2p->af_tx_sent_jiffies); + if (le32_to_cpu(af_params->dwell_time) > delta_ms) + extra_listen_time = le32_to_cpu(af_params->dwell_time) - +@@ -1943,7 +1940,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, + extra_listen_time); + extra_listen_time += 100; + if (!brcmf_p2p_discover_listen(p2p, +- p2p->af_sent_channel, ++ afx_hdl->my_listen_chan, + extra_listen_time)) { + unsigned long duration; + +@@ -2008,8 +2005,8 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, + + if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && + (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { +- afx_hdl->peer_chan = ch.control_ch_num; +- brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n", ++ afx_hdl->peer_chan = be16_to_cpu(rxframe->chanspec); ++ brcmf_dbg(INFO, "PROBE REQUEST: Peer found, chanspec=0x%04x\n", + afx_hdl->peer_chan); + complete(&afx_hdl->act_frm_scan); + } +@@ -2034,9 +2031,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, + mgmt_frame = (u8 *)(rxframe + 1); + mgmt_frame_len = e->datalen - sizeof(*rxframe); + freq = ieee80211_channel_to_frequency(ch.control_ch_num, +- ch.band == BRCMU_CHAN_BAND_2G ? +- NL80211_BAND_2GHZ : +- NL80211_BAND_5GHZ); ++ BRCMU_CHAN_BAND_TO_NL80211(ch.band)); + + cfg80211_rx_mgmt(&vif->wdev, freq, 0, mgmt_frame, mgmt_frame_len, 0); + +@@ -2080,6 +2075,7 @@ static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p, + } + } + /* Use default channel for P2P */ ++ ch.band = BRCMU_CHAN_BAND_2G; + ch.chnum = BRCMF_P2P_TEMP_CHAN; + ch.bw = BRCMU_CHAN_BW_20; + p2p->cfg->d11inf.encchspec(&ch); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h +index bbc455238707..d71709aae7ab 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h +@@ -87,7 +87,7 @@ struct afx_hdl { + struct work_struct afx_work; + struct completion act_frm_scan; + bool is_active; +- s32 peer_chan; ++ u16 peer_chan; + bool is_listen; + u16 my_listen_chan; + u16 peer_listen_chan; +@@ -172,7 +172,8 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp, + 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_cfg80211_vif *vif); ++ struct brcmf_cfg80211_vif *vif, ++ struct ieee80211_channel *peer_listen_chan); + 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/brcmutil/d11.c b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c +index 1e2b1e487eb7..5effa27542e9 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c +@@ -87,10 +87,20 @@ static void brcmu_d11ac_encchspec(struct brcmu_chan *ch) + 0, d11ac_bw(ch->bw)); + + ch->chspec &= ~BRCMU_CHSPEC_D11AC_BND_MASK; +- if (ch->chnum <= CH_MAX_2G_CHANNEL) +- ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G; +- else ++ switch (ch->band) { ++ case BRCMU_CHAN_BAND_6G: ++ ch->chspec |= BRCMU_CHSPEC_D11AC_BND_6G; ++ break; ++ case BRCMU_CHAN_BAND_5G: + ch->chspec |= BRCMU_CHSPEC_D11AC_BND_5G; ++ break; ++ case BRCMU_CHAN_BAND_2G: ++ ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G; ++ break; ++ default: ++ WARN_ONCE(1, "Invalid band 0x%04x\n", ch->band); ++ break; ++ } + } + + static void brcmu_d11n_decchspec(struct brcmu_chan *ch) +@@ -222,6 +232,9 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) + } + + switch (ch->chspec & BRCMU_CHSPEC_D11AC_BND_MASK) { ++ case BRCMU_CHSPEC_D11AC_BND_6G: ++ ch->band = BRCMU_CHAN_BAND_6G; ++ break; + case BRCMU_CHSPEC_D11AC_BND_5G: + ch->band = BRCMU_CHAN_BAND_5G; + break; +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h +index 9a54a046a795..3d7655c9c058 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h +@@ -84,9 +84,16 @@ + #define BRCMU_CHSPEC_D11AC_BND_3G 0x4000 + #define BRCMU_CHSPEC_D11AC_BND_6G 0x8000 + #define BRCMU_CHSPEC_D11AC_BND_5G 0xc000 +- +-#define BRCMU_CHAN_BAND_2G 0 +-#define BRCMU_CHAN_BAND_5G 1 ++#define BRCMU_CHSPEC_IS5G(chspec) \ ++ (((chspec) & BRCMU_CHSPEC_D11AC_BND_MASK) == BRCMU_CHSPEC_D11AC_BND_5G) ++#define BRCMU_CHSPEC_IS6G(chspec) \ ++ (((chspec) & BRCMU_CHSPEC_D11AC_BND_MASK) == BRCMU_CHSPEC_D11AC_BND_6G) ++#define BRCMU_CHAN_BAND_2G 1 ++#define BRCMU_CHAN_BAND_5G 2 ++#define BRCMU_CHAN_BAND_6G 3 ++#define BRCMU_CHAN_BAND_TO_NL80211(band) \ ++ ((band) == BRCMU_CHAN_BAND_2G ? NL80211_BAND_2GHZ : \ ++ ((band) == BRCMU_CHAN_BAND_5G ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ)) + + enum brcmu_chan_bw { + BRCMU_CHAN_BW_20, +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +index 3a9cad3730b8..38b0b35e602c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +@@ -92,7 +92,8 @@ + #define WLC_BAND_AUTO 0 /* auto-select */ + #define WLC_BAND_5G 1 /* 5 Ghz */ + #define WLC_BAND_2G 2 /* 2.4 Ghz */ +-#define WLC_BAND_ALL 3 /* all bands */ ++#define WLC_BAND_6G 3 /* 6 Ghz */ ++#define WLC_BAND_ALL 4 /* all bands */ + + #define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK)) + #define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0121-brcmfmac-fixes-invalid-channel-still-in-the-channel-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0121-brcmfmac-fixes-invalid-channel-still-in-the-channel-.patch new file mode 100644 index 000000000..6284cd7d8 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0121-brcmfmac-fixes-invalid-channel-still-in-the-channel-.patch @@ -0,0 +1,58 @@ +From 31a22e9c87baddf2b2aff01cee7878783a9944cb Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Thu, 14 Apr 2022 03:07:46 -0500 +Subject: [PATCH 121/179] brcmfmac: fixes invalid channel still in the channel + list + +The loop of removing disabled channel will miss detect some +channels. Modified the counter condition to solve this bug. + +Signed-off-by: JasonHuang +--- + .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 107509118bc1..0dfab09c1f2f 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -7560,7 +7560,7 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + band = wiphy->bands[NL80211_BAND_2GHZ]; + if (band) { + n_2g = band->n_channels; +- for (i = 0; i < band->n_channels; i++) { ++ for (i = 0; i < n_2g;) { + cur = &band->channels[i]; + if (cur->flags == IEEE80211_CHAN_DISABLED) { + for (j = i; j < n_2g - 1; j++) { +@@ -7569,14 +7569,15 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + memcpy(cur, next, sizeof(*cur)); + } + n_2g--; +- } ++ } else ++ i++; + } + wiphy->bands[NL80211_BAND_2GHZ]->n_channels = n_2g; + } + band = wiphy->bands[NL80211_BAND_5GHZ]; + if (band) { + n_5g = band->n_channels; +- for (i = 0; i < band->n_channels; i++) { ++ for (i = 0; i < n_5g;) { + cur = &band->channels[i]; + if (cur->flags == IEEE80211_CHAN_DISABLED) { + for (j = i; j < n_5g - 1; j++) { +@@ -7585,7 +7586,8 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + memcpy(cur, next, sizeof(*cur)); + } + n_5g--; +- } ++ } else ++ i++; + } + wiphy->bands[NL80211_BAND_5GHZ]->n_channels = n_5g; + } +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0122-non-upstream-Fix-lspci-not-enumerating-wifi-device-a.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0122-non-upstream-Fix-lspci-not-enumerating-wifi-device-a.patch new file mode 100644 index 000000000..b29072410 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0122-non-upstream-Fix-lspci-not-enumerating-wifi-device-a.patch @@ -0,0 +1,101 @@ +From 85da802dcb11b353e7089d477c906667c476751e Mon Sep 17 00:00:00 2001 +From: "Kumar Prasanth (CSTIPL CSS ICW APP ETG WIFI)" +Date: Tue, 10 May 2022 04:55:13 +0000 +Subject: [PATCH 122/179] non-upstream: Fix lspci not enumerating wifi device + after reboot + +--- + .../broadcom/brcm80211/brcmfmac/common.c | 21 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/core.c | 2 +- + .../broadcom/brcm80211/brcmfmac/core.h | 2 +- + 3 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +index 6e4a1d12b06e..5b132e90d9af 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -23,6 +23,9 @@ + #include "defs.h" + #include "fweh.h" + #include ++#include ++#include ++#include "pcie.h" + + MODULE_AUTHOR("Broadcom Corporation"); + MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); +@@ -92,6 +95,12 @@ MODULE_PARM_DESC(fw_ap_select, "Allow FW for AP selection"); + static struct brcmfmac_platform_data *brcmfmac_pdata; + struct brcmf_mp_global_t brcmf_mp_global; + ++static int brcmf_reboot_callback(struct notifier_block *this, unsigned long code, void *unused); ++static struct notifier_block brcmf_reboot_notifier = { ++ .notifier_call = brcmf_reboot_callback, ++ .priority = 1, ++}; ++ + void brcmf_c_set_joinpref_default(struct brcmf_if *ifp) + { + struct brcmf_pub *drvr = ifp->drvr; +@@ -530,6 +539,15 @@ void brcmf_release_module_param(struct brcmf_mp_device *module_param) + kfree(module_param); + } + ++static int ++brcmf_reboot_callback(struct notifier_block *this, unsigned long code, void *unused) ++{ ++ brcmf_dbg(INFO, "code = %ld\n", code); ++ if (code == SYS_RESTART) ++ brcmf_core_exit(); ++ return NOTIFY_DONE; ++} ++ + static int __init brcmf_common_pd_probe(struct platform_device *pdev) + { + brcmf_dbg(INFO, "Enter\n"); +@@ -576,6 +594,8 @@ static int __init brcmfmac_module_init(void) + if (err) { + if (brcmfmac_pdata) + platform_driver_unregister(&brcmf_pd); ++ } else { ++ register_reboot_notifier(&brcmf_reboot_notifier); + } + + return err; +@@ -584,6 +604,7 @@ static int __init brcmfmac_module_init(void) + static void __exit brcmfmac_module_exit(void) + { + brcmf_core_exit(); ++ unregister_reboot_notifier(&brcmf_reboot_notifier); + if (brcmfmac_pdata) + platform_driver_unregister(&brcmf_pd); + } +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +index 920056a2aec8..84e426d8f783 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1580,7 +1580,7 @@ int __init brcmf_core_init(void) + return err; + } + +-void __exit brcmf_core_exit(void) ++void brcmf_core_exit(void) + { + brcmf_sdio_exit(); + brcmf_usb_exit(); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +index 0b2938a09c5a..37a361254522 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -234,7 +234,7 @@ void brcmf_net_detach(struct net_device *ndev, bool locked); + 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); ++void 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); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0123-brcmfmac-support-signal-monitor-feature-for-wpa_supp.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0123-brcmfmac-support-signal-monitor-feature-for-wpa_supp.patch new file mode 100644 index 000000000..b64b66998 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0123-brcmfmac-support-signal-monitor-feature-for-wpa_supp.patch @@ -0,0 +1,107 @@ +From 5cbd28fb75d920e9d2366b882bec0189891ed754 Mon Sep 17 00:00:00 2001 +From: Ian Lin +Date: Tue, 10 May 2022 04:53:27 -0500 +Subject: [PATCH 123/179] brcmfmac: support signal monitor feature for + wpa_supplicant bgscan + +Add nl80211 operation and notify event for background scan +After connect to target AP, wpa_supplicant will continually +send scan request to driver with an given interval, and +apply the short/long interval according to signal level. + +Signed-off-by: Ian Lin +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 38 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/cfg80211.h | 6 +++ + 2 files changed, 44 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 0dfab09c1f2f..ceb0cc337b07 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3542,6 +3542,41 @@ next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss) + le32_to_cpu(bss->length)); + } + ++static s32 brcmf_singal_monitor(struct brcmf_cfg80211_info *cfg, ++ struct brcmf_if *ifp) ++{ ++ s32 err = 0, rssi = 0; ++ int i; ++ u8 bssid[ETH_ALEN] = {0}; ++ struct brcmf_scan_results *bss_list; ++ struct brcmf_bss_info_le *bi = NULL; ++ ++ if(!cfg->cqm_info.enable) ++ return 0; ++ ++ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, bssid, ETH_ALEN); ++ bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; ++ ++ /* wpa bgscan feature: wpa will send scan request after associated ++ * to the target AP, when we get the scan result of this associated ++ * AP, send the rssi threshold event upward */ ++ for (i = 0; i < bss_list->count; i++) { ++ bi = next_bss_le(bss_list, bi); ++ if (err == 0 && memcmp(bi->BSSID, bssid, ETH_ALEN) == 0) { ++ rssi = (s16)le16_to_cpu(bi->RSSI); ++ brcmf_dbg(TRACE, "%s(%pM), rssi: %d, threshold: %d, send event(%s)\n", ++ bi->SSID, bi->BSSID, rssi, cfg->cqm_info.rssi_threshold, ++ rssi > cfg->cqm_info.rssi_threshold ? "HIGH" : "LOW"); ++ cfg80211_cqm_rssi_notify(cfg_to_ndev(cfg), ++ (rssi > cfg->cqm_info.rssi_threshold ? ++ NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH : ++ NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW), ++ rssi, GFP_KERNEL); ++ } ++ } ++ return 0; ++} ++ + static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg) + { + struct brcmf_pub *drvr = cfg->pub; +@@ -3849,6 +3884,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, + goto exit; + if (cfg->int_escan_map || cfg->scan_request) { + brcmf_inform_bss(cfg); ++ brcmf_singal_monitor(cfg, ifp); + aborted = status != BRCMF_E_STATUS_SUCCESS; + brcmf_notify_escan_complete(cfg, ifp, aborted, false); + } else +@@ -8268,6 +8304,8 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + brcmf_feat_is_enabled(ifp, BRCMF_FEAT_OKC)) + wiphy_ext_feature_set(wiphy, + NL80211_EXT_FEATURE_ROAM_OFFLOAD); ++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); ++ + 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 95713e78f2f7..124ae65f1bdf 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -303,6 +303,11 @@ struct escan_info { + struct cfg80211_scan_request *request); + }; + ++struct cqm_rssi_info { ++ bool enable; ++ s32 rssi_threshold; ++}; ++ + /** + * struct brcmf_cfg80211_vif_event - virtual interface event information. + * +@@ -399,6 +404,7 @@ struct brcmf_cfg80211_info { + struct escan_info escan_info; + struct timer_list escan_timeout; + struct work_struct escan_timeout_work; ++ struct cqm_rssi_info cqm_info; + struct list_head vif_list; + struct brcmf_cfg80211_vif_event vif_event; + struct completion vif_disabled; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0124-brcmfmac-add-support-for-CYW55560-SDIO-chipset.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0124-brcmfmac-add-support-for-CYW55560-SDIO-chipset.patch new file mode 100644 index 000000000..cf985fa25 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0124-brcmfmac-add-support-for-CYW55560-SDIO-chipset.patch @@ -0,0 +1,368 @@ +From eb553209d120f7a1aa5a98f88a2d3b731af30186 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Sun, 5 Jul 2020 20:13:45 -0500 +Subject: [PATCH 124/179] brcmfmac: add support for CYW55560 SDIO chipset + +CYW55560 is a 2x2 dual-band 802.11a/b/g/n/ac/ax chipset with 20/40/80MHz +channel support. It's a WLAN+BT combo device with WLAN secure boot +support. + +Signed-off-by: Chung-Hsien Hsu +--- + .../broadcom/brcm80211/brcmfmac/bcmsdh.c | 6 + + .../broadcom/brcm80211/brcmfmac/chip.c | 1 + + .../broadcom/brcm80211/brcmfmac/sdio.c | 144 +++++++++++++++--- + .../broadcom/brcm80211/brcmfmac/sdio.h | 4 + + include/linux/mmc/sdio_ids.h | 1 + + 5 files changed, 139 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +index 48ff922a9989..d6ee946cc45c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -48,6 +48,8 @@ + #define SDIO_435X_FUNC2_BLOCKSIZE 256 + #define SDIO_4329_FUNC2_BLOCKSIZE 128 + #define SDIO_89459_FUNC2_BLOCKSIZE 256 ++#define SDIO_CYW55560_FUNC2_BLOCKSIZE 256 ++ + /* Maximum milliseconds to wait for F2 to come up */ + #define SDIO_WAIT_F2RDY 3000 + +@@ -933,6 +935,9 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) + case SDIO_DEVICE_ID_CYPRESS_54594: + f2_blksz = SDIO_89459_FUNC2_BLOCKSIZE; + break; ++ case SDIO_DEVICE_ID_CYPRESS_55560: ++ f2_blksz = SDIO_CYW55560_FUNC2_BLOCKSIZE; ++ break; + default: + break; + } +@@ -1009,6 +1014,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { + CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_54590), + CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_54591), + CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_54594), ++ CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_55560), + { /* end: all zeroes */ } + }; + MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +index d055cd43ddeb..b85e856bfc70 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -1641,6 +1641,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_55560_CHIP_ID: + case CY_CC_89459_CHIP_ID: + /* explicitly check SR engine enable bit */ + addr = CORE_CC_REG(base, sr_control0); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index 406569b0bea4..16190d77a115 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -70,6 +70,10 @@ + #define CY_89459_MES_WATERMARK 0x40 + #define CY_89459_MESBUSYCTRL (CY_89459_MES_WATERMARK | \ + SBSDIO_MESBUSYCTRL_ENAB) ++#define CYW55560_F2_WATERMARK 0x40 ++#define CYW55560_MES_WATERMARK 0x40 ++#define CYW55560_F1_MESBUSYCTRL (CYW55560_MES_WATERMARK | \ ++ SBSDIO_MESBUSYCTRL_ENAB) + + #ifdef DEBUG + +@@ -647,6 +651,7 @@ 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"); ++CY_FW_TRXSE_DEF(55560, "cyfmac55560-sdio"); + + /* firmware config files */ + MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.txt"); +@@ -680,7 +685,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { + 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_89459_CHIP_ID, 0xFFFFFFFF, 89459) ++ BRCMF_FW_ENTRY(CY_CC_89459_CHIP_ID, 0xFFFFFFFF, 89459), ++ BRCMF_FW_ENTRY(CY_CC_55560_CHIP_ID, 0xFFFFFFFF, 55560) + }; + + #define TXCTL_CREDITS 2 +@@ -741,7 +747,8 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) + * fail. Thereby just bailing out immediately after clearing KSO + * bit, to avoid polling of KSO bit. + */ +- if (!on && bus->ci->chip == CY_CC_43012_CHIP_ID) ++ if (!on && ((bus->ci->chip == CY_CC_43012_CHIP_ID) || ++ (bus->ci->chip == CY_CC_55560_CHIP_ID))) + return err; + + if (on) { +@@ -2543,7 +2550,8 @@ static bool brcmf_chip_is_ulp(struct brcmf_chip *ci) + + static bool brcmf_sdio_use_ht_avail(struct brcmf_chip *ci) + { +- if (ci->chip == CY_CC_4373_CHIP_ID) ++ if (ci->chip == CY_CC_4373_CHIP_ID || ++ ci->chip == CY_CC_55560_CHIP_ID) + return true; + else + return false; +@@ -3675,6 +3683,16 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus, + rstvec = get_unaligned_le32(fw->data); + brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec); + ++ if (bus->ci->blhs) { ++ bcmerror = bus->ci->blhs->prep_fwdl(bus->ci); ++ if (bcmerror) { ++ brcmf_err("FW download preparation failed\n"); ++ release_firmware(fw); ++ brcmf_fw_nvram_free(nvram); ++ goto err; ++ } ++ } ++ + bcmerror = brcmf_sdio_download_code_file(bus, fw); + release_firmware(fw); + if (bcmerror) { +@@ -3683,6 +3701,22 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus, + goto err; + } + ++ if (bus->ci->blhs) { ++ bcmerror = bus->ci->blhs->post_fwdl(bus->ci); ++ if (bcmerror) { ++ brcmf_err("FW download failed, err=%d\n", bcmerror); ++ brcmf_fw_nvram_free(nvram); ++ goto err; ++ } ++ ++ bcmerror = bus->ci->blhs->chk_validation(bus->ci); ++ if (bcmerror) { ++ brcmf_err("FW valication failed, err=%d\n", bcmerror); ++ brcmf_fw_nvram_free(nvram); ++ goto err; ++ } ++ } ++ + bcmerror = brcmf_sdio_download_nvram(bus, nvram, nvlen); + brcmf_fw_nvram_free(nvram); + if (bcmerror) { +@@ -3690,10 +3724,14 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus, + goto err; + } + +- /* Take arm out of reset */ +- if (!brcmf_chip_set_active(bus->ci, rstvec)) { +- brcmf_err("error getting out of ARM core reset\n"); +- goto err; ++ if (bus->ci->blhs) { ++ bus->ci->blhs->post_nvramdl(bus->ci); ++ } else { ++ /* Take arm out of reset */ ++ if (!brcmf_chip_set_active(bus->ci, rstvec)) { ++ brcmf_err("error getting out of ARM core reset\n"); ++ goto err; ++ } + } + + err: +@@ -3707,6 +3745,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 == CY_CC_55560_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 || +@@ -4131,6 +4170,20 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, + } + } + ++static u32 brcmf_sdio_buscore_blhs_read(void *ctx, u32 reg_offset) ++{ ++ struct brcmf_sdio_dev *sdiodev = (struct brcmf_sdio_dev *)ctx; ++ ++ return (u32)brcmf_sdiod_readb(sdiodev, reg_offset, NULL); ++} ++ ++static void brcmf_sdio_buscore_blhs_write(void *ctx, u32 reg_offset, u32 value) ++{ ++ struct brcmf_sdio_dev *sdiodev = (struct brcmf_sdio_dev *)ctx; ++ ++ brcmf_sdiod_writeb(sdiodev, reg_offset, (u8)value, NULL); ++} ++ + static int brcmf_sdio_buscoreprep(void *ctx) + { + struct brcmf_sdio_dev *sdiodev = ctx; +@@ -4227,11 +4280,39 @@ static void brcmf_sdio_buscore_write32(void *ctx, u32 addr, u32 val) + brcmf_sdiod_writel(sdiodev, addr, val, NULL); + } + ++static int brcmf_sdio_buscore_blhs_attach(void *ctx, struct brcmf_blhs **blhs, ++ u32 flag, uint timeout, uint interval) ++{ ++ struct brcmf_sdio_dev *sdiodev = (struct brcmf_sdio_dev *)ctx; ++ struct brcmf_blhs *blhsh; ++ u8 cardcap; ++ ++ if (sdiodev->func1->vendor != SDIO_VENDOR_ID_CYPRESS) ++ return 0; ++ ++ cardcap = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_BRCM_CARDCAP, NULL); ++ if (cardcap & SDIO_CCCR_BRCM_CARDCAP_SECURE_MODE) { ++ blhsh = kzalloc(sizeof(*blhsh), GFP_KERNEL); ++ if (!blhsh) ++ return -ENOMEM; ++ ++ blhsh->d2h = BRCMF_SDIO_REG_DAR_D2H_MSG_0; ++ blhsh->h2d = BRCMF_SDIO_REG_DAR_H2D_MSG_0; ++ blhsh->read = brcmf_sdio_buscore_blhs_read; ++ blhsh->write = brcmf_sdio_buscore_blhs_write; ++ ++ *blhs = blhsh; ++ } ++ ++ return 0; ++} ++ + static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { + .prepare = brcmf_sdio_buscoreprep, + .activate = brcmf_sdio_buscore_activate, + .read32 = brcmf_sdio_buscore_read32, + .write32 = brcmf_sdio_buscore_write32, ++ .blhs_attach = brcmf_sdio_buscore_blhs_attach, + }; + + static bool +@@ -4344,17 +4425,21 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) + if (err) + goto fail; + +- /* set PMUControl so a backplane reset does PMU state reload */ +- reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); +- reg_val = brcmf_sdiod_readl(sdiodev, reg_addr, &err); +- if (err) +- goto fail; ++ if (!bus->ci->blhs) { ++ /* set PMUControl so a backplane reset does PMU state reload */ ++ reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, ++ pmucontrol); ++ reg_val = brcmf_sdiod_readl(sdiodev, reg_addr, &err); ++ if (err) ++ goto fail; + +- reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); ++ reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << ++ BCMA_CC_PMU_CTL_RES_SHIFT); + +- brcmf_sdiod_writel(sdiodev, reg_addr, reg_val, &err); +- if (err) +- goto fail; ++ brcmf_sdiod_writel(sdiodev, reg_addr, reg_val, &err); ++ if (err) ++ goto fail; ++ } + + sdio_release_host(sdiodev->func1); + +@@ -4642,6 +4727,19 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, + brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_MESBUSYCTRL, + CY_89459_MESBUSYCTRL, &err); + break; ++ case SDIO_DEVICE_ID_CYPRESS_55560: ++ brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n", ++ CYW55560_F2_WATERMARK); ++ brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, ++ CYW55560_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, ++ CYW55560_F1_MESBUSYCTRL, &err); ++ break; + default: + brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, + DEFAULT_F2_WATERMARK, &err); +@@ -4748,6 +4846,9 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus) + { ".txt", bus->sdiodev->nvram_name }, + }; + ++ if (bus->ci->blhs) ++ fwnames[BRCMF_SDIO_FW_CODE].extension = ".trxse"; ++ + fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev, + brcmf_sdio_fwnames, + ARRAY_SIZE(brcmf_sdio_fwnames), +@@ -4755,7 +4856,10 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus) + if (!fwreq) + return NULL; + +- fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; ++ if (bus->ci->blhs) ++ fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_TRXSE; ++ else ++ fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; + fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; + fwreq->board_type = bus->sdiodev->settings->board_type; + +@@ -4911,10 +5015,16 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) + } else { + brcmf_chip_set_passive(bus->ci); + } ++ ++ if (bus->ci->blhs) ++ bus->ci->blhs->init(bus->ci); + /* Reset the PMU, backplane and all the + * cores by using the PMUWatchdogCounter. + */ + brcmf_chip_reset_watchdog(bus->ci); ++ if (bus->ci->blhs) ++ bus->ci->blhs->post_wdreset(bus->ci); ++ + brcmf_sdio_clkctl(bus, CLK_NONE, false); + sdio_release_host(bus->sdiodev->func1); + } +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +index ce52692adbc9..d4166805a197 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -28,12 +28,16 @@ + #define REG_F0_REG_MASK 0x7FF + #define REG_F1_MISC_MASK 0x1FFFF + ++#define BRCMF_SDIO_REG_DAR_H2D_MSG_0 0x10030 ++#define BRCMF_SDIO_REG_DAR_D2H_MSG_0 0x10038 ++ + /* function 0 vendor specific CCCR registers */ + + #define SDIO_CCCR_BRCM_CARDCAP 0xf0 + #define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT BIT(1) + #define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT BIT(2) + #define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC BIT(3) ++#define SDIO_CCCR_BRCM_CARDCAP_SECURE_MODE BIT(7) + + /* Interrupt enable bits for each function */ + #define SDIO_CCCR_IEN_FUNC0 BIT(0) +diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h +index 64d43a61249c..937264165319 100644 +--- a/include/linux/mmc/sdio_ids.h ++++ b/include/linux/mmc/sdio_ids.h +@@ -83,6 +83,7 @@ + #define SDIO_DEVICE_ID_CYPRESS_54591 0xbd3b + #define SDIO_DEVICE_ID_CYPRESS_54594 0xbd3c + #define SDIO_DEVICE_ID_CYPRESS_43439 0xbd3d ++#define SDIO_DEVICE_ID_CYPRESS_55560 0xbd31 + + #define SDIO_VENDOR_ID_MARVELL 0x02df + #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0125-brcmfmac-Modified-Kconfig-help-format.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0125-brcmfmac-Modified-Kconfig-help-format.patch new file mode 100644 index 000000000..89c96e58e --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0125-brcmfmac-Modified-Kconfig-help-format.patch @@ -0,0 +1,29 @@ +From 2777e0784354f687c862c8e25787b096bad2755b Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Thu, 9 Jun 2022 21:46:45 -0500 +Subject: [PATCH 125/179] brcmfmac: Modified Kconfig help format + +According to the kernel 5.10.9 kconfig-language.rst, the +attribute of help not support "---help---" any more. + +Signed-off-by: JasonHuang +--- + 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 5dbc1e2a83fc..b520d46ffe5d 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig ++++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig +@@ -43,7 +43,7 @@ config BRCMFMAC_PCIE_BARWIN_SZ + depends on BRCMFMAC + depends on PCI + default n +- ---help--- ++ 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 +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0126-brcmfmac-Fix-incorrect-WARN_ON-causing-set_pmk-failu.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0126-brcmfmac-Fix-incorrect-WARN_ON-causing-set_pmk-failu.patch new file mode 100644 index 000000000..d0b2a5d6f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0126-brcmfmac-Fix-incorrect-WARN_ON-causing-set_pmk-failu.patch @@ -0,0 +1,31 @@ +From ebe07cc44d6729dce7626a9502c07bf693946f64 Mon Sep 17 00:00:00 2001 +From: Ramesh Rangavittal +Date: Thu, 9 Jun 2022 11:10:09 -0500 +Subject: [PATCH 126/179] brcmfmac: Fix incorrect WARN_ON causing set_pmk + failure + +When STA switches from WPA2-PSK to Enterprise-PEAP +authentication, use_fwsup is set to BRCMF_PROFILE_FWSUP_ROAM. +This value also needs to be included in the WARN_ON check +for the authentication to go through. + +Signed-off-by: Ramesh Rangavittal ramesh.rangavittal@infineon.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 ceb0cc337b07..162b355d6e4c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6157,6 +6157,7 @@ static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev, + ifp = netdev_priv(dev); + drvr = ifp->drvr; + if (WARN_ON((ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X) && ++ (ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_ROAM) && + (ifp->vif->profile.is_ft != true) && + (ifp->vif->profile.is_okc != true))) + return -EINVAL; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0127-brcmfmac-report-cqm-rssi-event-based-on-rssi-change-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0127-brcmfmac-report-cqm-rssi-event-based-on-rssi-change-.patch new file mode 100644 index 000000000..81637296d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0127-brcmfmac-report-cqm-rssi-event-based-on-rssi-change-.patch @@ -0,0 +1,198 @@ +From ed4da3bcaa7b4873af362965db5720bf8b607012 Mon Sep 17 00:00:00 2001 +From: Suresh Sanaboina +Date: Fri, 17 Jun 2022 10:43:18 -0500 +Subject: [PATCH 127/179] brcmfmac: report cqm rssi event based on rssi change + for wpa_supplicant bgscan + +FW reports rssi change indication using BRCM_E_RSSI event. Register for +same event and report rssi change indication to supplicant using +CQM event. + +Signed-off-by: Suresh Sanaboina +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 100 +++++++++++------- + .../broadcom/brcm80211/brcmfmac/fwil_types.h | 17 +++ + 2 files changed, 81 insertions(+), 36 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 162b355d6e4c..4b5cb64dac72 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3542,41 +3542,6 @@ next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss) + le32_to_cpu(bss->length)); + } + +-static s32 brcmf_singal_monitor(struct brcmf_cfg80211_info *cfg, +- struct brcmf_if *ifp) +-{ +- s32 err = 0, rssi = 0; +- int i; +- u8 bssid[ETH_ALEN] = {0}; +- struct brcmf_scan_results *bss_list; +- struct brcmf_bss_info_le *bi = NULL; +- +- if(!cfg->cqm_info.enable) +- return 0; +- +- err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, bssid, ETH_ALEN); +- bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; +- +- /* wpa bgscan feature: wpa will send scan request after associated +- * to the target AP, when we get the scan result of this associated +- * AP, send the rssi threshold event upward */ +- for (i = 0; i < bss_list->count; i++) { +- bi = next_bss_le(bss_list, bi); +- if (err == 0 && memcmp(bi->BSSID, bssid, ETH_ALEN) == 0) { +- rssi = (s16)le16_to_cpu(bi->RSSI); +- brcmf_dbg(TRACE, "%s(%pM), rssi: %d, threshold: %d, send event(%s)\n", +- bi->SSID, bi->BSSID, rssi, cfg->cqm_info.rssi_threshold, +- rssi > cfg->cqm_info.rssi_threshold ? "HIGH" : "LOW"); +- cfg80211_cqm_rssi_notify(cfg_to_ndev(cfg), +- (rssi > cfg->cqm_info.rssi_threshold ? +- NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH : +- NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW), +- rssi, GFP_KERNEL); +- } +- } +- return 0; +-} +- + static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg) + { + struct brcmf_pub *drvr = cfg->pub; +@@ -3884,7 +3849,6 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, + goto exit; + if (cfg->int_escan_map || cfg->scan_request) { + brcmf_inform_bss(cfg); +- brcmf_singal_monitor(cfg, ifp); + aborted = status != BRCMF_E_STATUS_SUCCESS; + brcmf_notify_escan_complete(cfg, ifp, aborted, false); + } else +@@ -6256,6 +6220,39 @@ brcmf_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev, + return ret; + } + ++static int ++brcmf_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, ++ s32 rssi_thold, u32 rssi_hyst) ++{ ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_if *ifp; ++ struct wl_rssi_event rssi = {}; ++ int err = 0; ++ ++ ifp = netdev_priv(dev); ++ if (rssi_thold == 0) { ++ cfg->cqm_info.enable = 0; ++ cfg->cqm_info.rssi_threshold = 0; ++ } else { ++ cfg->cqm_info.enable = 1; ++ cfg->cqm_info.rssi_threshold = rssi_thold; ++ ++ rssi.rate_limit_msec = 0; ++ rssi.rssi_levels[rssi.num_rssi_levels++] = S8_MIN; ++ rssi.rssi_levels[rssi.num_rssi_levels++] = ++ cfg->cqm_info.rssi_threshold; ++ rssi.rssi_levels[rssi.num_rssi_levels++] = S8_MAX; ++ } ++ ++ err = brcmf_fil_iovar_data_set(ifp, "rssi_event", &rssi, sizeof(rssi)); ++ if (err < 0) ++ brcmf_err("set rssi_event iovar failed (%d)\n", err); ++ ++ brcmf_dbg(TRACE, "enable = %d, rssi_threshold = %d\n", ++ cfg->cqm_info.enable, cfg->cqm_info.rssi_threshold); ++ return err; ++} ++ + static struct cfg80211_ops brcmf_cfg80211_ops = { + .add_virtual_intf = brcmf_cfg80211_add_iface, + .del_virtual_intf = brcmf_cfg80211_del_iface, +@@ -6305,6 +6302,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = { + .del_pmk = brcmf_cfg80211_del_pmk, + .change_bss = brcmf_cfg80211_change_bss, + .external_auth = brcmf_cfg80211_external_auth, ++ .set_cqm_rssi_config = brcmf_cfg80211_set_cqm_rssi_config, + }; + + struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings) +@@ -7237,6 +7235,34 @@ brcmf_notify_mgmt_tx_status(struct brcmf_if *ifp, + return 0; + } + ++static s32 ++brcmf_notify_rssi_change_ind(struct brcmf_if *ifp, ++ const struct brcmf_event_msg *e, void *data) ++{ ++ struct brcmf_cfg80211_info *cfg = ifp->drvr->config; ++ struct wl_event_data_rssi *value = (struct wl_event_data_rssi *)data; ++ s32 rssi = 0; ++ ++ brcmf_dbg(INFO, "Enter: event %s (%d), status=%d\n", ++ brcmf_fweh_event_name(e->event_code), e->event_code, ++ e->status); ++ ++ if (!cfg->cqm_info.enable) ++ return 0; ++ ++ rssi = ntohl(value->rssi); ++ brcmf_dbg(TRACE, "rssi: %d, threshold: %d, send event(%s)\n", ++ rssi, cfg->cqm_info.rssi_threshold, ++ rssi > cfg->cqm_info.rssi_threshold ? "HIGH" : "LOW"); ++ cfg80211_cqm_rssi_notify(cfg_to_ndev(cfg), ++ (rssi > cfg->cqm_info.rssi_threshold ? ++ NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH : ++ NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW), ++ rssi, GFP_KERNEL); ++ ++ return 0; ++} ++ + static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) + { + conf->frag_threshold = (u32)-1; +@@ -7291,6 +7317,8 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) + brcmf_notify_mgmt_tx_status); + brcmf_fweh_register(cfg->pub, BRCMF_E_MGMT_FRAME_OFF_CHAN_COMPLETE, + brcmf_notify_mgmt_tx_status); ++ brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, ++ brcmf_notify_rssi_change_ind); + } + + static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +index aa4450d3c824..a182a507edb8 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +@@ -202,6 +202,8 @@ enum { + + #define DL_TYPE_CLM 2 + ++#define MAX_RSSI_LEVELS 8 ++ + /* join preference types for join_pref iovar */ + enum brcmf_join_pref_types { + BRCMF_JOIN_PREF_RSSI = 1, +@@ -1111,4 +1113,19 @@ struct brcmf_gscan_config { + struct brcmf_gscan_bucket_config bucket[1]; + }; + ++/* BRCM_E_RSSI event data */ ++struct wl_event_data_rssi { ++ s32 rssi; ++ s32 snr; ++ s32 noise; ++}; ++ ++/** RSSI event notification configuration. */ ++struct wl_rssi_event { ++ u32 rate_limit_msec; ++ u8 num_rssi_levels; ++ s8 rssi_levels[MAX_RSSI_LEVELS]; ++ s8 pad[3]; ++}; ++ + #endif /* FWIL_TYPES_H_ */ +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0128-brcmfmac-add-WPA3_AUTH_1X_SUITE_B_SHA384-related-sup.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0128-brcmfmac-add-WPA3_AUTH_1X_SUITE_B_SHA384-related-sup.patch new file mode 100644 index 000000000..460bdcc7b --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0128-brcmfmac-add-WPA3_AUTH_1X_SUITE_B_SHA384-related-sup.patch @@ -0,0 +1,153 @@ +From 5d3910563d9c6dbf5bbe499bf41155d38c2defae Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Sun, 3 Jul 2022 22:17:45 -0500 +Subject: [PATCH 128/179] brcmfmac: add WPA3_AUTH_1X_SUITE_B_SHA384 related + supporting + +Adding the supporting of GCMP256 and BIP-GMAC_256 of cipher suite. +Adding the supporting of 8021X_SUITE_B_192 of AKM. +Enlarging the MAX PMK LEN dues to the PMK length in Sute-B-192 has become to 48 bytes. + +Fixes: SWLINUX-2712 +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 31 +++++++++++++++++-- + .../broadcom/brcm80211/brcmfmac/fwil_types.h | 3 +- + .../broadcom/brcm80211/include/brcmu_wifi.h | 9 ++++++ + 3 files changed, 39 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 4b5cb64dac72..d03282a73157 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -274,15 +274,21 @@ static const struct ieee80211_regdomain brcmf_regdom = { + * are supported. A pointer to this array and the number of entries is passed + * on to upper layers. AES_CMAC defines whether or not the driver supports MFP. + * So the cipher suite AES_CMAC has to be the last one in the array, and when +- * device does not support MFP then the number of suites will be decreased by 1 ++ * device does not support MFP then the number of suites will be decreased by 4 + */ + static const u32 brcmf_cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, ++ WLAN_CIPHER_SUITE_CCMP_256, ++ WLAN_CIPHER_SUITE_GCMP, ++ WLAN_CIPHER_SUITE_GCMP_256, + /* Keep as last entry: */ +- WLAN_CIPHER_SUITE_AES_CMAC ++ WLAN_CIPHER_SUITE_AES_CMAC, ++ WLAN_CIPHER_SUITE_BIP_CMAC_256, ++ WLAN_CIPHER_SUITE_BIP_GMAC_128, ++ WLAN_CIPHER_SUITE_BIP_GMAC_256 + }; + + /* Vendor specific ie. id = 221, oui and type defines exact ie */ +@@ -2084,6 +2090,9 @@ brcmf_set_wsec_mode(struct net_device *ndev, + case WLAN_CIPHER_SUITE_AES_CMAC: + pval = AES_ENABLED; + break; ++ case WLAN_CIPHER_SUITE_GCMP_256: ++ pval = AES_ENABLED; ++ break; + default: + bphy_err(drvr, "invalid cipher pairwise (%d)\n", + sme->crypto.ciphers_pairwise[0]); +@@ -2105,6 +2114,9 @@ brcmf_set_wsec_mode(struct net_device *ndev, + case WLAN_CIPHER_SUITE_AES_CMAC: + gval = AES_ENABLED; + break; ++ case WLAN_CIPHER_SUITE_GCMP_256: ++ gval = AES_ENABLED; ++ break; + default: + bphy_err(drvr, "invalid cipher group (%d)\n", + sme->crypto.cipher_group); +@@ -2217,6 +2229,9 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + val = WFA_AUTH_DPP; + profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE; + break; ++ case WLAN_AKM_SUITE_8021X_SUITE_B_192: ++ val = WPA3_AUTH_1X_SUITE_B_SHA384; ++ break; + default: + bphy_err(drvr, "invalid cipher group (%d)\n", + sme->crypto.cipher_group); +@@ -3019,6 +3034,16 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, + val = AES_ENABLED; + brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n"); + break; ++ case WLAN_CIPHER_SUITE_GCMP_256: ++ key->algo = CRYPTO_ALGO_AES_GCM256; ++ val = AES_ENABLED; ++ brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_GCMP_256\n"); ++ break; ++ case WLAN_CIPHER_SUITE_BIP_GMAC_256: ++ key->algo = CRYPTO_ALGO_BIP_GMAC256; ++ val = AES_ENABLED; ++ brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_BIP_GMAC_256\n"); ++ break; + default: + bphy_err(drvr, "Invalid cipher (0x%x)\n", params->cipher); + err = -EINVAL; +@@ -8294,7 +8319,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + wiphy->cipher_suites = brcmf_cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites); + if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) +- wiphy->n_cipher_suites--; ++ wiphy->n_cipher_suites -= 4; + wiphy->bss_select_support = BIT(NL80211_BSS_SELECT_ATTR_RSSI) | + BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) | + BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +index a182a507edb8..9e987f229ac8 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +@@ -59,6 +59,7 @@ + #define BRCMF_SCANTYPE_PASSIVE 1 + + #define BRCMF_WSEC_MAX_PSK_LEN 32 ++#define BRCMF_WSEC_MAX_PMK_LEN 64 /* SUITE-B-192's PMK is 48 bytes */ + #define BRCMF_WSEC_PASSPHRASE BIT(0) + + #define BRCMF_WSEC_MAX_SAE_PASSWORD_LEN 128 +@@ -537,7 +538,7 @@ struct brcmf_wsec_key_le { + struct brcmf_wsec_pmk_le { + __le16 key_len; + __le16 flags; +- u8 key[2 * BRCMF_WSEC_MAX_PSK_LEN + 1]; ++ u8 key[2 * BRCMF_WSEC_MAX_PMK_LEN + 1]; + }; + + /** +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +index 38b0b35e602c..04bf1c0b3b06 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +@@ -202,6 +202,13 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec) + #define CRYPTO_ALGO_AES_RESERVED2 6 + #define CRYPTO_ALGO_NALG 7 + ++#define CRYPTO_ALGO_AES_GCM 14 /* 128 bit GCM */ ++#define CRYPTO_ALGO_AES_CCM256 15 /* 256 bit CCM */ ++#define CRYPTO_ALGO_AES_GCM256 16 /* 256 bit GCM */ ++#define CRYPTO_ALGO_BIP_CMAC256 17 /* 256 bit BIP CMAC */ ++#define CRYPTO_ALGO_BIP_GMAC 18 /* 128 bit BIP GMAC */ ++#define CRYPTO_ALGO_BIP_GMAC256 19 /* 256 bit BIP GMAC */ ++ + /* wireless security bitvec */ + + #define WEP_ENABLED 0x0001 +@@ -235,6 +242,8 @@ 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 WPA3_AUTH_1X_SUITE_B_SHA384 0x400000 /* Suite B-192 SHA384 */ ++ + + #define WFA_OUI "\x50\x6F\x9A" /* WFA OUI */ + #define DPP_VER 0x1A /* WFA DPP v1.0 */ +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0129-non-upstream-Handle-the-6G-case-in-the-bw_cap-chansp.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0129-non-upstream-Handle-the-6G-case-in-the-bw_cap-chansp.patch new file mode 100644 index 000000000..d4f3a2abb --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0129-non-upstream-Handle-the-6G-case-in-the-bw_cap-chansp.patch @@ -0,0 +1,108 @@ +From 8edcc5b1fc2926542d9408816ac1b48d263dd673 Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Mon, 4 Jul 2022 05:49:15 -0500 +Subject: [PATCH 129/179] non-upstream: Handle the 6G case in the bw_cap & + chanspecs iovar + +Support send the IOV_BW_CAP ioctl GET req for the 6G band. +Also while processing the response for the IOV_CHANSPECS ioctl +GET req, handle the case of 6G channels to stop the driver +from throwing the "Invalid channel Spec." error for every 6G +channel. + +Signed-off-by: JasonHuang +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 42 +++++++++++++++++-- + 1 file changed, 38 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index d03282a73157..dcbfcbd4f914 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -7537,8 +7537,7 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + u8 *pbuf; + u32 i, j; + u32 total; +- u32 chaninfo, n_2g = 0, n_5g = 0; +- ++ u32 chaninfo, n_2g = 0, n_5g = 0, n_6g = 0; + pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); + + if (pbuf == NULL) +@@ -7558,6 +7557,10 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + for (i = 0; i < band->n_channels; i++) + band->channels[i].flags = IEEE80211_CHAN_DISABLED; + band = wiphy->bands[NL80211_BAND_5GHZ]; ++ if (band) ++ for (i = 0; i < band->n_channels; i++) ++ band->channels[i].flags = IEEE80211_CHAN_DISABLED; ++ band = wiphy->bands[NL80211_BAND_6GHZ]; + if (band) + for (i = 0; i < band->n_channels; i++) + band->channels[i].flags = IEEE80211_CHAN_DISABLED; +@@ -7571,6 +7574,8 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + band = wiphy->bands[NL80211_BAND_2GHZ]; + } else if (ch.band == BRCMU_CHAN_BAND_5G) { + band = wiphy->bands[NL80211_BAND_5GHZ]; ++ } else if (ch.band == BRCMU_CHAN_BAND_6G) { ++ band = wiphy->bands[NL80211_BAND_6GHZ]; + } else { + bphy_err(drvr, "Invalid channel Spec. 0x%x.\n", + ch.chspec); +@@ -7681,6 +7686,26 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + } + wiphy->bands[NL80211_BAND_5GHZ]->n_channels = n_5g; + } ++ band = wiphy->bands[NL80211_BAND_6GHZ]; ++ if (band) { ++ n_6g = band->n_channels; ++ for (i = 0; i < n_6g;) { ++ cur = &band->channels[i]; ++ if (cur->flags == IEEE80211_CHAN_DISABLED) { ++ for (j = i; j < n_6g - 1; j++) { ++ cur = &band->channels[j]; ++ next = &band->channels[j + 1]; ++ memcpy(cur, next, sizeof(*cur)); ++ } ++ /* To avoid fw crash while delete all channels */ ++ if (n_6g == 1) ++ break; ++ n_6g--; ++ } else ++ i++; ++ } ++ wiphy->bands[NL80211_BAND_6GHZ]->n_channels = n_6g; ++ } + + fail_pbuf: + kfree(pbuf); +@@ -7779,7 +7804,13 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) + err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); + if (!err) { + bw_cap[NL80211_BAND_5GHZ] = band; +- return; ++ band = WLC_BAND_6G; ++ err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); ++ if (!err) { ++ bw_cap[NL80211_BAND_6GHZ] = band; ++ return; ++ } ++ WARN_ON(1); + } + WARN_ON(1); + return; +@@ -7945,7 +7976,10 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + struct wiphy *wiphy = cfg_to_wiphy(cfg); + u32 nmode = 0; + u32 vhtmode = 0; +- u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT }; ++ u32 bw_cap[4] = { WLC_BW_20MHZ_BIT, /* 2GHz */ ++ WLC_BW_20MHZ_BIT, /* 5GHz */ ++ 0, /* 60GHz */ ++ WLC_BW_20MHZ_BIT };/* 6GHz */ + u32 rxchain; + u32 nchain; + int err; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0130-net-brcm80211-Fix-race-on-timer_add-in-wifi-driver.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0130-net-brcm80211-Fix-race-on-timer_add-in-wifi-driver.patch new file mode 100644 index 000000000..bf28f3da9 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0130-net-brcm80211-Fix-race-on-timer_add-in-wifi-driver.patch @@ -0,0 +1,33 @@ +From acf44280c4ff09b3264524570598e0dd568f00c8 Mon Sep 17 00:00:00 2001 +From: Michael Trimarchi +Date: Sat, 11 Jun 2022 19:58:39 +0200 +Subject: [PATCH 130/179] net: brcm80211: Fix race on timer_add in wifi driver + +brcmf_sdio_wd_timer must be protected using the +sdio_claim_host and sdio_release_host + +Signed-off-by: Michael Trimarchi +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index 16190d77a115..a86717faafdf 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4780,11 +4780,10 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, + goto checkdied; + } + +- sdio_release_host(sdiod->func1); +- + /* Start the watchdog timer */ + bus->sdcnt.tickcnt = 0; + brcmf_sdio_wd_timer(bus, true); ++ sdio_release_host(sdiod->func1); + + err = brcmf_alloc(sdiod->dev, sdiod->settings); + if (err) { +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0131-Remove-WARN_ON-while-no-6g-bw_cap.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0131-Remove-WARN_ON-while-no-6g-bw_cap.patch new file mode 100644 index 000000000..851cd4dc4 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0131-Remove-WARN_ON-while-no-6g-bw_cap.patch @@ -0,0 +1,28 @@ +From 067daee397765ac4888a9ac64b35b3102210c2f5 Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Mon, 18 Jul 2022 03:19:24 -0500 +Subject: [PATCH 131/179] Remove WARN_ON, while no 6g bw_cap + +Remove kernel warning, due to the 6g bw not common currently. + +Signed-off-by: JasonHuang +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index dcbfcbd4f914..d211a76788b9 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -7810,7 +7810,7 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) + bw_cap[NL80211_BAND_6GHZ] = band; + return; + } +- WARN_ON(1); ++ return; + } + WARN_ON(1); + return; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0132-brcmfmac-update-the-statically-defined-HE-MAC-PHY-Ca.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0132-brcmfmac-update-the-statically-defined-HE-MAC-PHY-Ca.patch new file mode 100644 index 000000000..d968de121 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0132-brcmfmac-update-the-statically-defined-HE-MAC-PHY-Ca.patch @@ -0,0 +1,128 @@ +From e3bef0367adb40d1d02a02442c0d0d6c62439d94 Mon Sep 17 00:00:00 2001 +From: Ian Lin +Date: Wed, 20 Jul 2022 22:00:22 -0500 +Subject: [PATCH 132/179] brcmfmac: update the statically defined HE MAC & PHY + Capab as advertised by FW + +The HE MAC & PHY capabilities statically defined here are not matching with +the actual HE capabilities that are advertised by the FW through Beacons in +the default scenario. + +So update these static definitions by referring the HE IE from the beacons, +to stop incorrect HE capabilities from being registered with cfg80211. + +Signed-off-by: Ian Lin +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 94 ++++++++++++------- + 1 file changed, 58 insertions(+), 36 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index d211a76788b9..3af5b1f0077b 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -7926,44 +7926,66 @@ static void brcmf_update_he_cap(struct ieee80211_supported_band *band, + + data->types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); + he_cap->has_he = true; +- he_cap_elem->mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE; +- if (band->band == NL80211_BAND_5GHZ) { +- he_cap_elem->phy_cap_info[0] = +- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | +- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G | +- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; +- } +- he_cap_elem->phy_cap_info[1] = +- IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; +- he_cap_elem->phy_cap_info[2] = +- IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US; +- he_cap_elem->phy_cap_info[3] = +- IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; +- he_cap_elem->phy_cap_info[4] = +- IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | +- IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK | +- IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4; +- he_cap_elem->phy_cap_info[5] = +- IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2; +- he_cap_elem->phy_cap_info[6] = +- IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | +- IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | +- IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | +- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB | +- IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB | +- IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT; +- he_cap_elem->phy_cap_info[7] = +- IEEE80211_HE_PHY_CAP7_MAX_NC_1; +- he_cap_elem->phy_cap_info[8] = +- IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | +- IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU; +- he_cap_elem->phy_cap_info[9] = +- IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU | +- IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU; ++ ++ /* HE MAC Capabilities Information */ ++ he_cap_elem->mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE | ++ IEEE80211_HE_MAC_CAP0_TWT_REQ | ++ IEEE80211_HE_MAC_CAP0_TWT_RES; ++ ++ he_cap_elem->mac_cap_info[1] = IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_8US | ++ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US; ++ ++ he_cap_elem->mac_cap_info[2] = IEEE80211_HE_MAC_CAP2_BSR | ++ IEEE80211_HE_MAC_CAP2_BCAST_TWT; ++ ++ he_cap_elem->mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_OMI_CONTROL | ++ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 | ++ IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED; ++ ++ he_cap_elem->mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU; ++ ++ ++ /* HE PHY Capabilities Information */ ++ he_cap_elem->phy_cap_info[0] = IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G | ++ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; ++ ++ he_cap_elem->phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; ++ ++ he_cap_elem->phy_cap_info[2] = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | ++ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO | ++ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO; ++ ++ he_cap_elem->phy_cap_info[3] = IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK | ++ IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2 | ++ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM; ++ ++ he_cap_elem->phy_cap_info[4] = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | ++ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8; ++ ++ he_cap_elem->phy_cap_info[5] = IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK | ++ IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK; ++ ++ he_cap_elem->phy_cap_info[6] = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | ++ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | ++ IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | ++ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB | ++ IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB | ++ IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE | ++ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT; ++ ++ he_cap_elem->phy_cap_info[7] = IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI | ++ IEEE80211_HE_PHY_CAP7_MAX_NC_1; ++ ++ he_cap_elem->phy_cap_info[8] = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI | ++ IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G; ++ ++ he_cap_elem->phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU | ++ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | ++ IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB; ++ ++ /* HE Supported MCS and NSS Set */ + he_mcs->rx_mcs_80 = cpu_to_le16(0xfffa); + he_mcs->tx_mcs_80 = cpu_to_le16(0xfffa); +- he_mcs->rx_mcs_160 = cpu_to_le16((0xfffa)); +- he_mcs->tx_mcs_160 = cpu_to_le16((0xfffa)); + + band->n_iftype_data = idx; + band->iftype_data = data; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0133-brcmfmac-fix-set_pmk-warning-message.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0133-brcmfmac-fix-set_pmk-warning-message.patch new file mode 100644 index 000000000..0e20da6ca --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0133-brcmfmac-fix-set_pmk-warning-message.patch @@ -0,0 +1,62 @@ +From be46bb2e14ff9bb6230f9ed528354ecc4ddf260c Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Fri, 29 Jul 2022 00:34:38 -0500 +Subject: [PATCH 133/179] brcmfmac: fix set_pmk warning message + +Fixed warning message while do cfg80211_set_pmk. +Fixed the external supplicant set Suite-B-192 PMK with cfg80211_set_pmksa. + + +Signed-off-by: Carter Chen +--- + .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 11 ++++++++--- + .../wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | 1 + + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 3af5b1f0077b..259252945ca5 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2231,6 +2231,10 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + break; + case WLAN_AKM_SUITE_8021X_SUITE_B_192: + val = WPA3_AUTH_1X_SUITE_B_SHA384; ++ if (sme->want_1x) ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X; ++ else ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_ROAM; + break; + default: + bphy_err(drvr, "invalid cipher group (%d)\n", +@@ -4533,12 +4537,13 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, + return -EINVAL; + } + +- brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid); +- brcmf_dbg(CONN, "%*ph\n", WLAN_PMKID_LEN, pmk[npmk].pmkid); ++ brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[i].bssid); ++ brcmf_dbg(CONN, "%*ph\n", WLAN_PMKID_LEN, pmk[i].pmkid); + + err = brcmf_update_pmklist(cfg, ifp); + +- if (pmksa->pmk_len) { ++ if (pmksa->pmk_len && pmksa->pmk_len < BRCMF_WSEC_PMK_LEN_SUITEB_192) { ++ /* external supplicant stores SUITEB-192 PMK */ + if (ifp->vif->profile.is_okc) { + err = brcmf_fil_iovar_data_set(ifp, "okc_info_pmk", pmksa->pmk, + pmksa->pmk_len); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +index 9e987f229ac8..4365ca9eab5c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +@@ -59,6 +59,7 @@ + #define BRCMF_SCANTYPE_PASSIVE 1 + + #define BRCMF_WSEC_MAX_PSK_LEN 32 ++#define BRCMF_WSEC_PMK_LEN_SUITEB_192 48 + #define BRCMF_WSEC_MAX_PMK_LEN 64 /* SUITE-B-192's PMK is 48 bytes */ + #define BRCMF_WSEC_PASSPHRASE BIT(0) + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0134-brcmfmac-update-BIP-setting-and-wsec_info-for-GMAC-a.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0134-brcmfmac-update-BIP-setting-and-wsec_info-for-GMAC-a.patch new file mode 100644 index 000000000..3876038a1 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0134-brcmfmac-update-BIP-setting-and-wsec_info-for-GMAC-a.patch @@ -0,0 +1,230 @@ +From 4e01b7ded601728934963c032e6cf61d22c75ca6 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Fri, 29 Jul 2022 05:31:55 -0500 +Subject: [PATCH 134/179] brcmfmac: update BIP setting and wsec_info for GMAC + and GCMP + +update BIP setting to firmware by parsing connect information +update wsec_info for GCMP and GMAC + + +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 113 ++++++++++++++++++ + 1 file changed, 113 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 259252945ca5..45d1aae0731b 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -127,6 +127,15 @@ struct cca_msrmnt_query { + u32 time_req; + }; + ++/* algo bit vector */ ++#define KEY_ALGO_MASK(_algo) (1 << (_algo)) ++/* version of the wl_wsec_info structure */ ++#define WL_WSEC_INFO_VERSION 0x01 ++ ++/* start enum value for BSS properties */ ++#define WL_WSEC_INFO_BSS_BASE 0x0100 ++#define WL_WSEC_INFO_BSS_ALGOS (WL_WSEC_INFO_BSS_BASE + 6) ++ + static bool check_vif_up(struct brcmf_cfg80211_vif *vif) + { + if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) { +@@ -355,6 +364,27 @@ struct wl_interface_create_v3 { + u8 data[]; /* Optional for specific data */ + }; + ++/* tlv used to return wl_wsec_info properties */ ++struct wl_wsec_info_tlv { ++ u16 type; ++ u16 len; /* data length */ ++ u8 data[1]; /* data follows */ ++}; ++ ++/* input/output data type for wsec_info iovar */ ++struct wl_wsec_info { ++ u8 version; /* structure version */ ++ u8 pad[2]; ++ u8 num_tlvs; ++ struct wl_wsec_info_tlv tlvs[1]; /* tlv data follows */ ++}; ++ ++struct bcm_xtlv { ++ u16 id; ++ u16 len; ++ u8 data[1]; ++}; ++ + static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg); + static bool + wl_cfgoce_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len, +@@ -365,6 +395,50 @@ wl_cfgoce_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len, + wl_cfgoce_has_ie(ie, tlvs, len, \ + (const u8 *)WFA_OUI, TLV_OUI_LEN, WFA_OUI_TYPE_MBO_OCE) + ++static s32 ++wl_set_wsec_info_algos(struct brcmf_if *ifp, u32 algos, u32 mask) ++{ ++ struct brcmf_pub *drvr = ifp->drvr; ++ s32 err = 0; ++ struct wl_wsec_info *wsec_info; ++ struct bcm_xtlv *wsec_info_tlv; ++ u16 tlv_data_len; ++ u8 tlv_data[8]; ++ u32 param_len; ++ u8 *buf; ++ ++ brcmf_dbg(TRACE, "Enter\n"); ++ ++ buf = kzalloc(sizeof(struct wl_wsec_info) + sizeof(tlv_data), GFP_KERNEL); ++ if (!buf) { ++ bphy_err(drvr, "unable to allocate.\n"); ++ return -ENOMEM; ++ } ++ ++ wsec_info = (struct wl_wsec_info *)buf; ++ wsec_info->version = WL_WSEC_INFO_VERSION; ++ wsec_info_tlv = (struct bcm_xtlv *)(buf + offsetof(struct wl_wsec_info, tlvs)); ++ ++ wsec_info->num_tlvs++; ++ tlv_data_len = sizeof(tlv_data); ++ memcpy(tlv_data, &algos, sizeof(algos)); ++ memcpy(tlv_data + sizeof(algos), &mask, sizeof(mask)); ++ ++ wsec_info_tlv->id = cpu_to_le16(WL_WSEC_INFO_BSS_ALGOS); ++ wsec_info_tlv->len = cpu_to_le16(tlv_data_len); ++ memcpy(wsec_info_tlv->data, tlv_data, tlv_data_len); ++ ++ param_len = offsetof(struct wl_wsec_info, tlvs) + ++ offsetof(struct wl_wsec_info_tlv, data) + tlv_data_len; ++ ++ err = brcmf_fil_bsscfg_data_set(ifp, "wsec_info", buf, param_len); ++ if (err) ++ brcmf_err("set wsec_info_error:%d\n", err); ++ ++ kfree(buf); ++ return err; ++} ++ + /* Is any of the tlvs the expected entry? If + * not update the tlvs buffer pointer/length. + */ +@@ -2074,6 +2148,8 @@ brcmf_set_wsec_mode(struct net_device *ndev, + s32 gval = 0; + s32 wsec; + s32 err = 0; ++ u32 algos = 0, mask = 0; ++ + + if (sme->crypto.n_ciphers_pairwise) { + switch (sme->crypto.ciphers_pairwise[0]) { +@@ -2092,6 +2168,8 @@ brcmf_set_wsec_mode(struct net_device *ndev, + break; + case WLAN_CIPHER_SUITE_GCMP_256: + pval = AES_ENABLED; ++ algos = KEY_ALGO_MASK(CRYPTO_ALGO_AES_GCM256); ++ mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM); + break; + default: + bphy_err(drvr, "invalid cipher pairwise (%d)\n", +@@ -2116,6 +2194,8 @@ brcmf_set_wsec_mode(struct net_device *ndev, + break; + case WLAN_CIPHER_SUITE_GCMP_256: + gval = AES_ENABLED; ++ algos = KEY_ALGO_MASK(CRYPTO_ALGO_AES_GCM256); ++ mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM); + break; + default: + bphy_err(drvr, "invalid cipher group (%d)\n", +@@ -2125,6 +2205,7 @@ brcmf_set_wsec_mode(struct net_device *ndev, + } + + brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval); ++ brcmf_dbg(CONN, "algos (0x%x) mask (0x%x)\n", algos, mask); + /* In case of privacy, but no security and WPS then simulate */ + /* setting AES. WPS-2.0 allows no security */ + if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval && +@@ -2138,6 +2219,12 @@ brcmf_set_wsec_mode(struct net_device *ndev, + return err; + } + ++ err = wl_set_wsec_info_algos(ifp, algos, mask); ++ if (err) { ++ bphy_err(drvr, "set wsec_info error (%d)\n", err); ++ return err; ++ } ++ + sec = &profile->sec; + sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0]; + sec->cipher_group = sme->crypto.cipher_group; +@@ -2161,6 +2248,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + u16 rsn_cap; + u32 mfp; + u16 count; ++ u16 pmkid_count; ++ const u8 *group_mgmt_cs = NULL; + + profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE; + profile->is_ft = false; +@@ -2327,6 +2416,20 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + mfp = BRCMF_MFP_CAPABLE; + brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp); + ++ offset += RSN_CAP_LEN; ++ if (mfp && (ie_len - offset >= RSN_PMKID_COUNT_LEN)) { ++ pmkid_count = ie[offset] + (ie[offset + 1] << 8); ++ offset += RSN_PMKID_COUNT_LEN + (pmkid_count * WLAN_PMKID_LEN); ++ if (ie_len - offset >= WPA_IE_MIN_OUI_LEN) { ++ group_mgmt_cs = &ie[offset]; ++ if (memcmp(group_mgmt_cs, RSN_OUI, TLV_OUI_LEN) == 0) { ++ brcmf_fil_bsscfg_data_set(ifp, "bip", ++ (void *)group_mgmt_cs, ++ WPA_IE_MIN_OUI_LEN); ++ } ++ } ++ } ++ + skip_mfp_config: + brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val); + err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val); +@@ -2957,6 +3060,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, + s32 err; + u8 keybuf[8]; + bool ext_key; ++ u32 algos = 0, mask = 0; + + brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(CONN, "key index (%d)\n", key_idx); +@@ -3042,10 +3146,14 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, + key->algo = CRYPTO_ALGO_AES_GCM256; + val = AES_ENABLED; + brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_GCMP_256\n"); ++ algos = KEY_ALGO_MASK(CRYPTO_ALGO_AES_GCM256); ++ mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM); + break; + case WLAN_CIPHER_SUITE_BIP_GMAC_256: + key->algo = CRYPTO_ALGO_BIP_GMAC256; + val = AES_ENABLED; ++ algos = KEY_ALGO_MASK(CRYPTO_ALGO_BIP_GMAC256); ++ mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM); + brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_BIP_GMAC_256\n"); + break; + default: +@@ -3070,6 +3178,11 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, + goto done; + } + ++ brcmf_dbg(CONN, "algos (0x%x) mask (0x%x)\n", algos, mask); ++ err = wl_set_wsec_info_algos(ifp, algos, mask); ++ if (err) ++ bphy_err(drvr, "set wsec_info error (%d)\n", err); ++ + done: + brcmf_dbg(TRACE, "Exit\n"); + return err; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0135-brcmfmac-send-roam-request-when-supplicant-triggers-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0135-brcmfmac-send-roam-request-when-supplicant-triggers-.patch new file mode 100644 index 000000000..9d9128bdf --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0135-brcmfmac-send-roam-request-when-supplicant-triggers-.patch @@ -0,0 +1,50 @@ +From 2691650d64df9043a85ded6e787eafcf881ccf27 Mon Sep 17 00:00:00 2001 +From: Suresh Sanaboina +Date: Fri, 22 Jul 2022 09:47:48 -0500 +Subject: [PATCH 135/179] brcmfmac: send roam request when supplicant triggers + reassoc + +Sending assoc request to fw on reassoc would disassoc prev bssid +and then assoc to target AP. Supplicant sets prev bssid when it +tries to reassoc to new target AP. +Based on prev bssid set, sending reassoc request to FW to allow +STA smooth roam to target AP without disassoc. + +Signed-off-by: Suresh Sanaboina +--- + .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 12 ++++++++++-- + 1 file 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 45d1aae0731b..e27b9b3471b8 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2830,8 +2830,15 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, + + brcmf_set_join_pref(ifp, &sme->bss_select); + +- err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params, +- join_params_size); ++ if (sme->prev_bssid) { ++ brcmf_dbg(CONN, "Trying to REASSOC\n"); ++ join_params_size = sizeof(ext_join_params->assoc_le); ++ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_REASSOC, ++ &ext_join_params->assoc_le, join_params_size); ++ } else { ++ err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params, ++ join_params_size); ++ } + kfree(ext_join_params); + if (!err) + /* This is it. join command worked, we are done */ +@@ -6923,6 +6930,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, + cfg80211_roamed(ndev, &roam_info, GFP_KERNEL); + brcmf_dbg(CONN, "Report roaming result\n"); + ++ clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); + set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); + brcmf_dbg(TRACE, "Exit\n"); + return err; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0136-brcmfmac-send-BCNLOST_MSG-event-on-beacon-loss-for-s.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0136-brcmfmac-send-BCNLOST_MSG-event-on-beacon-loss-for-s.patch new file mode 100644 index 000000000..d1fd5dd67 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0136-brcmfmac-send-BCNLOST_MSG-event-on-beacon-loss-for-s.patch @@ -0,0 +1,68 @@ +From bf7163842721e1318c57dc26afc1b8e9dd91871a Mon Sep 17 00:00:00 2001 +From: "Sanaboina Suresh (IFINS CSS ICW ENG SW WFSW 1)" + +Date: Thu, 4 Aug 2022 06:23:36 +0000 +Subject: [PATCH 136/179] brcmfmac: send BCNLOST_MSG event on beacon loss for + supplicant roaming + +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 36 +++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index e27b9b3471b8..26a18df345c2 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -7414,6 +7414,40 @@ brcmf_notify_rssi_change_ind(struct brcmf_if *ifp, + return 0; + } + ++static s32 ++brcmf_notify_beacon_loss(struct brcmf_if *ifp, ++ const struct brcmf_event_msg *e, void *data) ++{ ++ struct brcmf_cfg80211_info *cfg = ifp->drvr->config; ++ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; ++ struct cfg80211_bss *bss; ++ ++ brcmf_dbg(INFO, "Enter: event %s (%d), status=%d\n", ++ brcmf_fweh_event_name(e->event_code), e->event_code, ++ e->status); ++ ++ if (!ifp->drvr->settings->roamoff) ++ return 0; ++ ++ /* On beacon loss event, Supplicant triggers new scan request ++ * with NL80211_SCAN_FLAG_FLUSH Flag set, but lost AP bss entry ++ * still remained as it is held by cfg as associated. Unlinking this ++ * current BSS from cfg cached bss list on beacon loss event here, ++ * would allow supplicant to receive new scanned entries ++ * without current bss and select new bss to trigger roam. ++ */ ++ bss = cfg80211_get_bss(cfg->wiphy, NULL, profile->bssid, 0, 0, ++ IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); ++ if (bss) { ++ cfg80211_unlink_bss(cfg->wiphy, bss); ++ cfg80211_put_bss(cfg->wiphy, bss); ++ } ++ ++ cfg80211_cqm_beacon_loss_notify(cfg_to_ndev(cfg), GFP_KERNEL); ++ ++ return 0; ++} ++ + static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) + { + conf->frag_threshold = (u32)-1; +@@ -7470,6 +7504,8 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) + brcmf_notify_mgmt_tx_status); + brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, + brcmf_notify_rssi_change_ind); ++ brcmf_fweh_register(cfg->pub, BRCMF_E_BCNLOST_MSG, ++ brcmf_notify_beacon_loss); + } + + static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0137-brcmfmac-trying-to-get-GCMP-cap-before-doing-set-it.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0137-brcmfmac-trying-to-get-GCMP-cap-before-doing-set-it.patch new file mode 100644 index 000000000..2cb5d2f2e --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0137-brcmfmac-trying-to-get-GCMP-cap-before-doing-set-it.patch @@ -0,0 +1,143 @@ +From b30da6315383a927ed10cb6e3e93e7ec9f5a817a Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Thu, 11 Aug 2022 02:02:24 -0500 +Subject: [PATCH 137/179] brcmfmac: trying to get GCMP cap before doing set it + +trying to get GCMP cp to make sure the firmware supports it before set. + + +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 45 +++++++++++++++---- + .../broadcom/brcm80211/brcmfmac/feature.c | 1 + + .../broadcom/brcm80211/brcmfmac/feature.h | 4 +- + 3 files changed, 41 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 26a18df345c2..126843b4483d 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2167,6 +2167,10 @@ brcmf_set_wsec_mode(struct net_device *ndev, + pval = AES_ENABLED; + break; + case WLAN_CIPHER_SUITE_GCMP_256: ++ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) { ++ brcmf_err("the low layer not support GCMP\n"); ++ return -EOPNOTSUPP; ++ } + pval = AES_ENABLED; + algos = KEY_ALGO_MASK(CRYPTO_ALGO_AES_GCM256); + mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM); +@@ -2193,6 +2197,10 @@ brcmf_set_wsec_mode(struct net_device *ndev, + gval = AES_ENABLED; + break; + case WLAN_CIPHER_SUITE_GCMP_256: ++ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) { ++ brcmf_err("the low layer not support GCMP\n"); ++ return -EOPNOTSUPP; ++ } + gval = AES_ENABLED; + algos = KEY_ALGO_MASK(CRYPTO_ALGO_AES_GCM256); + mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM); +@@ -2219,10 +2227,15 @@ brcmf_set_wsec_mode(struct net_device *ndev, + return err; + } + +- err = wl_set_wsec_info_algos(ifp, algos, mask); +- if (err) { +- bphy_err(drvr, "set wsec_info error (%d)\n", err); +- return err; ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) { ++ brcmf_dbg(CONN, ++ "set_wsdec_info algos (0x%x) mask (0x%x)\n", ++ algos, mask); ++ err = wl_set_wsec_info_algos(ifp, algos, mask); ++ if (err) { ++ brcmf_err("set wsec_info error (%d)\n", err); ++ return err; ++ } + } + + sec = &profile->sec; +@@ -3150,6 +3163,11 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, + brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n"); + break; + case WLAN_CIPHER_SUITE_GCMP_256: ++ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) { ++ brcmf_err("the low layer not support GCMP\n"); ++ err = -EOPNOTSUPP; ++ goto done; ++ } + key->algo = CRYPTO_ALGO_AES_GCM256; + val = AES_ENABLED; + brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_GCMP_256\n"); +@@ -3157,6 +3175,11 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, + mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM); + break; + case WLAN_CIPHER_SUITE_BIP_GMAC_256: ++ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) { ++ brcmf_err("the low layer not support GCMP\n"); ++ err = -EOPNOTSUPP; ++ goto done; ++ } + key->algo = CRYPTO_ALGO_BIP_GMAC256; + val = AES_ENABLED; + algos = KEY_ALGO_MASK(CRYPTO_ALGO_BIP_GMAC256); +@@ -3185,10 +3208,16 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, + goto done; + } + +- brcmf_dbg(CONN, "algos (0x%x) mask (0x%x)\n", algos, mask); +- err = wl_set_wsec_info_algos(ifp, algos, mask); +- if (err) +- bphy_err(drvr, "set wsec_info error (%d)\n", err); ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) { ++ brcmf_dbg(CONN, ++ "set_wsdec_info algos (0x%x) mask (0x%x)\n", ++ algos, mask); ++ err = wl_set_wsec_info_algos(ifp, algos, mask); ++ if (err) { ++ brcmf_err("set wsec_info error (%d)\n", err); ++ return err; ++ } ++ } + + done: + brcmf_dbg(TRACE, "Exit\n"); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +index f6e1f664c595..08535a5e61fe 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -45,6 +45,7 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = { + { BRCMF_FEAT_SAE_EXT, "sae_ext " }, + { BRCMF_FEAT_FBT, "fbt " }, + { BRCMF_FEAT_OKC, "okc" }, ++ { BRCMF_FEAT_GCMP, "gcmp" }, + }; + + #ifdef DEBUG +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +index 6f9f9e0b60b5..a81cabd975ce 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +@@ -31,6 +31,7 @@ + * FWAUTH: Firmware authenticator + * DUMP_OBSS: Firmware has capable to dump obss info to support ACS + * SAE_EXT: SAE be handled by userspace supplicant ++ * GCMP: firmware has defined GCMP or not. + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ +@@ -57,7 +58,8 @@ + BRCMF_FEAT_DEF(DUMP_OBSS) \ + BRCMF_FEAT_DEF(SAE_EXT) \ + BRCMF_FEAT_DEF(FBT) \ +- BRCMF_FEAT_DEF(OKC) ++ BRCMF_FEAT_DEF(OKC) \ ++ BRCMF_FEAT_DEF(GCMP) + + /* + * Quirks: +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0138-brcmfmac-update-firmware-loading-name-for-CY5557x.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0138-brcmfmac-update-firmware-loading-name-for-CY5557x.patch new file mode 100644 index 000000000..1600bb0d6 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0138-brcmfmac-update-firmware-loading-name-for-CY5557x.patch @@ -0,0 +1,291 @@ +From b75d5ec44a88800e209103d86ed213c950854ad3 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Thu, 25 Aug 2022 02:33:13 -0500 +Subject: [PATCH 138/179] brcmfmac: update firmware loading name for CY5557x + +Updating the firmware/nvram/clm_blob name to loading for CY5557x series. +Changing all naming of 55560 to 55572. + +CY55571, CY55573 use the same PID as 55572. + + +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 +++---- + .../broadcom/brcm80211/brcmfmac/chip.c | 22 ++++++++--------- + .../broadcom/brcm80211/brcmfmac/pcie.c | 14 +++++------ + .../broadcom/brcm80211/brcmfmac/sdio.c | 24 +++++++++---------- + .../broadcom/brcm80211/include/brcm_hw_ids.h | 4 ++-- + include/linux/mmc/sdio_ids.h | 2 +- + 6 files changed, 37 insertions(+), 37 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +index d6ee946cc45c..991348836af7 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -48,7 +48,7 @@ + #define SDIO_435X_FUNC2_BLOCKSIZE 256 + #define SDIO_4329_FUNC2_BLOCKSIZE 128 + #define SDIO_89459_FUNC2_BLOCKSIZE 256 +-#define SDIO_CYW55560_FUNC2_BLOCKSIZE 256 ++#define SDIO_CYW55572_FUNC2_BLOCKSIZE 256 + + /* Maximum milliseconds to wait for F2 to come up */ + #define SDIO_WAIT_F2RDY 3000 +@@ -935,8 +935,8 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) + case SDIO_DEVICE_ID_CYPRESS_54594: + f2_blksz = SDIO_89459_FUNC2_BLOCKSIZE; + break; +- case SDIO_DEVICE_ID_CYPRESS_55560: +- f2_blksz = SDIO_CYW55560_FUNC2_BLOCKSIZE; ++ case SDIO_DEVICE_ID_CYPRESS_55572: ++ f2_blksz = SDIO_CYW55572_FUNC2_BLOCKSIZE; + break; + default: + break; +@@ -1014,7 +1014,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { + CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_54590), + CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_54591), + CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_54594), +- CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_55560), ++ CYF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_55572), + { /* end: all zeroes */ } + }; + MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +index b85e856bfc70..2367946b9ff0 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -233,11 +233,11 @@ struct sbsocramregs { + /* Minimum PMU resource mask for 4373 */ + #define CY_4373_PMU_MIN_RES_MASK 0xFCAFF7F + +-/* CYW55560 dedicated space and RAM base */ +-#define CYW55560_TCAM_SIZE 0x800 +-#define CYW55560_TRXHDR_SIZE 0x2b4 +-#define CYW55560_RAM_BASE (0x370000 + \ +- CYW55560_TCAM_SIZE + CYW55560_TRXHDR_SIZE) ++/* CYW55572 dedicated space and RAM base */ ++#define CYW55572_TCAM_SIZE 0x800 ++#define CYW55572_TRXHDR_SIZE 0x2b4 ++#define CYW55572_RAM_BASE (0x370000 + \ ++ CYW55572_TCAM_SIZE + CYW55572_TRXHDR_SIZE) + + #define BRCMF_BLHS_POLL_INTERVAL 10 /* msec */ + #define BRCMF_BLHS_D2H_READY_TIMEOUT 100 /* msec */ +@@ -778,8 +778,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci) + return 0x170000; + case CY_CC_89459_CHIP_ID: + return ((ci->pub.chiprev < 9) ? 0x180000 : 0x160000); +- case CY_CC_55560_CHIP_ID: +- return CYW55560_RAM_BASE; ++ case CY_CC_55572_CHIP_ID: ++ return CYW55572_RAM_BASE; + default: + brcmf_err("unknown chip: %s\n", ci->pub.name); + break; +@@ -798,9 +798,9 @@ int brcmf_chip_get_raminfo(struct brcmf_chip *pub) + if (mem) { + mem_core = container_of(mem, struct brcmf_core_priv, pub); + ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core); +- if (ci->pub.chip == CY_CC_55560_CHIP_ID) +- ci->pub.ramsize -= (CYW55560_TCAM_SIZE + +- CYW55560_TRXHDR_SIZE); ++ if (ci->pub.chip == CY_CC_55572_CHIP_ID) ++ ci->pub.ramsize -= (CYW55572_TCAM_SIZE + ++ CYW55572_TRXHDR_SIZE); + ci->pub.rambase = brcmf_chip_tcm_rambase(ci); + if (ci->pub.rambase == INVALID_RAMBASE) { + brcmf_err("RAM base not provided with ARM CR4 core\n"); +@@ -1641,7 +1641,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_55560_CHIP_ID: ++ case CY_CC_55572_CHIP_ID: + case CY_CC_89459_CHIP_ID: + /* explicitly check SR engine enable bit */ + addr = CORE_CC_REG(base, sr_control0); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index a1332df9d495..e0657c369e12 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -64,7 +64,7 @@ BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); + BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); + BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); + CY_FW_DEF(4355, "cyfmac54591-pcie"); +-CY_FW_TRXSE_DEF(55560, "cyfmac55560-pcie"); ++CY_FW_TRXSE_DEF(55572, "cyfmac55572-pcie"); + CY_FW_DEF(4373, "cyfmac4373-pcie"); + + /* firmware config files */ +@@ -95,7 +95,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_55560_CHIP_ID, 0xFFFFFFFF, 55560), ++ BRCMF_FW_ENTRY(CY_CC_55572_CHIP_ID, 0xFFFFFFFF, 55572), + BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373), + }; + +@@ -114,7 +114,7 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + + #define BRCMF_PCIE_BAR0_WRAPBASE_DMP_OFFSET 0x1000 + #define BRCMF_PCIE_BAR0_PCIE_ENUM_OFFSET 0x2000 +-#define BRCMF_CYW55560_PCIE_BAR0_PCIE_ENUM_OFFSET 0x3000 ++#define BRCMF_CYW55572_PCIE_BAR0_PCIE_ENUM_OFFSET 0x3000 + + #define BRCMF_PCIE_ARMCR4REG_BANKIDX 0x40 + #define BRCMF_PCIE_ARMCR4REG_BANKPDA 0x4C +@@ -2107,7 +2107,7 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + devinfo->nvram_name); + } + +- if (devinfo->ci->chip == CY_CC_55560_CHIP_ID) { ++ if (devinfo->ci->chip == CY_CC_55572_CHIP_ID) { + /* Write the length token to the last word of RAM address */ + brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, + cpu_to_le32(nvram_csm)); +@@ -2317,8 +2317,8 @@ static int brcmf_pcie_buscore_blhs_attach(void *ctx, struct brcmf_blhs **blhs, + blhsh->write = brcmf_pcie_buscore_blhs_write; + + /* Host indication for bootloarder to start the init */ +- if (devinfo->pdev->device == CY_PCIE_55560_DEVICE_ID) +- pcie_enum = BRCMF_CYW55560_PCIE_BAR0_PCIE_ENUM_OFFSET; ++ if (devinfo->pdev->device == CY_PCIE_55572_DEVICE_ID) ++ pcie_enum = BRCMF_CYW55572_PCIE_BAR0_PCIE_ENUM_OFFSET; + else + pcie_enum = BRCMF_PCIE_BAR0_PCIE_ENUM_OFFSET; + +@@ -2881,7 +2881,7 @@ static const struct pci_device_id brcmf_pcie_devid_table[] = { + BRCMF_PCIE_DEVICE(CY_PCIE_54591_DEVICE_ID), + BRCMF_PCIE_DEVICE(CY_PCIE_54590_DEVICE_ID), + BRCMF_PCIE_DEVICE(CY_PCIE_54594_DEVICE_ID), +- BRCMF_PCIE_DEVICE_CY(CY_PCIE_55560_DEVICE_ID), ++ BRCMF_PCIE_DEVICE_CY(CY_PCIE_55572_DEVICE_ID), + BRCMF_PCIE_DEVICE(CY_PCIE_4373_RAW_DEVICE_ID), + BRCMF_PCIE_DEVICE(CY_PCIE_4373_DUAL_DEVICE_ID), + BRCMF_PCIE_DEVICE(CY_PCIE_4373_2G_DEVICE_ID), +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index a86717faafdf..7b80a4e54726 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -70,9 +70,9 @@ + #define CY_89459_MES_WATERMARK 0x40 + #define CY_89459_MESBUSYCTRL (CY_89459_MES_WATERMARK | \ + SBSDIO_MESBUSYCTRL_ENAB) +-#define CYW55560_F2_WATERMARK 0x40 +-#define CYW55560_MES_WATERMARK 0x40 +-#define CYW55560_F1_MESBUSYCTRL (CYW55560_MES_WATERMARK | \ ++#define CYW55572_F2_WATERMARK 0x40 ++#define CYW55572_MES_WATERMARK 0x40 ++#define CYW55572_F1_MESBUSYCTRL (CYW55572_MES_WATERMARK | \ + SBSDIO_MESBUSYCTRL_ENAB) + + #ifdef DEBUG +@@ -651,7 +651,7 @@ 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"); +-CY_FW_TRXSE_DEF(55560, "cyfmac55560-sdio"); ++CY_FW_TRXSE_DEF(55572, "cyfmac55572-sdio"); + + /* firmware config files */ + MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.txt"); +@@ -686,7 +686,7 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { + 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_89459_CHIP_ID, 0xFFFFFFFF, 89459), +- BRCMF_FW_ENTRY(CY_CC_55560_CHIP_ID, 0xFFFFFFFF, 55560) ++ BRCMF_FW_ENTRY(CY_CC_55572_CHIP_ID, 0xFFFFFFFF, 55572) + }; + + #define TXCTL_CREDITS 2 +@@ -748,7 +748,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) + * bit, to avoid polling of KSO bit. + */ + if (!on && ((bus->ci->chip == CY_CC_43012_CHIP_ID) || +- (bus->ci->chip == CY_CC_55560_CHIP_ID))) ++ (bus->ci->chip == CY_CC_55572_CHIP_ID))) + return err; + + if (on) { +@@ -2551,7 +2551,7 @@ static bool brcmf_chip_is_ulp(struct brcmf_chip *ci) + static bool brcmf_sdio_use_ht_avail(struct brcmf_chip *ci) + { + if (ci->chip == CY_CC_4373_CHIP_ID || +- ci->chip == CY_CC_55560_CHIP_ID) ++ ci->chip == CY_CC_55572_CHIP_ID) + return true; + else + return false; +@@ -3745,7 +3745,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 == CY_CC_55560_CHIP_ID || ++ bus->ci->chip == CY_CC_55572_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 || +@@ -4727,18 +4727,18 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, + brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_MESBUSYCTRL, + CY_89459_MESBUSYCTRL, &err); + break; +- case SDIO_DEVICE_ID_CYPRESS_55560: ++ case SDIO_DEVICE_ID_CYPRESS_55572: + brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n", +- CYW55560_F2_WATERMARK); ++ CYW55572_F2_WATERMARK); + brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, +- CYW55560_F2_WATERMARK, &err); ++ CYW55572_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, +- CYW55560_F1_MESBUSYCTRL, &err); ++ CYW55572_F1_MESBUSYCTRL, &err); + break; + default: + brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, +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 9e4daf21887c..eb476b245491 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -57,7 +57,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_55560_CHIP_ID 0xd908 ++#define CY_CC_55572_CHIP_ID 0xd908 + + /* USB Device IDs */ + #define BRCM_USB_43143_DEVICE_ID 0xbd1e +@@ -96,7 +96,7 @@ + #define CY_PCIE_54591_DEVICE_ID 0x4417 + #define CY_PCIE_54590_DEVICE_ID 0x4416 + #define CY_PCIE_54594_DEVICE_ID 0x441a +-#define CY_PCIE_55560_DEVICE_ID 0xbd31 ++#define CY_PCIE_55572_DEVICE_ID 0xbd31 + #define CY_PCIE_4373_RAW_DEVICE_ID 0x4373 + #define CY_PCIE_4373_DUAL_DEVICE_ID 0x4418 + #define CY_PCIE_4373_2G_DEVICE_ID 0x4419 +diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h +index 937264165319..3a261681ff0b 100644 +--- a/include/linux/mmc/sdio_ids.h ++++ b/include/linux/mmc/sdio_ids.h +@@ -83,7 +83,7 @@ + #define SDIO_DEVICE_ID_CYPRESS_54591 0xbd3b + #define SDIO_DEVICE_ID_CYPRESS_54594 0xbd3c + #define SDIO_DEVICE_ID_CYPRESS_43439 0xbd3d +-#define SDIO_DEVICE_ID_CYPRESS_55560 0xbd31 ++#define SDIO_DEVICE_ID_CYPRESS_55572 0xbd31 + + #define SDIO_VENDOR_ID_MARVELL 0x02df + #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0139-brcmfmac-use-SR-core-id-to-decide-SR-capability-for-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0139-brcmfmac-use-SR-core-id-to-decide-SR-capability-for-.patch new file mode 100644 index 000000000..8b58c318f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0139-brcmfmac-use-SR-core-id-to-decide-SR-capability-for-.patch @@ -0,0 +1,82 @@ +From 46f8fe2ca95e2e7c73618efe7cbbfddf5f8aece1 Mon Sep 17 00:00:00 2001 +From: Owen Huang +Date: Fri, 2 Sep 2022 00:38:21 -0500 +Subject: [PATCH 139/179] brcmfmac: use SR core id to decide SR capability for + CY55572 + +Use SR core id to decide SR capability for CY55572. + +Signed-off-by: Owen Huang +--- + .../broadcom/brcm80211/brcmfmac/chip.c | 21 +++++++++++++++++-- + include/linux/bcma/bcma.h | 1 + + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +index 2367946b9ff0..750a7e44e21c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -544,6 +544,21 @@ char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len) + return buf; + } + ++static bool brcmf_chip_find_coreid(struct brcmf_chip_priv *ci, u16 coreid) ++{ ++ struct brcmf_core_priv *core; ++ ++ list_for_each_entry(core, &ci->cores, list) { ++ brcmf_dbg(TRACE, " core 0x%x:%-2d base 0x%08x wrap 0x%08x\n", ++ core->pub.id, core->pub.rev, core->pub.base, ++ core->wrapbase); ++ if (core->pub.id == coreid) ++ return true; ++ } ++ ++ return false; ++} ++ + static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip_priv *ci, + u16 coreid, u32 base, + u32 wrapbase) +@@ -980,7 +995,8 @@ int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci) + /* need core with ports */ + if (nmw + nsw == 0 && + id != BCMA_CORE_PMU && +- id != BCMA_CORE_GCI) ++ id != BCMA_CORE_GCI && ++ id != BCMA_CORE_SR) + continue; + + /* try to obtain register address info */ +@@ -1641,7 +1657,6 @@ 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_55572_CHIP_ID: + case CY_CC_89459_CHIP_ID: + /* explicitly check SR engine enable bit */ + addr = CORE_CC_REG(base, sr_control0); +@@ -1654,6 +1669,8 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub) + reg = chip->ops->read32(chip->ctx, addr); + return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK | + PMU_RCTL_LOGIC_DISABLE_MASK)) == 0; ++ case CY_CC_55572_CHIP_ID: ++ return brcmf_chip_find_coreid(chip, BCMA_CORE_SR); + default: + addr = CORE_CC_REG(pmu->base, pmucapabilities_ext); + reg = chip->ops->read32(chip->ctx, addr); +diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h +index 60b94b944e9f..fe1cb2aeaef3 100644 +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -154,6 +154,7 @@ struct bcma_host_ops { + #define BCMA_CORE_USB30_DEV 0x83D + #define BCMA_CORE_ARM_CR4 0x83E + #define BCMA_CORE_GCI 0x840 ++#define BCMA_CORE_SR 0x841 + #define BCMA_CORE_CMEM 0x846 /* CNDS DDR2/3 memory controller */ + #define BCMA_CORE_ARM_CA7 0x847 + #define BCMA_CORE_SYS_MEM 0x849 +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0140-brcmfmac-SAP-mode-parsing-sae_h2e-setting-from-beaco.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0140-brcmfmac-SAP-mode-parsing-sae_h2e-setting-from-beaco.patch new file mode 100644 index 000000000..da3f0587d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0140-brcmfmac-SAP-mode-parsing-sae_h2e-setting-from-beaco.patch @@ -0,0 +1,124 @@ +From 8eec3397f4b89dcab93e558b50a027cf041a8b38 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Thu, 15 Sep 2022 01:18:49 -0500 +Subject: [PATCH 140/179] brcmfmac: SAP mode parsing sae_h2e setting from + beacon data + +While the SAP mode is with ext_sae firmware build string, +we need to set extsae_pwe parameter to firmware. + +Parsing the information from the supported rate/extended support rate +and RSNX ie which are in the beacon data. + + +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 78 +++++++++++++++++++ + 1 file changed, 78 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 126843b4483d..31707d9f3715 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -107,6 +107,11 @@ + #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ + (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) + ++#define BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY 123 ++#define BSS_MEMBERSHIP_SELECTOR_SET 0x80 ++#define SAE_H2E_ONLY_ENABLE (BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY | \ ++ BSS_MEMBERSHIP_SELECTOR_SET) ++ + struct brcmf_dump_survey { + u32 obss; + u32 ibss; +@@ -5355,6 +5360,75 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif, + return err; + } + ++static s32 ++brcmf_parse_configure_sae_pwe(struct brcmf_if *ifp, ++ struct cfg80211_ap_settings *settings) ++{ ++ s32 err = 0; ++ const struct brcmf_tlv *rsnx_ie; ++ const struct brcmf_tlv *ext_rate_ie; ++ const struct brcmf_tlv *supp_rate_ie; ++ u8 ie_len, i; ++ bool support_sae_h2e = false, must_sae_h2e = false; ++ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE_EXT)) { ++ rsnx_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, ++ settings->beacon.tail_len, ++ WLAN_EID_RSNX); ++ if (rsnx_ie) { ++ ie_len = rsnx_ie->len; ++ if (ie_len) { ++ if (rsnx_ie->data[0] & WLAN_RSNX_CAPA_SAE_H2E) ++ support_sae_h2e = true; ++ } ++ brcmf_dbg(INFO, "found RSNX IE, support_sae_h2e:%d\n", ++ support_sae_h2e); ++ } ++ ++ /* found rsnx_ie with SAE_H2E, check the bss selector to know if it is a H2E only */ ++ if (support_sae_h2e) { ++ supp_rate_ie = brcmf_parse_tlvs((u8 *)settings->beacon.head, ++ settings->beacon.head_len, ++ WLAN_EID_SUPP_RATES); ++ ext_rate_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, ++ settings->beacon.tail_len, ++ WLAN_EID_EXT_SUPP_RATES); ++ if (ext_rate_ie) { ++ ie_len = ext_rate_ie->len; ++ for (i = 0; i < ie_len; i++) { ++ if (ext_rate_ie->data[i] == SAE_H2E_ONLY_ENABLE) { ++ must_sae_h2e = true; ++ break; ++ } ++ } ++ } ++ ++ /* if we cannot found H2E only selector in ext_supp_rate ie. ++ * traversal supp_rate ie to make sure it really doesn't exist. ++ */ ++ if (!must_sae_h2e && supp_rate_ie) { ++ ie_len = supp_rate_ie->len; ++ for (i = 0; i < ie_len; i++) { ++ if (supp_rate_ie->data[i] == SAE_H2E_ONLY_ENABLE) { ++ must_sae_h2e = true; ++ break; ++ } ++ } ++ } ++ brcmf_dbg(INFO, "must_sae_h2e:%d\n", must_sae_h2e); ++ } ++ ++ if (must_sae_h2e) /* support SAE H2E only */ ++ err = brcmf_fil_iovar_int_set(ifp, "extsae_pwe", 1); ++ else if (support_sae_h2e) /* support SAE P&H and H2E both */ ++ err = brcmf_fil_iovar_int_set(ifp, "extsae_pwe", 2); ++ else /* support SAE P&H only */ ++ err = brcmf_fil_iovar_int_set(ifp, "extsae_pwe", 0); ++ } ++ ++ return err; ++} ++ + static s32 + brcmf_parse_configure_security(struct brcmf_if *ifp, + struct cfg80211_ap_settings *settings, +@@ -5388,6 +5462,10 @@ brcmf_parse_configure_security(struct brcmf_if *ifp, + err = brcmf_configure_wpaie(ifp, tmp_ie, true); + if (err < 0) + return err; ++ ++ err = brcmf_parse_configure_sae_pwe(ifp, settings); ++ if (err < 0) ++ return err; + } + } else { + brcmf_dbg(TRACE, "No WPA(2) IEs found\n"); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0141-brcmfmac-add-sanity-check-for-potential-underflow-an.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0141-brcmfmac-add-sanity-check-for-potential-underflow-an.patch new file mode 100644 index 000000000..a2d70f6bb --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0141-brcmfmac-add-sanity-check-for-potential-underflow-an.patch @@ -0,0 +1,78 @@ +From f07f6c9c22470cc090d361c8ef7a26c23456f864 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Fri, 2 Sep 2022 02:20:39 -0500 +Subject: [PATCH 141/179] brcmfmac: add sanity check for potential underflow + and overflow + + +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 24 +++++++++++++++---- + .../broadcom/brcm80211/brcmfmac/fwsignal.c | 2 +- + 2 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 31707d9f3715..2c0211ac8f11 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2234,7 +2234,7 @@ brcmf_set_wsec_mode(struct net_device *ndev, + + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) { + brcmf_dbg(CONN, +- "set_wsdec_info algos (0x%x) mask (0x%x)\n", ++ "set_wsec_info algos (0x%x) mask (0x%x)\n", + algos, mask); + err = wl_set_wsec_info_algos(ifp, algos, mask); + if (err) { +@@ -4057,6 +4057,13 @@ static struct cfg80211_scan_request * + brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) { + struct cfg80211_scan_request *req; + size_t req_size; ++ size_t size_sanity = ~0; ++ ++ if (n_netinfo > ((size_sanity - sizeof(*req)) / ++ (sizeof(req->channels[0]) + sizeof(*req->ssids)))) { ++ brcmf_err("requesting a huge count:%d\n", n_netinfo); ++ return NULL; ++ } + + req_size = sizeof(*req) + + n_netinfo * sizeof(req->channels[0]) + +@@ -4207,9 +4214,18 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp, + } + + netinfo_start = brcmf_get_netinfo_array(pfn_result); +- datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result); +- if (datalen < result_count * sizeof(*netinfo)) { +- bphy_err(drvr, "insufficient event data\n"); ++ /* To make sure e->datalen is big enough */ ++ if (e->datalen >= ((void *)netinfo_start - (void *)pfn_result)) { ++ u32 cnt_sanity = ~0; ++ ++ datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result); ++ if (datalen < result_count * sizeof(*netinfo) || ++ (result_count > cnt_sanity / sizeof(*netinfo))) { ++ brcmf_err("insufficient event data\n"); ++ goto out_err; ++ } ++ } else { ++ brcmf_err("insufficient event data\n"); + goto out_err; + } + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +index 8d41be637760..741552568386 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -1847,7 +1847,7 @@ void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb) + u8 *signal_data; + s16 data_len; + u8 type; +- u8 len; ++ s16 len; + u8 *data; + s32 status; + s32 err; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0142-brcmfmac-Fixing-vulnerability.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0142-brcmfmac-Fixing-vulnerability.patch new file mode 100644 index 000000000..35623f097 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0142-brcmfmac-Fixing-vulnerability.patch @@ -0,0 +1,122 @@ +From 7a6422f2f958c876159681e65fef7a7c0211a5b5 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Mon, 5 Sep 2022 02:51:45 -0500 +Subject: [PATCH 142/179] brcmfmac: Fixing vulnerability + +Adding sanity check to make the driver doesn't handle an overflowed +length. + + +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/sdio.c | 56 +++++++++++-------- + 1 file changed, 34 insertions(+), 22 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index 7b80a4e54726..1b811655cacc 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -1614,13 +1614,20 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) + /* If there's a descriptor, generate the packet chain */ + if (bus->glomd) { + pfirst = pnext = NULL; +- dlen = (u16) (bus->glomd->len); +- dptr = bus->glomd->data; +- if (!dlen || (dlen & 1)) { +- brcmf_err("bad glomd len(%d), ignore descriptor\n", ++ /* it is a u32 len to u16 dlen, should have a sanity check here. */ ++ if (bus->glomd->len <= 0xFFFF) { ++ dlen = (u16)(bus->glomd->len); ++ if (!dlen || (dlen & 1)) { ++ brcmf_err("bad glomd len(%d), ignore descriptor\n", ++ dlen); ++ dlen = 0; ++ } ++ } else { ++ brcmf_err("overflowed glomd len(%d), ignore descriptor\n", + dlen); + dlen = 0; + } ++ dptr = bus->glomd->data; + + for (totlen = num = 0; dlen; num++) { + /* Get (and move past) next length */ +@@ -1686,6 +1693,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) + /* Ok -- either we just generated a packet chain, + or had one from before */ + if (!skb_queue_empty(&bus->glom)) { ++ u32 len_glom = 0; + if (BRCMF_GLOM_ON()) { + brcmf_dbg(GLOM, "try superframe read, packet chain:\n"); + skb_queue_walk(&bus->glom, pnext) { +@@ -1696,7 +1704,14 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) + } + + pfirst = skb_peek(&bus->glom); +- dlen = (u16) brcmf_sdio_glom_len(bus); ++ len_glom = brcmf_sdio_glom_len(bus); ++ if (len_glom > 0xFFFF) { ++ brcmf_err("glom_len is %d bytes, overflowed\n", ++ len_glom); ++ goto frame_error_handle; ++ } else { ++ dlen = (u16)len_glom; ++ } + + /* Do an SDIO read for the superframe. Configurable iovar to + * read directly into the chained packet, or allocate a large +@@ -1712,13 +1727,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) + if (errcode < 0) { + brcmf_err("glom read of %d bytes failed: %d\n", + dlen, errcode); +- +- sdio_claim_host(bus->sdiodev->func1); +- brcmf_sdio_rxfail(bus, true, false); +- bus->sdcnt.rxglomfail++; +- brcmf_sdio_free_glom(bus); +- sdio_release_host(bus->sdiodev->func1); +- return 0; ++ goto frame_error_handle; + } + + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), +@@ -1755,16 +1764,9 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) + num++; + } + +- if (errcode) { +- /* Terminate frame on error */ +- sdio_claim_host(bus->sdiodev->func1); +- brcmf_sdio_rxfail(bus, true, false); +- bus->sdcnt.rxglomfail++; +- brcmf_sdio_free_glom(bus); +- sdio_release_host(bus->sdiodev->func1); +- bus->cur_read.len = 0; +- return 0; +- } ++ /* Terminate frame on error */ ++ if (errcode) ++ goto frame_error_handle; + + /* Basic SD framing looks ok - process each packet (header) */ + +@@ -1805,6 +1807,16 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) + bus->sdcnt.rxglomframes++; + } + return num; ++ ++frame_error_handle: ++ sdio_claim_host(bus->sdiodev->func1); ++ brcmf_sdio_rxfail(bus, true, false); ++ bus->sdcnt.rxglomfail++; ++ brcmf_sdio_free_glom(bus); ++ sdio_release_host(bus->sdiodev->func1); ++ bus->cur_read.len = 0; ++ ++ return 0; + } + + static int brcmf_sdio_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition, +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0143-brcmfmac-Implementing-set_bitrate_mask-cfg80211-ops-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0143-brcmfmac-Implementing-set_bitrate_mask-cfg80211-ops-.patch new file mode 100644 index 000000000..0ed480382 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0143-brcmfmac-Implementing-set_bitrate_mask-cfg80211-ops-.patch @@ -0,0 +1,107 @@ +From 6ec7a6a391e51ca8ad836748b3771a575cc45388 Mon Sep 17 00:00:00 2001 +From: Ashwin Adiga +Date: Tue, 27 Sep 2022 07:50:27 -0500 +Subject: [PATCH 143/179] brcmfmac: Implementing set_bitrate_mask cfg80211 ops + for iw + +Implement .set_bitrate_mask on cfg80211 ops & function +brcmf_cfg80211_set_bitrate to parse the rate parameters coming +from the above layer. + + +Signed-off-by: Ashwin Adiga +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 50 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/cfg80211.h | 8 +++ + 2 files changed, 58 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 2c0211ac8f11..12e108d4ea72 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6493,6 +6493,55 @@ brcmf_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev, + return ret; + } + ++static int ++brcmf_cfg80211_set_bitrate(struct wiphy *wiphy, struct net_device *ndev, ++ const u8 *addr, const struct cfg80211_bitrate_mask *mask) ++{ ++ struct brcmf_if *ifp; ++ u32 he[2] = {0, 0}; ++ u32 rspec = 0; ++ uint hegi; ++ int ret = TIME_OK, i = 0; ++ ++ ifp = netdev_priv(ndev); ++ ret = brcmf_fil_iovar_data_get(ifp, "he", he, sizeof(he)); ++ if (unlikely(ret)) { ++ brcmf_dbg(INFO, "error reading he (%d)\n", ret); ++ return -EOPNOTSUPP; ++ } ++ for (i = 0; i < NUM_NL80211_BANDS; i++) { ++ if (i != NL80211_BAND_2GHZ && i != NL80211_BAND_5GHZ && ++ i != NL80211_BAND_6GHZ) { ++ continue; ++ } ++ if (he[0]) { ++ rspec = WL_RSPEC_ENCODE_HE; /* 11ax HE */ ++ rspec |= (WL_RSPEC_HE_NSS_UNSPECIFIED << WL_RSPEC_HE_NSS_SHIFT) | ++ mask->control[i].he_mcs[0]; ++ /* set the other rspec fields */ ++ hegi = mask->control[i].he_gi; ++ rspec |= ((hegi != 0xFF) ? HE_GI_TO_RSPEC(hegi) : 0); ++ ++ if (i == NL80211_BAND_2GHZ) ++ ret = brcmf_fil_iovar_data_set(ifp, "2g_rate", (char *)&rspec, 4); ++ ++ if (i == NL80211_BAND_5GHZ) ++ ret = brcmf_fil_iovar_data_set(ifp, "5g_rate", (char *)&rspec, 4); ++ ++ if (i == NL80211_BAND_6GHZ) ++ ret = brcmf_fil_iovar_data_set(ifp, "6g_rate", (char *)&rspec, 4); ++ ++ if (unlikely(ret)) ++ brcmf_dbg(INFO, "%s: set rate failed, retcode = %d\n", ++ __func__, ret); ++ } else { ++ brcmf_dbg(INFO, "Only HE supported\n"); ++ return -EOPNOTSUPP; ++ } ++ } ++ return ret; ++} ++ + static int + brcmf_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, + s32 rssi_thold, u32 rssi_hyst) +@@ -6554,6 +6603,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = { + .start_ap = brcmf_cfg80211_start_ap, + .stop_ap = brcmf_cfg80211_stop_ap, + .change_beacon = brcmf_cfg80211_change_beacon, ++ .set_bitrate_mask = brcmf_cfg80211_set_bitrate, + .del_station = brcmf_cfg80211_del_station, + .change_station = brcmf_cfg80211_change_station, + .sched_scan_start = brcmf_cfg80211_sched_scan_start, +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +index 124ae65f1bdf..e115d5d852e5 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -101,6 +101,14 @@ + #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) ++ ++#define WL_RSPEC_ENCODE_HE 0x03000000 /* HE MCS and Nss is stored in RSPEC_RATE_MASK */ ++#define WL_RSPEC_HE_NSS_UNSPECIFIED 0xF ++#define WL_RSPEC_HE_NSS_SHIFT 4 /* HE Nss value shift */ ++#define WL_RSPEC_HE_GI_MASK 0x00000C00 /* HE GI indices */ ++#define WL_RSPEC_HE_GI_SHIFT 10 ++#define HE_GI_TO_RSPEC(gi) (((gi) << WL_RSPEC_HE_GI_SHIFT) & WL_RSPEC_HE_GI_MASK) ++ + /** + * enum brcmf_scan_status - scan engine status + * +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0144-brcm80211-add-FT-PSK-roaming-offload-support.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0144-brcm80211-add-FT-PSK-roaming-offload-support.patch new file mode 100644 index 000000000..eecb32f4a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0144-brcm80211-add-FT-PSK-roaming-offload-support.patch @@ -0,0 +1,27 @@ +From 82e56951d7fba264790cea6d6cde39fc8fbbf6e1 Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Fri, 23 Sep 2022 02:51:00 -0500 +Subject: [PATCH 144/179] brcm80211: add FT-PSK roaming offload support + +Add roaming offload support for FT-PSK scenario. + +Signed-off-by: JasonHuang +--- + 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 12e108d4ea72..627304dd8f5b 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2331,6 +2331,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + case WLAN_AKM_SUITE_FT_PSK: + val = WPA2_AUTH_PSK | WPA2_AUTH_FT; + profile->is_ft = true; ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_ROAM; + break; + case WLAN_AKM_SUITE_DPP: + val = WFA_AUTH_DPP; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0145-brcmfmac-enable-6G-split-scanning-feature.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0145-brcmfmac-enable-6G-split-scanning-feature.patch new file mode 100644 index 000000000..3768a7499 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0145-brcmfmac-enable-6G-split-scanning-feature.patch @@ -0,0 +1,28 @@ +From 196fca1f3d2789968d3dd0f404c239e1e96eb270 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Wed, 5 Oct 2022 22:24:01 -0500 +Subject: [PATCH 145/179] brcmfmac: enable 6G split scanning feature + + +Signed-off-by: Carter Chen +--- + 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 627304dd8f5b..bcd3d243ab7f 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -8720,7 +8720,8 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + WIPHY_FLAG_PS_ON_BY_DEFAULT | + WIPHY_FLAG_HAVE_AP_SME | + WIPHY_FLAG_OFFCHAN_TX | +- WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; ++ WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | ++ WIPHY_FLAG_SPLIT_SCAN_6GHZ; + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) + wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; + if (!ifp->drvr->settings->roamoff) +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0146-brcmfmac-set-HE-6GHz-capabilities-for-bring-up-SAP.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0146-brcmfmac-set-HE-6GHz-capabilities-for-bring-up-SAP.patch new file mode 100644 index 000000000..243f465ac --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0146-brcmfmac-set-HE-6GHz-capabilities-for-bring-up-SAP.patch @@ -0,0 +1,56 @@ +From aa1d0b069361430440dfbe3b448abcf5921f0aef Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Wed, 5 Oct 2022 03:24:29 -0500 +Subject: [PATCH 146/179] brcmfmac: set HE 6GHz capabilities for bring-up SAP + +Need to set correct HE 6GHz capabilities to match hostapd +configuration. + +Signed-off-by: JasonHuang +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index bcd3d243ab7f..574cc3b1bfeb 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -8254,6 +8255,7 @@ static void brcmf_update_he_cap(struct ieee80211_supported_band *band, + struct ieee80211_sta_he_cap *he_cap = &data->he_cap; + struct ieee80211_he_cap_elem *he_cap_elem = &he_cap->he_cap_elem; + struct ieee80211_he_mcs_nss_supp *he_mcs = &he_cap->he_mcs_nss_supp; ++ struct ieee80211_he_6ghz_capa *he_6ghz_capa = &data->he_6ghz_capa; + + if (data == NULL) { + brcmf_dbg(INFO, "failed to allco mem\n"); +@@ -8322,7 +8324,18 @@ static void brcmf_update_he_cap(struct ieee80211_supported_band *band, + /* HE Supported MCS and NSS Set */ + he_mcs->rx_mcs_80 = cpu_to_le16(0xfffa); + he_mcs->tx_mcs_80 = cpu_to_le16(0xfffa); +- ++ /* HE 6 GHz band capabilities */ ++ if (band->band == NL80211_BAND_6GHZ) { ++ u16 capa = 0; ++ ++ capa = FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START, ++ IEEE80211_HT_MPDU_DENSITY_8) | ++ FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP, ++ IEEE80211_VHT_MAX_AMPDU_1024K) | ++ FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN, ++ IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454); ++ he_6ghz_capa->capa = cpu_to_le16(capa); ++ } + band->n_iftype_data = idx; + band->iftype_data = data; + } +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0147-brcmfmac-add-interface-to-set-bsscolor-for-bring-up-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0147-brcmfmac-add-interface-to-set-bsscolor-for-bring-up-.patch new file mode 100644 index 000000000..1ac526a61 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0147-brcmfmac-add-interface-to-set-bsscolor-for-bring-up-.patch @@ -0,0 +1,58 @@ +From 277236bf9bd8b1e3973be098870af65ed373dcf1 Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Fri, 7 Oct 2022 05:01:24 -0500 +Subject: [PATCH 147/179] brcmfmac: add interface to set bsscolor for bring-up + softAP + +FMAC need to add interface to mapping enable and set bsscolor using +he_bss_color= anycolor(1-63) in hostapd.conf while bring-up SAP. + +Signed-off-by: JasonHuang +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 574cc3b1bfeb..20554491b517 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -142,6 +142,8 @@ struct cca_msrmnt_query { + #define WL_WSEC_INFO_BSS_BASE 0x0100 + #define WL_WSEC_INFO_BSS_ALGOS (WL_WSEC_INFO_BSS_BASE + 6) + ++#define WL_HE_CMD_BSSCOLOR 5 ++ + static bool check_vif_up(struct brcmf_cfg80211_vif *vif) + { + if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) { +@@ -5514,6 +5516,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, + bool mbss; + int is_11d; + bool supports_11d; ++ struct bcm_xtlv *he_tlv; + + brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n", + settings->chandef.chan->hw_value, +@@ -5731,6 +5734,19 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, + } else { + WARN_ON(1); + } ++ /* Set he_bss_color in hostapd */ ++ if (settings->he_bss_color.enabled) { ++ u8 param[8] = {0}; ++ ++ he_tlv = (struct bcm_xtlv *)param; ++ he_tlv->id = cpu_to_le16(WL_HE_CMD_BSSCOLOR); ++ he_tlv->len = cpu_to_le16(1); ++ memcpy(he_tlv->data, &settings->he_bss_color.color, sizeof(u8)); ++ err = brcmf_fil_iovar_data_set(ifp, "he", param, sizeof(param)); ++ ++ if (err) ++ brcmf_err("set he bss_color error:%d\n", err); ++ } + + brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon); + set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0148-non-upstream-add-IFX-vendor-OUI-file.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0148-non-upstream-add-IFX-vendor-OUI-file.patch new file mode 100644 index 000000000..65f68e6f3 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0148-non-upstream-add-IFX-vendor-OUI-file.patch @@ -0,0 +1,77 @@ +From 2eda05d0e586f0e514a92fdb6643aaa4f5b226a0 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Thu, 13 Oct 2022 00:21:42 -0500 +Subject: [PATCH 148/179] non-upstream: add IFX vendor OUI file + + +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 56 +++++++++++++++++++ + 1 file changed, 56 insertions(+) + create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +new file mode 100644 +index 000000000000..39fef7f6ba49 +--- /dev/null ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -0,0 +1,56 @@ ++/* SPDX-License-Identifier: ISC ++ * ++ * Infineon Technologies OUI and vendor specific assignments ++ * ++ * $ Copyright Infineon $ ++ */ ++ ++#ifndef IFX_VENDOR_H ++#define IFX_VENDOR_H ++ ++/* This file is a registry of identifier assignments from the Infineon ++ * OUI 00:03:19 for purposes other than MAC address assignment. New identifiers ++ * can be assigned through normal review process for changes to the upstream ++ * hostap.git repository. ++ */ ++#define OUI_IFX 0x000319 ++ ++/* enum ifx_nl80211_vendor_subcmds - IFX nl80211 vendor command identifiers ++ * ++ * @IFX_VENDOR_SCMD_UNSPEC: Reserved value 0 ++ * ++ * @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list. ++ * Make sure it located at the end of the list. ++ */ ++enum ifx_nl80211_vendor_subcmds { ++ /* TODO: IFX Vendor subcmd enum IDs between 1-15 are reserved ++ * to be filled later with BRCM Vendor subcmds that are ++ * already used by IFX. ++ */ ++ IFX_VENDOR_SCMD_UNSPEC = 0, ++ /* Reserved 1-5 */ ++ IFX_VENDOR_SCMD_FRAMEBURST = 6, ++ /* Reserved 7-15 */ ++ IFX_VENDOR_SCMD_DCMD = 16, ++ IFX_VENDOR_SCMD_MAX = 17 ++}; ++ ++/* enum ifx_vendor_attr - IFX nl80211 vendor attributes ++ * ++ * @IFX_VENDOR_ATTR_UNSPEC: Reserved value 0 ++ * ++ * @IFX_VENDOR_ATTR_MAX: This acts as a the tail of attrs list. ++ * Make sure it located at the end of the list. ++ */ ++enum ifx_vendor_attr { ++ /* TODO: IFX Vendor attr enum IDs between 0-10 are reserved ++ * to be filled later with BRCM Vendor attrs that are ++ * already used by IFX. ++ */ ++ IFX_VENDOR_ATTR_UNSPEC = 0, ++ /* Reserved 1-10 */ ++ IFX_VENDOR_ATTR_MAX = 11 ++}; ++ ++#endif /* IFX_VENDOR_H */ ++ +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0149-non-upstream-adding-vendor_cmds-are-with-IFX_OUI.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0149-non-upstream-adding-vendor_cmds-are-with-IFX_OUI.patch new file mode 100644 index 000000000..74408c474 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0149-non-upstream-adding-vendor_cmds-are-with-IFX_OUI.patch @@ -0,0 +1,141 @@ +From d708a6312ad3721d2447de38cf1de05d39e279b5 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Thu, 13 Oct 2022 06:23:22 -0500 +Subject: [PATCH 149/179] non-upstream: adding vendor_cmds are with IFX_OUI + +Fixes: SWLINUX-2939 + +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- + .../broadcom/brcm80211/brcmfmac/vendor.c | 22 ++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor.h | 1 + + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 40 +++++++++++++++---- + 4 files changed, 57 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 20554491b517..d99fd7f0ab03 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -8790,7 +8790,7 @@ 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->n_vendor_commands = get_brcmf_num_vndr_cmds(); + wiphy->vendor_events = brcmf_vendor_events; + wiphy->n_vendor_events = BRCMF_VNDR_EVTS_LAST; + brcmf_fweh_register(cfg->pub, BRCMF_E_PHY_TEMP, +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index dec1307a0e00..fe181a5b8c3c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -15,6 +15,7 @@ + #include "cfg80211.h" + #include "vendor.h" + #include "fwil.h" ++#include "vendor_ifx.h" + + static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy, + struct wireless_dev *wdev, +@@ -239,6 +240,20 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + .policy = VENDOR_CMD_RAW_DATA, + .doit = brcmf_cfg80211_vndr_cmds_frameburst + }, ++ { ++ IFX_SUBCMD(DCMD, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ brcmf_cfg80211_vndr_cmds_dcmd_handler) ++ }, ++ { ++ IFX_SUBCMD(FRAMEBURST, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ brcmf_cfg80211_vndr_cmds_frameburst) ++ }, + }; + + const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = { +@@ -247,3 +262,10 @@ const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = { + .subcmd = BRCMF_VNDR_EVTS_PHY_TEMP, + }, + }; ++ ++int get_brcmf_num_vndr_cmds(void) ++{ ++ int num = ARRAY_SIZE(brcmf_vendor_cmds); ++ ++ return num; ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h +index 3c691bbe0bae..adc559e12dae 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.h +@@ -69,5 +69,6 @@ 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); ++int get_brcmf_num_vndr_cmds(void); + + #endif /* _vendor_h_ */ +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index 39fef7f6ba49..522e617885e3 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -22,17 +22,43 @@ + * @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list. + * Make sure it located at the end of the list. + */ ++#define SCMD(_CMD) IFX_VENDOR_SCMD_##_CMD ++#define IFX_SUBCMD(_CMD, _FLAGS, _POLICY, _FN) \ ++ { \ ++ .vendor_id = OUI_IFX, \ ++ .subcmd = SCMD(_CMD) \ ++ }, \ ++ .flags = (_FLAGS), \ ++ .policy = (_POLICY), \ ++ .doit = (_FN) ++ + enum ifx_nl80211_vendor_subcmds { +- /* TODO: IFX Vendor subcmd enum IDs between 1-15 are reserved ++ /* TODO: IFX Vendor subcmd enum IDs between 2-15 are reserved + * to be filled later with BRCM Vendor subcmds that are + * already used by IFX. ++ * ++ * @IFX_VENDOR_SCMD_DCMD: equivilent to SCMD_PRIV_STR in DHD. ++ * ++ * @IFX_VENDOR_SCMD_FRAMEBURST: align ID to DHD. + */ +- IFX_VENDOR_SCMD_UNSPEC = 0, +- /* Reserved 1-5 */ +- IFX_VENDOR_SCMD_FRAMEBURST = 6, +- /* Reserved 7-15 */ +- IFX_VENDOR_SCMD_DCMD = 16, +- IFX_VENDOR_SCMD_MAX = 17 ++ /* Reserved 2-5 */ ++ SCMD(UNSPEC) = 0, ++ SCMD(DCMD) = 1, ++ SCMD(RSV2) = 2, ++ SCMD(RSV3) = 3, ++ SCMD(RSV4) = 4, ++ SCMD(RSV5) = 5, ++ SCMD(FRAMEBURST) = 6, ++ SCMD(RSV7) = 7, ++ SCMD(RSV8) = 8, ++ SCMD(RSV9) = 9, ++ SCMD(RSV10) = 10, ++ SCMD(RSV11) = 11, ++ SCMD(RSV12) = 12, ++ SCMD(RSV13) = 13, ++ SCMD(RSV14) = 14, ++ SCMD(RSV15) = 15, ++ SCMD(MAX) = 16 + }; + + /* enum ifx_vendor_attr - IFX nl80211 vendor attributes +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0150-brcmfmac-introduce-a-module-parameter-to-disable-the.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0150-brcmfmac-introduce-a-module-parameter-to-disable-the.patch new file mode 100644 index 000000000..9922265c8 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0150-brcmfmac-introduce-a-module-parameter-to-disable-the.patch @@ -0,0 +1,96 @@ +From 7c4418cb5f0a1764b942c5fdd38b6ec48b03fa13 Mon Sep 17 00:00:00 2001 +From: Gokul Sivakumar +Date: Thu, 13 Oct 2022 04:41:42 -0500 +Subject: [PATCH 150/179] brcmfmac: introduce a module parameter to disable the + 6GHz Operation + +Add a kernel module parameter "disable_6ghz" to disable the operation of +the STA and SoftAP in the 6GHz band. By default, this module parameter will +be set to zero, so 6GHz operation will be disabled during kernel module +load only when explicity setting "disable_6ghz=1". + +Signed-off-by: Gokul Sivakumar +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/common.c | 5 +++++ + .../net/wireless/broadcom/brcm80211/brcmfmac/common.h | 2 ++ + .../net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 5 +++++ + .../net/wireless/broadcom/brcm80211/brcmfmac/feature.h | 9 +++++++++ + 4 files changed, 21 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +index 5b132e90d9af..98865efd05c2 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -92,6 +92,10 @@ static int brcmf_fw_ap_select; + module_param_named(fw_ap_select, brcmf_fw_ap_select, int, 0400); + MODULE_PARM_DESC(fw_ap_select, "Allow FW for AP selection"); + ++static int brcmf_disable_6ghz; ++module_param_named(disable_6ghz, brcmf_disable_6ghz, int, 0400); ++MODULE_PARM_DESC(disable_6ghz, "Disable 6GHz Operation"); ++ + static struct brcmfmac_platform_data *brcmfmac_pdata; + struct brcmf_mp_global_t brcmf_mp_global; + +@@ -501,6 +505,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, + settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; + #endif + settings->fw_ap_select = !!brcmf_fw_ap_select; ++ settings->disable_6ghz = !!brcmf_disable_6ghz; + + if (bus_type == BRCMF_BUSTYPE_SDIO) + settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +index d9f740a3e4e7..81fed6b54655 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -41,6 +41,7 @@ extern struct brcmf_mp_global_t brcmf_mp_global; + * @default_pm: default power management (PM) mode. + * @ignore_probe_fail: Ignore probe failure. + * @fw_ap_select: Allow FW to select AP. ++ * @disable_6ghz: Disable 6GHz operation + * @country_codes: If available, pointer to struct for translating country codes + * @bus: Bus specific platform data. Only SDIO at the mmoment. + */ +@@ -54,6 +55,7 @@ struct brcmf_mp_device { + int default_pm; + bool ignore_probe_fail; + bool fw_ap_select; ++ bool disable_6ghz; + struct brcmfmac_pd_cc *country_codes; + const char *board_type; + union { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +index 08535a5e61fe..f653f2cc2ae3 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -332,3 +332,8 @@ bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp, + { + return (ifp->drvr->chip_quirks & BIT(quirk)); + } ++ ++bool brcmf_feat_is_6ghz_enabled(struct brcmf_if *ifp) ++{ ++ return (!ifp->drvr->settings->disable_6ghz); ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +index a81cabd975ce..c054946e4187 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +@@ -128,4 +128,13 @@ bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id); + bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp, + enum brcmf_feat_quirk quirk); + ++/** ++ * brcmf_feat_is_6ghz_enabled() - Find if 6GHZ Operation is allowed ++ * ++ * @ifp: interface instance. ++ * ++ * Return: true if 6GHz operation is allowed; otherwise false. ++ */ ++bool brcmf_feat_is_6ghz_enabled(struct brcmf_if *ifp); ++ + #endif /* _BRCMF_FEATURE_H */ +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0151-brcmfmac-skip-6GHz-capab-registration-with-cfg80211-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0151-brcmfmac-skip-6GHz-capab-registration-with-cfg80211-.patch new file mode 100644 index 000000000..7f42d8dd2 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0151-brcmfmac-skip-6GHz-capab-registration-with-cfg80211-.patch @@ -0,0 +1,109 @@ +From 448f489f602e491115f664530db4a0b58d74a26f Mon Sep 17 00:00:00 2001 +From: Gokul Sivakumar +Date: Thu, 13 Oct 2022 05:23:54 -0500 +Subject: [PATCH 151/179] brcmfmac: skip 6GHz capab registration with cfg80211 + based on module param + +When the kernel module param "disable_6ghz" is enabled, avoid handling the +6GHz channel capab advertised by FW during module load and skip registering +them with cfg80211. This helps with restricting the device from initiating +a scan as a STA and beacon as an AP on a 6GHz channel whenever it needs to +be avoided. + + +Signed-off-by: Gokul Sivakumar +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 34 +++++++++++++------ + 1 file changed, 24 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index d99fd7f0ab03..617467881892 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -7927,8 +7927,14 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + band = wiphy->bands[NL80211_BAND_2GHZ]; + } else if (ch.band == BRCMU_CHAN_BAND_5G) { + band = wiphy->bands[NL80211_BAND_5GHZ]; +- } else if (ch.band == BRCMU_CHAN_BAND_6G) { +- band = wiphy->bands[NL80211_BAND_6GHZ]; ++ } else if ((ch.band == BRCMU_CHAN_BAND_6G)) { ++ if (brcmf_feat_is_6ghz_enabled(ifp)) { ++ band = wiphy->bands[NL80211_BAND_6GHZ]; ++ } else { ++ brcmf_dbg(INFO, "Disabled channel Spec. 0x%x.\n", ++ ch.chspec); ++ continue; ++ } + } else { + bphy_err(drvr, "Invalid channel Spec. 0x%x.\n", + ch.chspec); +@@ -8157,6 +8163,10 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) + err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); + if (!err) { + bw_cap[NL80211_BAND_5GHZ] = band; ++ ++ if (!brcmf_feat_is_6ghz_enabled(ifp)) ++ return; ++ + band = WLC_BAND_6G; + err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); + if (!err) { +@@ -8364,9 +8374,9 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + u32 nmode = 0; + u32 vhtmode = 0; + u32 bw_cap[4] = { WLC_BW_20MHZ_BIT, /* 2GHz */ +- WLC_BW_20MHZ_BIT, /* 5GHz */ +- 0, /* 60GHz */ +- WLC_BW_20MHZ_BIT };/* 6GHz */ ++ WLC_BW_20MHZ_BIT, /* 5GHz */ ++ 0, /* 60GHz */ ++ 0 }; /* 6GHz */ + u32 rxchain; + u32 nchain; + int err; +@@ -8386,9 +8396,9 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + } + (void)brcmf_fil_iovar_data_get(ifp, "he", he, sizeof(he)); + +- brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, he=%d, bw_cap=(%d, %d)\n", ++ brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, he=%d, bw_cap=(%d, %d, %d)\n", + nmode, vhtmode, he[0], bw_cap[NL80211_BAND_2GHZ], +- bw_cap[NL80211_BAND_5GHZ]); ++ bw_cap[NL80211_BAND_5GHZ], bw_cap[NL80211_BAND_6GHZ]); + + err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain); + if (err) { +@@ -8424,6 +8434,10 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + if (band == NULL) + continue; + ++ if ((band->band == NL80211_BAND_6GHZ) && ++ !brcmf_feat_is_6ghz_enabled(ifp)) ++ continue; ++ + if (nmode) + brcmf_update_ht_cap(band, bw_cap, nchain); + if (vhtmode) +@@ -8749,8 +8763,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + WIPHY_FLAG_PS_ON_BY_DEFAULT | + WIPHY_FLAG_HAVE_AP_SME | + WIPHY_FLAG_OFFCHAN_TX | +- WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | +- WIPHY_FLAG_SPLIT_SCAN_6GHZ; ++ WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) + wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; + if (!ifp->drvr->settings->roamoff) +@@ -8840,7 +8853,8 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + band->n_channels = ARRAY_SIZE(__wl_5ghz_channels); + wiphy->bands[NL80211_BAND_5GHZ] = band; + } +- if (bandlist[i] == cpu_to_le32(WLC_BAND_6G)) { ++ if (bandlist[i] == cpu_to_le32(WLC_BAND_6G) && ++ brcmf_feat_is_6ghz_enabled(ifp)) { + band = kmemdup(&__wl_band_6ghz, sizeof(__wl_band_6ghz), + GFP_KERNEL); + if (!band) +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0152-brcmfmac-set-HE-rate-only-if-HE-MCS-set-and-valid.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0152-brcmfmac-set-HE-rate-only-if-HE-MCS-set-and-valid.patch new file mode 100644 index 000000000..b90d1eb59 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0152-brcmfmac-set-HE-rate-only-if-HE-MCS-set-and-valid.patch @@ -0,0 +1,106 @@ +From 438a28914bec48b492c10cad66578e3219eac6e2 Mon Sep 17 00:00:00 2001 +From: "Sanaboina Suresh (IFINS CSS ICW ENG SW WFSW 1)" + +Date: Thu, 20 Oct 2022 09:25:27 +0000 +Subject: [PATCH 152/179] brcmfmac: set HE rate only if HE MCS set and valid + +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 68 ++++++++++++------- + 1 file changed, 45 insertions(+), 23 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 617467881892..4685fdfa85cc 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6518,8 +6518,10 @@ brcmf_cfg80211_set_bitrate(struct wiphy *wiphy, struct net_device *ndev, + struct brcmf_if *ifp; + u32 he[2] = {0, 0}; + u32 rspec = 0; ++ s32 ret = TIME_OK; + uint hegi; +- int ret = TIME_OK, i = 0; ++ u16 mcs_mask; ++ u8 band, mcs; + + ifp = netdev_priv(ndev); + ret = brcmf_fil_iovar_data_get(ifp, "he", he, sizeof(he)); +@@ -6527,34 +6529,54 @@ brcmf_cfg80211_set_bitrate(struct wiphy *wiphy, struct net_device *ndev, + brcmf_dbg(INFO, "error reading he (%d)\n", ret); + return -EOPNOTSUPP; + } +- for (i = 0; i < NUM_NL80211_BANDS; i++) { +- if (i != NL80211_BAND_2GHZ && i != NL80211_BAND_5GHZ && +- i != NL80211_BAND_6GHZ) { ++ ++ if (!he[0]) { ++ brcmf_dbg(INFO, "Only HE supported\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ for (band = 0; band < NUM_NL80211_BANDS; band++) { ++ if (band != NL80211_BAND_2GHZ && band != NL80211_BAND_5GHZ && ++ band != NL80211_BAND_6GHZ) { ++ continue; ++ } ++ ++ /* Skip setting HE rates if legacy rate set is called from userspace. ++ * Also if any one of 2.4, 5 or 6GHz is being called then other two will have ++ * an invalid he mask of 0xFFF so skip setting he rates for other two bands. ++ */ ++ if (!mask->control[band].he_mcs[0] || mask->control[band].he_mcs[0] == 0xFFF) ++ continue; ++ ++ mcs_mask = mask->control[band].he_mcs[0]; ++ mcs_mask = (mcs_mask ^ ((mcs_mask - 1) & mcs_mask)); ++ if (mcs_mask != mask->control[band].he_mcs[0]) + continue; ++ ++ while (mcs_mask) { ++ mcs++; ++ mcs_mask >>= 1; + } +- if (he[0]) { +- rspec = WL_RSPEC_ENCODE_HE; /* 11ax HE */ +- rspec |= (WL_RSPEC_HE_NSS_UNSPECIFIED << WL_RSPEC_HE_NSS_SHIFT) | +- mask->control[i].he_mcs[0]; +- /* set the other rspec fields */ +- hegi = mask->control[i].he_gi; +- rspec |= ((hegi != 0xFF) ? HE_GI_TO_RSPEC(hegi) : 0); + +- if (i == NL80211_BAND_2GHZ) +- ret = brcmf_fil_iovar_data_set(ifp, "2g_rate", (char *)&rspec, 4); ++ rspec = WL_RSPEC_ENCODE_HE; /* 11ax HE */ ++ rspec |= (WL_RSPEC_HE_NSS_UNSPECIFIED << WL_RSPEC_HE_NSS_SHIFT) | (mcs - 1); ++ /* set the other rspec fields */ ++ hegi = mask->control[band].he_gi; ++ rspec |= ((hegi != 0xFF) ? HE_GI_TO_RSPEC(hegi) : 0); + +- if (i == NL80211_BAND_5GHZ) +- ret = brcmf_fil_iovar_data_set(ifp, "5g_rate", (char *)&rspec, 4); ++ if (band == NL80211_BAND_2GHZ) ++ ret = brcmf_fil_iovar_data_set(ifp, "2g_rate", (char *)&rspec, 4); + +- if (i == NL80211_BAND_6GHZ) +- ret = brcmf_fil_iovar_data_set(ifp, "6g_rate", (char *)&rspec, 4); ++ if (band == NL80211_BAND_5GHZ) ++ ret = brcmf_fil_iovar_data_set(ifp, "5g_rate", (char *)&rspec, 4); + +- if (unlikely(ret)) +- brcmf_dbg(INFO, "%s: set rate failed, retcode = %d\n", +- __func__, ret); +- } else { +- brcmf_dbg(INFO, "Only HE supported\n"); +- return -EOPNOTSUPP; ++ if (band == NL80211_BAND_6GHZ) ++ ret = brcmf_fil_iovar_data_set(ifp, "6g_rate", (char *)&rspec, 4); ++ ++ if (unlikely(ret)) { ++ brcmf_dbg(INFO, "%s: set rate failed, retcode = %d\n", ++ __func__, ret); ++ return ret; + } + } + return ret; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0153-brcmfmac-remove-workaround-cause-the-FW-can-support-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0153-brcmfmac-remove-workaround-cause-the-FW-can-support-.patch new file mode 100644 index 000000000..9095f4cf0 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0153-brcmfmac-remove-workaround-cause-the-FW-can-support-.patch @@ -0,0 +1,32 @@ +From 9ac10f0dc60c63dbd21b7ae48cdeb53b41900acd Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Tue, 18 Oct 2022 01:06:04 -0500 +Subject: [PATCH 153/179] brcmfmac: remove workaround cause the FW can support + 6G channels + +Earlier firmware not ready support 6G channels. We add this workaround +to avoid FW crash, when driver want to remove disabled 6G channels. Now, +remove this workaround cause firmware is ready for the 6G channels. + +Signed-off-by: JasonHuang +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 4685fdfa85cc..a9c9639d86dd 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -8078,9 +8078,6 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + next = &band->channels[j + 1]; + memcpy(cur, next, sizeof(*cur)); + } +- /* To avoid fw crash while delete all channels */ +- if (n_6g == 1) +- break; + n_6g--; + } else + i++; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0154-brcmfmac-ext_owe-supporting.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0154-brcmfmac-ext_owe-supporting.patch new file mode 100644 index 000000000..96358cd96 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0154-brcmfmac-ext_owe-supporting.patch @@ -0,0 +1,272 @@ +From c91d313c24f9139fe29190bc8bdfe5800327bc69 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Wed, 12 Oct 2022 21:19:47 -0500 +Subject: [PATCH 154/179] brcmfmac: ext_owe supporting + +parsing the AKM setting of OWE. +parsing the ie in the cfg80211_connect_params, to find the owe extension +ie we need to set to firmware. + +Fixes: SWLINUX-2956 + +Signed-off-by: Carter Chen +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 151 +++++++++++++++++- + .../broadcom/brcm80211/include/brcmu_wifi.h | 2 +- + 2 files changed, 150 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index a9c9639d86dd..76dc9de86f64 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -141,7 +141,6 @@ struct cca_msrmnt_query { + /* start enum value for BSS properties */ + #define WL_WSEC_INFO_BSS_BASE 0x0100 + #define WL_WSEC_INFO_BSS_ALGOS (WL_WSEC_INFO_BSS_BASE + 6) +- + #define WL_HE_CMD_BSSCOLOR 5 + + static bool check_vif_up(struct brcmf_cfg80211_vif *vif) +@@ -327,6 +326,29 @@ struct parsed_vndr_ies { + struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT]; + }; + ++struct brcmf_ext_tlv { ++ u8 id; ++ u8 len; ++ u8 ext_id; ++}; ++ ++struct parsed_ext_ie_info { ++ u8 *ie_ptr; ++ u32 ie_len; /* total length including id & length field */ ++ struct brcmf_ext_tlv ie_data; ++}; ++ ++struct parsed_extension_ies { ++ u32 count; ++ struct parsed_ext_ie_info ie_info[VNDR_IE_PARSE_LIMIT]; ++}; ++ ++struct dot11_assoc_resp { ++ u16 capability; /* capability information */ ++ u16 status; /* status code */ ++ u16 aid; /* association ID */ ++}; ++ + #define WLC_E_IF_ROLE_STA 0 /* Infra STA */ + #define WLC_E_IF_ROLE_AP 1 /* Access Point */ + +@@ -2087,6 +2109,8 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev, + } 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 if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_OWE) ++ val = WPA3_AUTH_OWE; + else + val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; + } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3) { +@@ -2340,6 +2364,10 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + val = WFA_AUTH_DPP; + profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE; + break; ++ case WLAN_AKM_SUITE_OWE: ++ val = WPA3_AUTH_OWE; ++ profile->use_fwsup = BRCMF_PROFILE_FWSUP_ROAM; ++ break; + case WLAN_AKM_SUITE_8021X_SUITE_B_192: + val = WPA3_AUTH_1X_SUITE_B_SHA384; + if (sme->want_1x) +@@ -5162,6 +5190,58 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) + return ie_len + VNDR_IE_HDR_SIZE; + } + ++static s32 ++brcmf_parse_extension_ies(const u8 *extension_ie_buf, u32 extension_ie_len, ++ struct parsed_extension_ies *extension_ies) ++{ ++ struct brcmf_ext_tlv *ext_ie; ++ struct brcmf_tlv *ie; ++ struct parsed_ext_ie_info *parsed_info; ++ s32 remaining_len; ++ ++ remaining_len = (s32)extension_ie_len; ++ memset(extension_ies, 0, sizeof(*extension_ies)); ++ ++ ie = (struct brcmf_tlv *)extension_ie_buf; ++ while (ie) { ++ if (ie->id != WLAN_EID_EXTENSION) ++ goto next; ++ ext_ie = (struct brcmf_ext_tlv *)ie; ++ ++ /* len should be bigger than ext_id + one data */ ++ if (ext_ie->len < 2) { ++ brcmf_err("invalid ext_ie ie. length is too small %d\n", ++ ext_ie->len); ++ goto next; ++ } ++ ++ parsed_info = &extension_ies->ie_info[extension_ies->count]; ++ ++ parsed_info->ie_ptr = (char *)ext_ie; ++ parsed_info->ie_len = ext_ie->len + TLV_HDR_LEN; ++ memcpy(&parsed_info->ie_data, ext_ie, sizeof(*ext_ie)); ++ ++ extension_ies->count++; ++ ++ brcmf_dbg(TRACE, "** EXT_IE %d, len 0x%02x EXT_ID: %d\n", ++ parsed_info->ie_data.id, ++ parsed_info->ie_data.len, ++ parsed_info->ie_data.ext_id); ++ ++ /* temperory parsing at most 5 EXT_ID, will review it.*/ ++ if (extension_ies->count >= VNDR_IE_PARSE_LIMIT) ++ break; ++next: ++ remaining_len -= (ie->len + TLV_HDR_LEN); ++ if (remaining_len <= TLV_HDR_LEN) ++ ie = NULL; ++ else ++ ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len + ++ TLV_HDR_LEN); ++ } ++ return 0; ++} ++ + s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, + const u8 *vndr_ie_buf, u32 vndr_ie_len) + { +@@ -5183,6 +5263,9 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, + s32 i; + u8 *ptr; + int remained_buf_len; ++ struct parsed_extension_ies new_ext_ies; ++ struct parsed_extension_ies old_ext_ies; ++ struct parsed_ext_ie_info *extie_info; + + if (!vif) + return -ENODEV; +@@ -5244,6 +5327,13 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, + vndrie_info->ie_len); + parsed_ie_buf_len += vndrie_info->ie_len; + } ++ brcmf_parse_extension_ies(vndr_ie_buf, vndr_ie_len, &new_ext_ies); ++ for (i = 0; i < new_ext_ies.count; i++) { ++ extie_info = &new_ext_ies.ie_info[i]; ++ memcpy(ptr + parsed_ie_buf_len, extie_info->ie_ptr, ++ extie_info->ie_len); ++ parsed_ie_buf_len += extie_info->ie_len; ++ } + } + + if (mgmt_ie_buf && *mgmt_ie_len) { +@@ -5256,6 +5346,8 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, + + /* parse old vndr_ie */ + brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies); ++ /* parse old ext_ie */ ++ brcmf_parse_extension_ies(mgmt_ie_buf, *mgmt_ie_len, &old_ext_ies); + + /* make a command to delete old ie */ + for (i = 0; i < old_vndr_ies.count; i++) { +@@ -5273,6 +5365,23 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, + curr_ie_buf += del_add_ie_buf_len; + total_ie_buf_len += del_add_ie_buf_len; + } ++ /* make a command to delete old extension ie */ ++ for (i = 0; i < old_ext_ies.count; i++) { ++ extie_info = &old_ext_ies.ie_info[i]; ++ ++ brcmf_dbg(TRACE, "DEL EXT_IE : %d, Len: %d , ext_id:%d\n", ++ extie_info->ie_data.id, ++ extie_info->ie_data.len, ++ extie_info->ie_data.ext_id); ++ ++ del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, ++ pktflag | BRCMF_VNDR_IE_CUSTOM_FLAG, ++ extie_info->ie_ptr, ++ extie_info->ie_len, ++ "del"); ++ curr_ie_buf += del_add_ie_buf_len; ++ total_ie_buf_len += del_add_ie_buf_len; ++ } + } + + *mgmt_ie_len = 0; +@@ -5311,6 +5420,39 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, + vndrie_info->ie_len); + *mgmt_ie_len += vndrie_info->ie_len; + ++ curr_ie_buf += del_add_ie_buf_len; ++ total_ie_buf_len += del_add_ie_buf_len; ++ } ++ /* make a command to add new EXT ie */ ++ for (i = 0; i < new_ext_ies.count; i++) { ++ extie_info = &new_ext_ies.ie_info[i]; ++ ++ /* verify remained buf size before copy data */ ++ if (remained_buf_len < (extie_info->ie_data.len + ++ VNDR_IE_VSIE_OFFSET)) { ++ bphy_err(drvr, "no space in mgmt_ie_buf: len left %d", ++ remained_buf_len); ++ break; ++ } ++ remained_buf_len -= (extie_info->ie_len + ++ VNDR_IE_VSIE_OFFSET); ++ ++ brcmf_dbg(TRACE, "ADDED EXT ID : %d, Len: %d, OUI:%d\n", ++ extie_info->ie_data.id, ++ extie_info->ie_data.len, ++ extie_info->ie_data.ext_id); ++ ++ del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, ++ pktflag | BRCMF_VNDR_IE_CUSTOM_FLAG, ++ extie_info->ie_ptr, ++ extie_info->ie_len, ++ "add"); ++ ++ /* save the parsed IE in wl struct */ ++ memcpy(ptr + (*mgmt_ie_len), extie_info->ie_ptr, ++ extie_info->ie_len); ++ *mgmt_ie_len += extie_info->ie_len; ++ + curr_ie_buf += del_add_ie_buf_len; + total_ie_buf_len += del_add_ie_buf_len; + } +@@ -7002,6 +7144,11 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg, + conn_info->req_ie_len = 0; + conn_info->req_ie = NULL; + } ++ ++ /* resp_len is the total length of assoc resp ++ * which includes 6 bytes of aid/status code/capabilities. ++ * the assoc_resp_ie length should minus the 6 bytes which starts from rate_ie. ++ */ + if (resp_len) { + err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies", + cfg->extra_buf, +@@ -7010,7 +7157,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg, + bphy_err(drvr, "could not get assoc resp (%d)\n", err); + return err; + } +- conn_info->resp_ie_len = resp_len; ++ conn_info->resp_ie_len = resp_len - sizeof(struct dot11_assoc_resp); + conn_info->resp_ie = + kmemdup(cfg->extra_buf, conn_info->resp_ie_len, + GFP_KERNEL); +diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +index 04bf1c0b3b06..de5b585b91a8 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +@@ -240,7 +240,7 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec) + #define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */ + + #define WPA3_AUTH_SAE_PSK 0x40000 /* SAE with 4-way handshake */ +- ++#define WPA3_AUTH_OWE 0x100000 /* OWE */ + #define WFA_AUTH_DPP 0x200000 /* WFA DPP AUTH */ + #define WPA3_AUTH_1X_SUITE_B_SHA384 0x400000 /* Suite B-192 SHA384 */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0155-brcmfmac-Avoid-adding-two-sets-of-HE-Capab-and-Oper-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0155-brcmfmac-Avoid-adding-two-sets-of-HE-Capab-and-Oper-.patch new file mode 100644 index 000000000..92646fdb0 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0155-brcmfmac-Avoid-adding-two-sets-of-HE-Capab-and-Oper-.patch @@ -0,0 +1,35 @@ +From 4bc730179a645079ab8726b8d7c635df507b48aa Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Fri, 21 Oct 2022 00:28:37 -0500 +Subject: [PATCH 155/179] brcmfmac: Avoid adding two sets of HE Capab and Oper + IE to the outgoing mgmt frames + +Fixes: SWWLAN-143520 +Signed-off-by: Carter Chen +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 76dc9de86f64..a082b994ce81 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5215,6 +5215,15 @@ brcmf_parse_extension_ies(const u8 *extension_ie_buf, u32 extension_ie_len, + goto next; + } + ++ /* skip parsing the HE capab & oper IE from upper layer ++ * to avoid sending it to the FW, as these IEs will be ++ * added by the FW based on the MAC & PHY capab if HE ++ * is enabled. ++ */ ++ if (ext_ie->id == WLAN_EID_EXT_HE_CAPABILITY || ++ ext_ie->id == WLAN_EID_EXT_HE_OPERATION) ++ goto next; ++ + parsed_info = &extension_ies->ie_info[extension_ies->count]; + + parsed_info->ie_ptr = (char *)ext_ie; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0156-non-upstream-Add-IFX-TWT-Offload-support.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0156-non-upstream-Add-IFX-TWT-Offload-support.patch new file mode 100644 index 000000000..ea511daf6 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0156-non-upstream-Add-IFX-TWT-Offload-support.patch @@ -0,0 +1,880 @@ +From 2122a270e1e50878a0b3f0e6c8c583db8ec593cf Mon Sep 17 00:00:00 2001 +From: Ian Lin +Date: Thu, 20 Oct 2022 21:02:43 -0500 +Subject: [PATCH 156/179] non-upstream: Add IFX TWT Offload support + +Define the NL80211 Vendor attributes and subcmd for IFX +TWT Setup/Teardown process, and add the corresponding subcmd handler. +The handler convert the TWT params from userspace into FW format, +then pass it to FW through iovar "twt" + + +Signed-off-by: Ian Lin +--- + .../broadcom/brcm80211/brcmfmac/Makefile | 3 +- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 10 + + .../broadcom/brcm80211/brcmfmac/fweh.h | 1 + + .../broadcom/brcm80211/brcmfmac/vendor.c | 9 + + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 373 +++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 375 +++++++++++++++++- + 6 files changed, 765 insertions(+), 6 deletions(-) + create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile +index baf713279532..96e4b7a402c5 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile +@@ -24,7 +24,8 @@ brcmfmac-objs += \ + btcoex.o \ + vendor.o \ + pno.o \ +- xtlv.o ++ xtlv.o \ ++ vendor_ifx.o + brcmfmac-$(CONFIG_BRCMFMAC_PROTO_BCDC) += \ + bcdc.o \ + fwsignal.o +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index a082b994ce81..62674335bb7e 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -7817,6 +7817,14 @@ brcmf_notify_beacon_loss(struct brcmf_if *ifp, + return 0; + } + ++int brcmf_notify_twt(struct brcmf_if *ifp, ++ const struct brcmf_event_msg *e, ++ void *data) ++{ ++ brcmf_dbg(TRACE, "Enter\n"); ++ return 0; ++} ++ + static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) + { + conf->frag_threshold = (u32)-1; +@@ -7875,6 +7883,8 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) + brcmf_notify_rssi_change_ind); + brcmf_fweh_register(cfg->pub, BRCMF_E_BCNLOST_MSG, + brcmf_notify_beacon_loss); ++ brcmf_fweh_register(cfg->pub, BRCMF_E_TWT_SETUP, ++ brcmf_notify_twt); + } + + static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +index f92700237d0c..0950131e6ed6 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +@@ -93,6 +93,7 @@ struct brcmf_cfg80211_info; + BRCMF_ENUM_DEF(PHY_TEMP, 111) \ + BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \ + BRCMF_ENUM_DEF(ULP, 146) \ ++ BRCMF_ENUM_DEF(TWT_SETUP, 157) \ + BRCMF_ENUM_DEF(EXT_AUTH_REQ, 187) \ + BRCMF_ENUM_DEF(EXT_AUTH_FRAME_RX, 188) \ + BRCMF_ENUM_DEF(MGMT_FRAME_TXSTATUS, 189) \ +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index fe181a5b8c3c..e85a99280604 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -254,6 +254,15 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + VENDOR_CMD_RAW_DATA, + brcmf_cfg80211_vndr_cmds_frameburst) + }, ++ { ++ IFX_SUBCMD(TWT, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ ifx_vendor_attr_twt_policy, ++ ifx_cfg80211_vndr_cmds_twt), ++ .maxattr = IFX_VENDOR_ATTR_TWT_MAX ++ }, ++ + }; + + const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +new file mode 100644 +index 000000000000..3e04a7dfe7cd +--- /dev/null ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -0,0 +1,373 @@ ++/* ++ * Infineon WLAN driver: vendor specific implement ++ * ++ * ©2022 Cypress Semiconductor Corporation (an Infineon company) ++ * or an affiliate 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 ++ * affiliates ("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, non-exclusive, ++ * 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 expresswritten 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 ++#include "core.h" ++#include "cfg80211.h" ++#include "debug.h" ++#include "fwil.h" ++#include "vendor_ifx.h" ++ ++/* ++ * Wake Duration derivation from Nominal Minimum Wake Duration ++ */ ++static inline u32 ++ifx_twt_min_twt_to_wake_dur(u8 min_twt, u8 min_twt_unit) ++{ ++ u32 wake_dur; ++ ++ if (min_twt_unit == 1) { ++ /* ++ * If min_twt_unit is 1, then min_twt is ++ * in units of TUs (i.e) 102400 usecs. ++ */ ++ wake_dur = (u32)min_twt * 102400; ++ } else if (min_twt_unit == 0) { ++ /* ++ * If min_twt_unit is 0, then min_twt is ++ * in units of 256 usecs. ++ */ ++ wake_dur = (u32)min_twt * 256; ++ } else { ++ /* Invalid min_twt */ ++ wake_dur = 0; ++ } ++ ++ return wake_dur; ++} ++ ++/* ++ * Wake Interval derivation from Wake Interval Mantissa & Exponent ++ */ ++static inline u32 ++ifx_twt_float_to_uint32(u8 exponent, u16 mantissa) ++{ ++ return (u32)mantissa << exponent; ++} ++ ++int ifx_twt_setup(struct wireless_dev *wdev, struct ifx_twt twt) ++{ ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ ifx_twt_setup_t val; ++ s32 err; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ ++ memset(&val, 0, sizeof(val)); ++ val.version = IFX_TWT_SETUP_VER; ++ val.length = sizeof(val.version) + sizeof(val.length); ++ ++ /* Default values, Override Below */ ++ val.desc.flow_flags = 0x0; ++ val.desc.wake_dur = 0xFFFFFFFF; ++ val.desc.wake_int = 0xFFFFFFFF; ++ val.desc.wake_int_max = 0xFFFFFFFF; ++ ++ /* Setup command */ ++ val.desc.setup_cmd = twt.setup_cmd; ++ ++ /* Flow flags */ ++ val.desc.flow_flags |= ((twt.negotiation_type & 0x02) >> 1 ? ++ IFX_TWT_FLOW_FLAG_BROADCAST : 0); ++ val.desc.flow_flags |= (twt.implicit ? IFX_TWT_FLOW_FLAG_IMPLICIT : 0); ++ val.desc.flow_flags |= (twt.flow_type ? IFX_TWT_FLOW_FLAG_UNANNOUNCED : 0); ++ val.desc.flow_flags |= (twt.trigger ? IFX_TWT_FLOW_FLAG_TRIGGER : 0); ++ val.desc.flow_flags |= ((twt.negotiation_type & 0x01) ? ++ IFX_TWT_FLOW_FLAG_WAKE_TBTT_NEGO : 0); ++ val.desc.flow_flags |= (twt.requestor ? IFX_TWT_FLOW_FLAG_REQUEST : 0); ++ val.desc.flow_flags |= (twt.protection ? IFX_TWT_FLOW_FLAG_PROTECT : 0); ++ ++ if (twt.flow_id) { ++ /* Flow ID */ ++ val.desc.flow_id = twt.flow_id; ++ } else if (twt.bcast_twt_id) { ++ /* Broadcast TWT ID */ ++ val.desc.bid = twt.bcast_twt_id; ++ } else { ++ /* Let the FW choose the Flow ID, Broadcast TWT ID */ ++ val.desc.flow_id = 0xFF; ++ val.desc.bid = 0xFF; ++ } ++ ++ if (twt.twt) { ++ /* Target Wake Time parameter */ ++ val.desc.wake_time_h = (u32)(twt.twt >> 32); ++ val.desc.wake_time_l = (u32)(twt.twt); ++ val.desc.wake_type = IFX_TWT_TIME_TYPE_BSS; ++ } else if (twt.twt_offset) { ++ /* Target Wake Time offset parameter */ ++ val.desc.wake_time_h = (u32)(twt.twt_offset >> 32); ++ val.desc.wake_time_l = (u32)(twt.twt_offset); ++ val.desc.wake_type = IFX_TWT_TIME_TYPE_OFFSET; ++ } else { ++ /* Let the FW choose the Target Wake Time */ ++ val.desc.wake_time_h = 0x0; ++ val.desc.wake_time_l = 0x0; ++ val.desc.wake_type = IFX_TWT_TIME_TYPE_AUTO; ++ } ++ ++ /* Wake Duration or Service Period */ ++ val.desc.wake_dur = ifx_twt_min_twt_to_wake_dur(twt.min_twt, ++ twt.min_twt_unit); ++ /* Wake Interval or Service Interval */ ++ val.desc.wake_int = ifx_twt_float_to_uint32(twt.exponent, ++ twt.mantissa); ++ /* TWT Negotiation_type */ ++ val.desc.negotiation_type = (u8)twt.negotiation_type; ++ err = brcmf_fil_xtlv_data_set(ifp, "twt", IFX_TWT_CMD_SETUP, ++ (void *)&val, sizeof(val)); ++ ++ brcmf_dbg(TRACE, "TWT setup\n" ++ "Setup command : %u\n" ++ "Flow flags : 0x %02x\n" ++ "Flow ID : %u\n" ++ "Broadcast TWT ID : %u\n" ++ "Wake Time H,L : 0x %08x %08x\n" ++ "Wake Type : %u\n" ++ "Wake Dururation : %u usecs\n" ++ "Wake Interval : %u usecs\n" ++ "Negotiation type : %u\n", ++ val.desc.setup_cmd, ++ val.desc.flow_flags, ++ val.desc.flow_id, ++ val.desc.bid, ++ val.desc.wake_time_h, ++ val.desc.wake_time_l, ++ val.desc.wake_type, ++ val.desc.wake_dur, ++ val.desc.wake_int, ++ val.desc.negotiation_type); ++ ++ if (err < 0) { ++ brcmf_err("TWT setup failed. ret:%d\n", err); ++ } ++ ++ return err; ++} ++ ++int ifx_twt_teardown(struct wireless_dev *wdev, struct ifx_twt twt) ++{ ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ ifx_twt_teardown_t val; ++ s32 err; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ ++ memset(&val, 0, sizeof(val)); ++ val.version = IFX_TWT_TEARDOWN_VER; ++ val.length = sizeof(val.version) + sizeof(val.length); ++ ++ if (twt.flow_id) { ++ /* Flow ID */ ++ val.teardesc.flow_id = twt.flow_id; ++ } else if (twt.bcast_twt_id) { ++ /* Broadcast TWT ID */ ++ val.teardesc.bid = twt.bcast_twt_id; ++ } else { ++ /* Let the FW choose the Flow ID, Broadcast TWT */ ++ val.teardesc.flow_id = 0xFF; ++ val.teardesc.bid = 0xFF; ++ } ++ ++ /* TWT Negotiation_type */ ++ val.teardesc.negotiation_type = (u8)twt.negotiation_type; ++ /* Teardown all Negotiated TWT */ ++ val.teardesc.alltwt = twt.teardown_all_twt; ++ err = brcmf_fil_xtlv_data_set(ifp, "twt", IFX_TWT_CMD_TEARDOWN, ++ (void *)&val, sizeof(val)); ++ ++ brcmf_dbg(TRACE, "TWT teardown\n" ++ "Flow ID : %u\n" ++ "Broadcast TWT ID : %u\n" ++ "Negotiation type : %u\n" ++ "Teardown all TWT : %u\n", ++ val.teardesc.flow_id, ++ val.teardesc.bid, ++ val.teardesc.negotiation_type, ++ val.teardesc.alltwt); ++ ++ if (err < 0) { ++ brcmf_err("TWT teardown failed. ret:%d\n", err); ++ } ++ ++ return err; ++} ++ ++int ifx_twt_oper(struct wireless_dev *wdev, struct ifx_twt twt) ++{ ++ int ret = -1; ++ ++ switch (twt.twt_oper) { ++ case IFX_TWT_OPER_SETUP: ++ ret = ifx_twt_setup(wdev, twt); ++ break; ++ case IFX_TWT_OPER_TEARDOWN: ++ ret = ifx_twt_teardown(wdev, twt); ++ break; ++ default: ++ brcmf_err("Requested TWT operation (%d) is not supported\n", ++ twt.twt_oper); ++ ret = -EINVAL; ++ goto exit; ++ } ++exit: ++ return ret; ++} ++ ++static void ++ifx_cfgvendor_twt_parse_params(const struct nlattr *attr_iter, ++ struct ifx_twt *twt) ++{ ++ int tmp, twt_param; ++ const struct nlattr *twt_param_iter; ++ ++ nla_for_each_nested(twt_param_iter, attr_iter, tmp) { ++ twt_param = nla_type(twt_param_iter); ++ switch (twt_param) { ++ case IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE: ++ twt->negotiation_type = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE: ++ twt->setup_cmd = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN: ++ twt->dialog_token = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME: ++ twt->twt = nla_get_u64(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET: ++ twt->twt_offset = nla_get_u64(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION: ++ twt->min_twt = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT: ++ twt->exponent = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA: ++ twt->mantissa = nla_get_u16(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR: ++ twt->requestor = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER: ++ twt->trigger = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT: ++ twt->implicit = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE: ++ twt->flow_type = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID: ++ twt->flow_id = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID: ++ twt->bcast_twt_id = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION: ++ twt->protection = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL: ++ twt->twt_channel = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED: ++ twt->twt_info_frame_disabled = ++ nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT: ++ twt->min_twt_unit = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT: ++ twt->teardown_all_twt = ++ nla_get_u8(twt_param_iter); ++ break; ++ default: ++ brcmf_dbg(TRACE, "Unknown TWT param %d, skipping\n", ++ twt_param); ++ break; ++ } ++ } ++} ++ ++int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, ++ struct wireless_dev *wdev, const void *data, int len) ++{ ++ int tmp, attr_type; ++ const struct nlattr *attr_iter; ++ ++ struct ifx_twt twt = { ++ .twt_oper = 0, ++ .negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_ITWT, ++ .setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST, ++ .dialog_token = 1, ++ .twt = 0, ++ .twt_offset = 0, ++ .requestor = 1, ++ .trigger = 0, ++ .implicit = 1, ++ .flow_type = 0, ++ .flow_id = 0, ++ .bcast_twt_id = 0, ++ .protection = 0, ++ .twt_channel = 0, ++ .twt_info_frame_disabled = 0, ++ .min_twt_unit = 0, ++ .teardown_all_twt = 0 ++ }; ++ ++ nla_for_each_attr(attr_iter, data, len, tmp) { ++ attr_type = nla_type(attr_iter); ++ ++ switch (attr_type) { ++ case IFX_VENDOR_ATTR_TWT_OPER: ++ twt.twt_oper = nla_get_u8(attr_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAMS: ++ ifx_cfgvendor_twt_parse_params(attr_iter, &twt); ++ break; ++ default: ++ brcmf_dbg(TRACE, "Unknown TWT attribute %d, skipping\n", ++ attr_type); ++ break; ++ } ++ } ++ ++ return ifx_twt_oper(wdev, twt); ++} ++ ++ +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index 522e617885e3..92bf53d26bce 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -1,13 +1,40 @@ +-/* SPDX-License-Identifier: ISC ++/* ++ * Infineon WLAN driver: vendor specific implement + * +- * Infineon Technologies OUI and vendor specific assignments +- * +- * $ Copyright Infineon $ ++ * ©2022 Cypress Semiconductor Corporation (an Infineon company) ++ * or an affiliate 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 ++ * affiliates ("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, non-exclusive, ++ * 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 expresswritten 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. + */ + + #ifndef IFX_VENDOR_H + #define IFX_VENDOR_H + ++#include ++ + /* This file is a registry of identifier assignments from the Infineon + * OUI 00:03:19 for purposes other than MAC address assignment. New identifiers + * can be assigned through normal review process for changes to the upstream +@@ -56,7 +83,7 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(RSV11) = 11, + SCMD(RSV12) = 12, + SCMD(RSV13) = 13, +- SCMD(RSV14) = 14, ++ SCMD(TWT) = 14, + SCMD(RSV15) = 15, + SCMD(MAX) = 16 + }; +@@ -78,5 +105,343 @@ enum ifx_vendor_attr { + IFX_VENDOR_ATTR_MAX = 11 + }; + ++/* TWT define/enum/struct ++ */ ++/* TWT cmd version*/ ++#define IFX_TWT_SETUP_VER 0u ++#define IFX_TWT_TEARDOWN_VER 0u ++/* Flow flags */ ++#define IFX_TWT_FLOW_FLAG_BROADCAST (1 << 0) ++#define IFX_TWT_FLOW_FLAG_IMPLICIT (1 << 1) ++#define IFX_TWT_FLOW_FLAG_UNANNOUNCED (1 << 2) ++#define IFX_TWT_FLOW_FLAG_TRIGGER (1 << 3) ++#define IFX_TWT_FLOW_FLAG_WAKE_TBTT_NEGO (1 << 4) ++#define IFX_TWT_FLOW_FLAG_REQUEST (1 << 5) ++#define IFX_TWT_FLOW_FLAG_PROTECT (1u << 0u) ++#define IFX_TWT_FLOW_FLAG_RESPONDER_PM (1u << 6u) ++#define IFX_TWT_FLOW_FLAG_UNSOLICITED (1u << 7u) ++/* Flow id */ ++#define IFX_TWT_FLOW_ID_FID 0x07u /* flow id */ ++#define IFX_TWT_FLOW_ID_GID_MASK 0x70u /* group id - broadcast TWT only */ ++#define IFX_TWT_FLOW_ID_GID_SHIFT 4u ++#define IFX_TWT_INV_BCAST_ID 0xFFu ++#define IFX_TWT_INV_FLOW_ID 0xFFu ++/* auto flow_id */ ++#define IFX_TWT_SETUP_FLOW_ID_AUTO 0xFFu ++/* auto broadcast ID */ ++#define IFX_TWT_SETUP_BCAST_ID_AUTO 0xFFu ++/* Infinite persistence for broadcast schedule */ ++#define IFX_TWT_INFINITE_BTWT_PERSIST 0xFFFFFFFFu ++/* Wake type */ ++/* TODO: not yet finalized */ ++#define IFX_TWT_TIME_TYPE_BSS 0u /* The time specified in wake_time_h/l is ++ * the BSS TSF time. ++ */ ++#define IFX_TWT_TIME_TYPE_OFFSET 1u /* The time specified in wake_time_h/l is an offset ++ * of the TSF time when the iovar is processed. ++ */ ++#define IFX_TWT_TIME_TYPE_AUTO 2u /* The target wake time is chosen internally by the FW */ ++ ++/* ++ * enum ifx_vendor_attr_twt - Attributes for the TWT vendor command ++ * ++ * @IFX_VENDOR_ATTR_TWT_UNSPEC: Reserved value 0 ++ * ++ * @IFX_VENDOR_ATTR_TWT_OPER: To specify the type of TWT operation ++ * to be performed. Uses attributes defined in enum ifx_twt_oper. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAMS: Nester attributes representing the ++ * parameters configured for TWT. These parameters are defined in ++ * the enum ifx_vendor_attr_twt_param. ++ * ++ * @IFX_VENDOR_ATTR_TWT_MAX: This acts as a the tail of cmds list. ++ * Make sure it located at the end of the list. ++ */ ++enum ifx_vendor_attr_twt { ++ IFX_VENDOR_ATTR_TWT_UNSPEC, ++ IFX_VENDOR_ATTR_TWT_OPER, ++ IFX_VENDOR_ATTR_TWT_PARAMS, ++ IFX_VENDOR_ATTR_TWT_MAX ++}; ++ ++/* ++ * enum ifx_twt_oper - TWT operation to be specified using the vendor ++ * attribute IFX_VENDOR_ATTR_TWT_OPER ++ * ++ * @IFX_TWT_OPER_UNSPEC: Reserved value 0 ++ * ++ * @IFX_TWT_OPER_SETUP: Setup a TWT session. Required parameters are ++ * obtained through the nested attrs under IFX_VENDOR_ATTR_TWT_PARAMS. ++ * ++ * @IFX_TWT_OPER_TEARDOWN: Teardown the already negotiated TWT session. ++ * Required parameters are obtained through the nested attrs under ++ * IFX_VENDOR_ATTR_TWT_PARAMS. ++ * ++ * @IFX_TWT_OPER_MAX: This acts as a the tail of the list. ++ * Make sure it located at the end of the list. ++ */ ++enum ifx_twt_oper { ++ IFX_TWT_OPER_UNSPEC, ++ IFX_TWT_OPER_SETUP, ++ IFX_TWT_OPER_TEARDOWN, ++ IFX_TWT_OPER_MAX ++}; ++ ++/* ++ * enum ifx_vendor_attr_twt_param - TWT parameters ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC: Reserved value 0 ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE: Specifies the type of Negotiation to be ++ * done during Setup. The four possible types are ++ * 0 - Individual TWT Negotiation ++ * 1 - Wake TBTT Negotiation ++ * 2 - Broadcast TWT in Beacon ++ * 3 - Broadcast TWT Membership Negotiation ++ * ++ * The possible values are defined in the enum ifx_twt_param_nego_type ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE: Specifies the type of TWT Setup frame ++ * when sent by the TWT Requesting STA ++ * 0 - Request ++ * 1 - Suggest ++ * 2 - Demand ++ * ++ * when sent by the TWT Responding STA. ++ * 3 - Grouping ++ * 4 - Accept ++ * 5 - Alternate ++ * 6 - Dictate ++ * 7 - Reject ++ * ++ * The possible values are defined in the enum ifx_twt_oper_setup_cmd_type. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN: Dialog Token used by the TWT Requesting STA to ++ * identify the TWT Setup request/response transaction. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME: Target Wake Time. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET: Target Wake Time Offset. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION: Nominal Minimum TWT Wake Duration. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT: TWT Wake Interval Exponent. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA: TWT Wake Interval Mantissa. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR: Specify this is a TWT Requesting / Responding STA. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER: Specify Trigger based / Non-Trigger based TWT Session. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT: Specify Implicit / Explicit TWT session. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE: Specify Un-Announced / Announced TWT session. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID: Flow ID of an iTWT session. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID: Brocast TWT ID of a bTWT session. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION: Specifies whether Tx within SP is protected. ++ * Set to 1 to indicate that TXOPs within the TWT SPs shall be initiated ++ * with a NAV protection mechanism, such as (MU) RTS/CTS or CTS-to-self frame; ++ * otherwise, it shall set it to 0. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL: TWT channel field which is set to 0, unless ++ * the HE STA sets up a subchannel selective transmission operation. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED: TWT Information frame RX handing ++ * disabled / enabled. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT: Nominal Minimum TWT Wake Duration ++ * Unit. 0 represents unit in "256 usecs" and 1 represents unit in "TUs". ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT: Teardown all negotiated TWT sessions. ++ * ++ * @IFX_VENDOR_ATTR_TWT_PARAM_MAX: This acts as a the tail of the list. ++ * Make sure it located at the end of the list. ++ */ ++enum ifx_vendor_attr_twt_param { ++ IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC, ++ IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE, ++ IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE, ++ IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN, ++ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME, ++ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET, ++ IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION, ++ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT, ++ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA, ++ IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR, ++ IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER, ++ IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT, ++ IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE, ++ IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID, ++ IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID, ++ IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION, ++ IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL, ++ IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED, ++ IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT, ++ IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT, ++ IFX_VENDOR_ATTR_TWT_PARAM_MAX ++}; ++ ++enum ifx_twt_param_nego_type { ++ IFX_TWT_PARAM_NEGO_TYPE_INVALID = -1, ++ IFX_TWT_PARAM_NEGO_TYPE_ITWT = 0, ++ IFX_TWT_PARAM_NEGO_TYPE_WAKE_TBTT = 1, ++ IFX_TWT_PARAM_NEGO_TYPE_BTWT_IE_BCN = 2, ++ IFX_TWT_PARAM_NEGO_TYPE_BTWT = 3, ++ IFX_TWT_PARAM_NEGO_TYPE_MAX = 4 ++}; ++ ++enum ifx_twt_oper_setup_cmd_type { ++ IFX_TWT_OPER_SETUP_CMD_TYPE_INVALID = -1, ++ IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST = 0, ++ IFX_TWT_OPER_SETUP_CMD_TYPE_SUGGEST = 1, ++ IFX_TWT_OPER_SETUP_CMD_TYPE_DEMAND = 2, ++ IFX_TWT_OPER_SETUP_CMD_TYPE_GROUPING = 3, ++ IFX_TWT_OPER_SETUP_CMD_TYPE_ACCEPT = 4, ++ IFX_TWT_OPER_SETUP_CMD_TYPE_ALTERNATE = 5, ++ IFX_TWT_OPER_SETUP_CMD_TYPE_DICTATE = 6, ++ IFX_TWT_OPER_SETUP_CMD_TYPE_REJECT = 7, ++ IFX_TWT_OPER_SETUP_CMD_TYPE_MAX = 8 ++}; ++ ++/* TWT top level command IDs */ ++enum { ++ IFX_TWT_CMD_ENAB = 0, ++ IFX_TWT_CMD_SETUP = 1, ++ IFX_TWT_CMD_TEARDOWN = 2, ++ IFX_TWT_CMD_INFO = 3, ++ IFX_TWT_CMD_AUTOSCHED = 4, ++ IFX_TWT_CMD_STATS = 5, ++ IFX_TWT_CMD_EARLY_TERM_TIME = 6, ++ IFX_TWT_CMD_RESP_CONFIG = 7, ++ IFX_TWT_CMD_SPPS_ENAB = 8, ++ IFX_TWT_CMD_FEATURES = 9, ++ IFX_TWT_CMD_LAST ++}; ++ ++static const struct nla_policy ++ifx_vendor_attr_twt_param_policy[IFX_VENDOR_ATTR_TWT_PARAM_MAX + 1] = { ++ [IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME] = {.type = NLA_U64}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET] = {.type = NLA_U64}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA] = {.type = NLA_U16}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAM_MAX] = {.type = NLA_U8}, ++}; ++ ++static const struct nla_policy ifx_vendor_attr_twt_policy[IFX_VENDOR_ATTR_TWT_MAX + 1] = { ++ [IFX_VENDOR_ATTR_TWT_UNSPEC] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_OPER] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_TWT_PARAMS] = ++ NLA_POLICY_NESTED(ifx_vendor_attr_twt_param_policy), ++ [IFX_VENDOR_ATTR_TWT_MAX] = {.type = NLA_U8}, ++}; ++ ++struct ifx_twt { ++ u8 twt_oper; ++ enum ifx_twt_param_nego_type negotiation_type; ++ enum ifx_twt_oper_setup_cmd_type setup_cmd; ++ u8 dialog_token; ++ u64 twt; ++ u64 twt_offset; ++ u8 min_twt; ++ u8 exponent; ++ u16 mantissa; ++ u8 requestor; ++ u8 trigger; ++ u8 implicit; ++ u8 flow_type; ++ u8 flow_id; ++ u8 bcast_twt_id; ++ u8 protection; ++ u8 twt_channel; ++ u8 twt_info_frame_disabled; ++ u8 min_twt_unit; ++ u8 teardown_all_twt; ++}; ++ ++/* ++ * NOTES: ++ * ifx_twt_sdesc_t is used to support both broadcast TWT and individual TWT. ++ * Value in bit[0:2] in 'flow_id' field is interpreted differently: ++ * - flow id for individual TWT (when IFX_TWT_FLOW_FLAG_BROADCAST bit is NOT set ++ * in 'flow_flags' field) ++ * - flow id as defined in Table 8-248l1 for broadcast TWT (when ++ * IFX_TWT_FLOW_FLAG_BROADCAST bit is set) ++ * In latter case other bits could be used to differentiate different flows ++ * in order to support multiple broadcast TWTs with the same flow id. ++ */ ++ ++/* TWT Setup descriptor */ ++typedef struct ifx_twt_sdesc { ++ /* Setup Command. */ ++ u8 setup_cmd; /* See TWT_SETUP_CMD_XXXX in 802.11ah.h */ ++ u8 flow_flags; /* Flow attributes. See WL_TWT_FLOW_FLAG_XXXX below */ ++ u8 flow_id; /* must be between 0 and 7. Set 0xFF for auto assignment */ ++ u8 wake_type; /* See WL_TWT_TIME_TYPE_XXXX below */ ++ u32 wake_time_h; /* target wake time - BSS TSF (us) */ ++ u32 wake_time_l; ++ u32 wake_dur; /* target wake duration in unit of microseconds */ ++ u32 wake_int; /* target wake interval */ ++ u32 btwt_persistence; /* Broadcast TWT Persistence */ ++ u32 wake_int_max; /* max wake interval(uS) for TWT */ ++ u8 duty_cycle_min; /* min duty cycle for TWT(Percentage) */ ++ u8 pad; ++ u8 bid; /* must be between 0 and 31. Set 0xFF for auto assignment */ ++ u8 channel; /* Twt channel - Not used for now */ ++ u8 negotiation_type; /* Negotiation Type: See macros TWT_NEGO_TYPE_X */ ++ u8 frame_recomm; /* frame recommendation for broadcast TWTs - Not used for now */ ++} ifx_twt_sdesc_t; ++ ++/* twt teardown descriptor */ ++typedef struct ifx_twt_teardesc { ++ u8 negotiation_type; ++ u8 flow_id; /* must be between 0 and 7 */ ++ u8 bid; /* must be between 0 and 31 */ ++ u8 alltwt; /* all twt teardown - 0 or 1 */ ++} ifx_twt_teardesc_t; ++ ++/* HE TWT Setup command */ ++typedef struct ifx_twt_setup { ++ /* structure control */ ++ u16 version; /* structure version */ ++ u16 length; /* data length (starting after this field) */ ++ /* peer address */ ++ struct ether_addr peer; /* leave it all 0s' for AP */ ++ u8 pad[2]; ++ /* setup descriptor */ ++ ifx_twt_sdesc_t desc; ++} ifx_twt_setup_t; ++ ++/* HE TWT Teardown command */ ++typedef struct ifx_twt_teardown { ++ /* structure control */ ++ u16 version; /* structure version */ ++ u16 length; /* data length (starting after this field) */ ++ /* peer address */ ++ struct ether_addr peer; /* leave it all 0s' for AP */ ++ ifx_twt_teardesc_t teardesc; /* Teardown descriptor */ ++} ifx_twt_teardown_t; ++ ++int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, ++ struct wireless_dev *wdev, const void *data, int len); ++ + #endif /* IFX_VENDOR_H */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0157-non-upstream-vendor-cmd-addition-for-wl-he-bsscolor.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0157-non-upstream-vendor-cmd-addition-for-wl-he-bsscolor.patch new file mode 100644 index 000000000..0625b4e8d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0157-non-upstream-vendor-cmd-addition-for-wl-he-bsscolor.patch @@ -0,0 +1,232 @@ +From 1d8a90b83afb143644172476ef4c5019633731e7 Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Tue, 1 Nov 2022 04:16:58 -0500 +Subject: [PATCH 157/179] non-upstream: vendor cmd addition for "wl he + bsscolor" + +User can get HE bsscolor through iw vendor subcmd 0x10. + +Signed-off-by: JasonHuang +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 10 +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.h | 6 +++ + .../broadcom/brcm80211/brcmfmac/vendor.c | 10 +++- + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 50 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 41 ++++++++++++++- + 5 files changed, 106 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 62674335bb7e..f8b58aa8dcd1 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -30,6 +30,7 @@ + #include "fwil.h" + #include "proto.h" + #include "vendor.h" ++#include "vendor_ifx.h" + #include "bus.h" + #include "common.h" + +@@ -141,7 +142,6 @@ struct cca_msrmnt_query { + /* start enum value for BSS properties */ + #define WL_WSEC_INFO_BSS_BASE 0x0100 + #define WL_WSEC_INFO_BSS_ALGOS (WL_WSEC_INFO_BSS_BASE + 6) +-#define WL_HE_CMD_BSSCOLOR 5 + + static bool check_vif_up(struct brcmf_cfg80211_vif *vif) + { +@@ -409,12 +409,6 @@ struct wl_wsec_info { + struct wl_wsec_info_tlv tlvs[1]; /* tlv data follows */ + }; + +-struct bcm_xtlv { +- u16 id; +- u16 len; +- u8 data[1]; +-}; +- + static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg); + static bool + wl_cfgoce_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len, +@@ -5890,7 +5884,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, + u8 param[8] = {0}; + + he_tlv = (struct bcm_xtlv *)param; +- he_tlv->id = cpu_to_le16(WL_HE_CMD_BSSCOLOR); ++ he_tlv->id = cpu_to_le16(IFX_HE_CMD_BSSCOLOR); + he_tlv->len = cpu_to_le16(1); + memcpy(he_tlv->data, &settings->he_bss_color.color, sizeof(u8)); + err = brcmf_fil_iovar_data_set(ifp, "he", param, sizeof(param)); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +index e115d5d852e5..d9fd3cf9c3f2 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -438,6 +438,12 @@ struct brcmf_tlv { + u8 data[1]; + }; + ++struct bcm_xtlv { ++ u16 id; ++ u16 len; ++ u8 data[1]; ++}; ++ + static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg) + { + return cfg->wiphy; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index e85a99280604..8b8f41f294d4 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -261,8 +261,14 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + ifx_vendor_attr_twt_policy, + ifx_cfg80211_vndr_cmds_twt), + .maxattr = IFX_VENDOR_ATTR_TWT_MAX +- }, +- ++ }, ++ { ++ IFX_SUBCMD(BSSCOLOR, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ ifx_cfg80211_vndr_cmds_bsscolor) ++ }, + }; + + const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index 3e04a7dfe7cd..01b0139bcc0d 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -37,6 +37,23 @@ + #include "fwil.h" + #include "vendor_ifx.h" + ++static int ifx_cfg80211_vndr_send_cmd_reply(struct wiphy *wiphy, ++ const void *data, int len) ++{ ++ struct sk_buff *skb; ++ ++ /* Alloc the SKB for vendor_event */ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len); ++ if (unlikely(!skb)) { ++ brcmf_err("skb alloc failed\n"); ++ return -ENOMEM; ++ } ++ ++ /* Push the data to the skb */ ++ nla_put_nohdr(skb, len, data); ++ return cfg80211_vendor_cmd_reply(skb); ++} ++ + /* + * Wake Duration derivation from Nominal Minimum Wake Duration + */ +@@ -370,4 +387,37 @@ int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, + return ifx_twt_oper(wdev, twt); + } + ++int ifx_cfg80211_vndr_cmds_bsscolor(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len) ++{ ++ int ret = 0; ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ struct bcm_xtlv *he_tlv; ++ u8 val = *(u8 *)data; ++ u8 param[8] = {0}; + ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ he_tlv = (struct bcm_xtlv *)param; ++ he_tlv->id = cpu_to_le16(IFX_HE_CMD_BSSCOLOR); ++ ++ if (val == 0xa) { ++ /* To get fw iovars of the form "wl he bsscolor" using iw, ++ * call the parent iovar "he" with the subcmd filled and ++ * passed along ./iw dev wlan0 vendor recv 0x000319 0x10 0xa ++ */ ++ ret = brcmf_fil_iovar_data_get(ifp, "he", param, sizeof(param)); ++ if (ret) { ++ brcmf_err("get he bss_color error:%d\n", ret); ++ } else { ++ brcmf_dbg(INFO, "get he bss_color: %d\n", *param); ++ ifx_cfg80211_vndr_send_cmd_reply(wiphy, param, 1); ++ } ++ } else { ++ brcmf_dbg(INFO, "not support set bsscolor during runtime!\n"); ++ } ++ ++ return ret; ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index 92bf53d26bce..5d9a5099f230 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -85,7 +85,8 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(RSV13) = 13, + SCMD(TWT) = 14, + SCMD(RSV15) = 15, +- SCMD(MAX) = 16 ++ SCMD(BSSCOLOR) = 16, ++ SCMD(MAX) = 17 + }; + + /* enum ifx_vendor_attr - IFX nl80211 vendor attributes +@@ -321,6 +322,41 @@ enum { + IFX_TWT_CMD_LAST + }; + ++/** ++ * HE top level command IDs ++ */ ++enum { ++ IFX_HE_CMD_ENAB = 0, ++ IFX_HE_CMD_FEATURES = 1, ++ IFX_HE_CMD_TWT_SETUP = 2, ++ IFX_HE_CMD_TWT_TEARDOWN = 3, ++ IFX_HE_CMD_TWT_INFO = 4, ++ IFX_HE_CMD_BSSCOLOR = 5, ++ IFX_HE_CMD_PARTIAL_BSSCOLOR = 6, ++ IFX_HE_CMD_CAP = 7, ++ IFX_HE_CMD_STAID = 8, ++ IFX_HE_CMD_RTSDURTHRESH = 10, ++ IFX_HE_CMD_PEDURATION = 11, ++ IFX_HE_CMD_TESTBED_MODE = 12, ++ IFX_HE_CMD_OMI = 13, ++ IFX_HE_CMD_MAC_PAD_DUR = 14, ++ IFX_HE_CMD_MUEDCA = 15, ++ IFX_HE_CMD_MACCAP = 16, ++ IFX_HE_CMD_PHYCAP = 17, ++ IFX_HE_CMD_DISPLAY = 18, ++ IFX_HE_CMD_ACTION = 19, ++ IFX_HE_CMD_OFDMATX = 20, ++ IFX_HE_CMD_20IN80_MODE = 21, ++ IFX_HE_CMD_SMPS = 22, ++ IFX_HE_CMD_PPETHRESH = 23, ++ IFX_HE_CMD_HTC_OMI_EN = 24, ++ IFX_HE_CMD_ERSU_EN = 25, ++ IFX_HE_CMD_PREPUNCRX_EN = 26, ++ IFX_HE_CMD_MIMOCAP_EN = 27, ++ IFX_HE_CMD_MUEDCA_OPT = 28, ++ IFX_HE_CMD_LAST ++}; ++ + static const struct nla_policy + ifx_vendor_attr_twt_param_policy[IFX_VENDOR_ATTR_TWT_PARAM_MAX + 1] = { + [IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC] = {.type = NLA_U8}, +@@ -442,6 +478,9 @@ typedef struct ifx_twt_teardown { + + int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len); ++int ifx_cfg80211_vndr_cmds_bsscolor(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len); + + #endif /* IFX_VENDOR_H */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0158-non-upstream-vendor-cmd-addition-for-wl-he-muedca_op.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0158-non-upstream-vendor-cmd-addition-for-wl-he-muedca_op.patch new file mode 100644 index 000000000..0ac98322f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0158-non-upstream-vendor-cmd-addition-for-wl-he-muedca_op.patch @@ -0,0 +1,109 @@ +From f3fb3182fd4a6faff68a6c09bc02876e39b31fc5 Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Tue, 1 Nov 2022 02:47:44 -0500 +Subject: [PATCH 158/179] non-upstream: vendor cmd addition for "wl he + muedca_opt_enable" + +User can set/get HE muedca_opt_enable through iw vendor subcmd 0xb. + +Signed-off-by: JasonHuang +--- + .../broadcom/brcm80211/brcmfmac/vendor.c | 7 ++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 42 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 5 ++- + 3 files changed, 53 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index 8b8f41f294d4..e906effdd70d 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -254,6 +254,13 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + VENDOR_CMD_RAW_DATA, + brcmf_cfg80211_vndr_cmds_frameburst) + }, ++ { ++ IFX_SUBCMD(MUEDCA_OPT_ENABLE, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ ifx_cfg80211_vndr_cmds_muedca_opt) ++ }, + { + IFX_SUBCMD(TWT, + (WIPHY_VENDOR_CMD_NEED_WDEV | +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index 01b0139bcc0d..57069b4cd578 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -421,3 +421,45 @@ int ifx_cfg80211_vndr_cmds_bsscolor(struct wiphy *wiphy, + + return ret; + } ++ ++int ifx_cfg80211_vndr_cmds_muedca_opt(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len) ++{ ++ int ret = 0; ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ struct bcm_xtlv *he_tlv; ++ u8 val = *(u8 *)data; ++ u8 param[8] = {0}; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ he_tlv = (struct bcm_xtlv *)param; ++ he_tlv->id = cpu_to_le16(IFX_HE_CMD_MUEDCA_OPT); ++ ++ if (val == 0xa) { ++ /* To get fw iovars of the form "wl he muedca_opt_enable" ++ * using iw, call the parent iovar "he" with the subcmd ++ * filled and passed along ++ * ./iw dev wlan0 vendor recv 0x000319 0xb 0xa ++ */ ++ ret = brcmf_fil_iovar_data_get(ifp, "he", param, sizeof(param)); ++ if (ret) { ++ brcmf_err("get he muedca_opt_enable error:%d\n", ret); ++ } else { ++ brcmf_dbg(INFO, ++ "get he muedca_opt_enable: %d\n", *param); ++ ifx_cfg80211_vndr_send_cmd_reply(wiphy, param, 1); ++ } ++ } else { ++ he_tlv->len = cpu_to_le16(1); ++ he_tlv->data[0] = val; ++ ret = brcmf_fil_iovar_data_set(ifp, "he", ++ param, sizeof(param)); ++ if (ret) ++ brcmf_err("set he muedca_opt_enable error:%d\n", ret); ++ } ++ ++ return ret; ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index 5d9a5099f230..403972526c3b 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -80,7 +80,7 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(RSV8) = 8, + SCMD(RSV9) = 9, + SCMD(RSV10) = 10, +- SCMD(RSV11) = 11, ++ SCMD(MUEDCA_OPT_ENABLE) = 11, + SCMD(RSV12) = 12, + SCMD(RSV13) = 13, + SCMD(TWT) = 14, +@@ -481,6 +481,9 @@ int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, + int ifx_cfg80211_vndr_cmds_bsscolor(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len); ++int ifx_cfg80211_vndr_cmds_muedca_opt(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len); + + #endif /* IFX_VENDOR_H */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0159-non-upstream-vendor-cmd-addition-for-wl-amsdu.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0159-non-upstream-vendor-cmd-addition-for-wl-amsdu.patch new file mode 100644 index 000000000..b2e93ab25 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0159-non-upstream-vendor-cmd-addition-for-wl-amsdu.patch @@ -0,0 +1,99 @@ +From d35e722fa522c071788f6ce868852792e0ac98b1 Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Tue, 1 Nov 2022 02:55:11 -0500 +Subject: [PATCH 159/179] non-upstream: vendor cmd addition for "wl amsdu" + +User can set/get amsdu through iw vendor subcmd 0xd. + +Signed-off-by: JasonHuang +--- + .../broadcom/brcm80211/brcmfmac/vendor.c | 7 ++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 33 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 5 ++- + 3 files changed, 44 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index e906effdd70d..efdf98a42149 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -261,6 +261,13 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + VENDOR_CMD_RAW_DATA, + ifx_cfg80211_vndr_cmds_muedca_opt) + }, ++ { ++ IFX_SUBCMD(AMSDU, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ ifx_cfg80211_vndr_cmds_amsdu) ++ }, + { + IFX_SUBCMD(TWT, + (WIPHY_VENDOR_CMD_NEED_WDEV | +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index 57069b4cd578..94df8ea1ba32 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -463,3 +463,36 @@ int ifx_cfg80211_vndr_cmds_muedca_opt(struct wiphy *wiphy, + + return ret; + } ++ ++int ifx_cfg80211_vndr_cmds_amsdu(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len) ++{ ++ int ret = 0; ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ int val = *(s32 *)data; ++ s32 get_amsdu = 0; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ ++ if (val == 0xa) { ++ ret = brcmf_fil_iovar_int_get(ifp, "amsdu", &get_amsdu); ++ if (ret) { ++ brcmf_err("get amsdu error:%d\n", ret); ++ ++ return ret; ++ } ++ ++ brcmf_dbg(INFO, "get amsdu: %d\n", get_amsdu); ++ ifx_cfg80211_vndr_send_cmd_reply( ++ wiphy, &get_amsdu, sizeof(int)); ++ } else { ++ ret = brcmf_fil_iovar_int_set(ifp, "amsdu", val); ++ if (ret) ++ brcmf_err("set amsdu error:%d\n", ret); ++ } ++ ++ return ret; ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index 403972526c3b..2d418135d1b6 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -82,7 +82,7 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(RSV10) = 10, + SCMD(MUEDCA_OPT_ENABLE) = 11, + SCMD(RSV12) = 12, +- SCMD(RSV13) = 13, ++ SCMD(AMSDU) = 13, + SCMD(TWT) = 14, + SCMD(RSV15) = 15, + SCMD(BSSCOLOR) = 16, +@@ -484,6 +484,9 @@ int ifx_cfg80211_vndr_cmds_bsscolor(struct wiphy *wiphy, + int ifx_cfg80211_vndr_cmds_muedca_opt(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len); ++int ifx_cfg80211_vndr_cmds_amsdu(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len); + + #endif /* IFX_VENDOR_H */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0160-non-upstream-vendor-cmd-addition-for-wl-ldpc_cap.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0160-non-upstream-vendor-cmd-addition-for-wl-ldpc_cap.patch new file mode 100644 index 000000000..684e39d1f --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0160-non-upstream-vendor-cmd-addition-for-wl-ldpc_cap.patch @@ -0,0 +1,98 @@ +From 8eb9bcf0b2387eee4bc73e5757fa5016bf6d55d6 Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Tue, 1 Nov 2022 03:13:05 -0500 +Subject: [PATCH 160/179] non-upstream: vendor cmd addition for "wl ldpc_cap" + +User can set/get ldpc_cap through iw vendor subcmd 0xc. + +Signed-off-by: JasonHuang +--- + .../broadcom/brcm80211/brcmfmac/vendor.c | 7 ++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 32 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 5 ++- + 3 files changed, 43 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index efdf98a42149..2c27a5abdc03 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -261,6 +261,13 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + VENDOR_CMD_RAW_DATA, + ifx_cfg80211_vndr_cmds_muedca_opt) + }, ++ { ++ IFX_SUBCMD(LDPC_CAP, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ ifx_cfg80211_vndr_cmds_ldpc_cap) ++ }, + { + IFX_SUBCMD(AMSDU, + (WIPHY_VENDOR_CMD_NEED_WDEV | +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index 94df8ea1ba32..de397d8963cd 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -496,3 +496,35 @@ int ifx_cfg80211_vndr_cmds_amsdu(struct wiphy *wiphy, + + return ret; + } ++ ++int ifx_cfg80211_vndr_cmds_ldpc_cap(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len) ++{ ++ int ret = 0; ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ int val = *(s32 *)data; ++ s32 buf = 0; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ ++ if (val == 0xa) { ++ ret = brcmf_fil_iovar_int_get(ifp, "ldpc_cap", &buf); ++ if (ret) { ++ brcmf_err("get ldpc_cap error:%d\n", ret); ++ ++ return ret; ++ } ++ ++ brcmf_dbg(INFO, "get ldpc_cap: %d\n", buf); ++ ifx_cfg80211_vndr_send_cmd_reply(wiphy, &buf, sizeof(int)); ++ } else { ++ ret = brcmf_fil_iovar_int_set(ifp, "ldpc_cap", val); ++ if (ret) ++ brcmf_err("set ldpc_cap error:%d\n", ret); ++ } ++ ++ return ret; ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index 2d418135d1b6..35fc3aba3e71 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -81,7 +81,7 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(RSV9) = 9, + SCMD(RSV10) = 10, + SCMD(MUEDCA_OPT_ENABLE) = 11, +- SCMD(RSV12) = 12, ++ SCMD(LDPC_CAP) = 12, + SCMD(AMSDU) = 13, + SCMD(TWT) = 14, + SCMD(RSV15) = 15, +@@ -487,6 +487,9 @@ int ifx_cfg80211_vndr_cmds_muedca_opt(struct wiphy *wiphy, + int ifx_cfg80211_vndr_cmds_amsdu(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len); ++int ifx_cfg80211_vndr_cmds_ldpc_cap(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len); + + #endif /* IFX_VENDOR_H */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0161-non-upstream-Refine-TWT-code-for-checkpatch.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0161-non-upstream-Refine-TWT-code-for-checkpatch.patch new file mode 100644 index 000000000..44aa004ae --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0161-non-upstream-Refine-TWT-code-for-checkpatch.patch @@ -0,0 +1,560 @@ +From 97dbe8a93c26107eeb6363c6b6d738ec9da59481 Mon Sep 17 00:00:00 2001 +From: Ian Lin +Date: Tue, 1 Nov 2022 22:30:00 -0500 +Subject: [PATCH 161/179] non-upstream: Refine TWT code for checkpatch + +Fix license statement and coding style. + +Signed-off-by: Ian Lin +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 6 +- + .../broadcom/brcm80211/brcmfmac/vendor.c | 14 +- + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 213 +++++++++--------- + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 78 +++---- + 4 files changed, 149 insertions(+), 162 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index f8b58aa8dcd1..8346f357b8ec 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -7812,8 +7812,8 @@ brcmf_notify_beacon_loss(struct brcmf_if *ifp, + } + + int brcmf_notify_twt(struct brcmf_if *ifp, +- const struct brcmf_event_msg *e, +- void *data) ++ const struct brcmf_event_msg *e, ++ void *data) + { + brcmf_dbg(TRACE, "Enter\n"); + return 0; +@@ -7878,7 +7878,7 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) + brcmf_fweh_register(cfg->pub, BRCMF_E_BCNLOST_MSG, + brcmf_notify_beacon_loss); + brcmf_fweh_register(cfg->pub, BRCMF_E_TWT_SETUP, +- brcmf_notify_twt); ++ brcmf_notify_twt); + } + + static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index 2c27a5abdc03..79b4e8742f42 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -275,13 +275,13 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + VENDOR_CMD_RAW_DATA, + ifx_cfg80211_vndr_cmds_amsdu) + }, +- { +- IFX_SUBCMD(TWT, +- (WIPHY_VENDOR_CMD_NEED_WDEV | +- WIPHY_VENDOR_CMD_NEED_NETDEV), +- ifx_vendor_attr_twt_policy, +- ifx_cfg80211_vndr_cmds_twt), +- .maxattr = IFX_VENDOR_ATTR_TWT_MAX ++ { ++ IFX_SUBCMD(TWT, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ ifx_vendor_attr_twt_policy, ++ ifx_cfg80211_vndr_cmds_twt), ++ .maxattr = IFX_VENDOR_ATTR_TWT_MAX + }, + { + IFX_SUBCMD(BSSCOLOR, +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index de397d8963cd..c9aa4f61694f 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -1,5 +1,6 @@ +-/* +- * Infineon WLAN driver: vendor specific implement ++// SPDX-License-Identifier: ISC ++ ++/* Infineon WLAN driver: vendor specific implement + * + * ©2022 Cypress Semiconductor Corporation (an Infineon company) + * or an affiliate of Cypress Semiconductor Corporation. All rights reserved. +@@ -54,23 +55,19 @@ static int ifx_cfg80211_vndr_send_cmd_reply(struct wiphy *wiphy, + return cfg80211_vendor_cmd_reply(skb); + } + +-/* +- * Wake Duration derivation from Nominal Minimum Wake Duration +- */ ++/* Wake Duration derivation from Nominal Minimum Wake Duration */ + static inline u32 + ifx_twt_min_twt_to_wake_dur(u8 min_twt, u8 min_twt_unit) + { + u32 wake_dur; + + if (min_twt_unit == 1) { +- /* +- * If min_twt_unit is 1, then min_twt is ++ /* If min_twt_unit is 1, then min_twt is + * in units of TUs (i.e) 102400 usecs. + */ + wake_dur = (u32)min_twt * 102400; + } else if (min_twt_unit == 0) { +- /* +- * If min_twt_unit is 0, then min_twt is ++ /* If min_twt_unit is 0, then min_twt is + * in units of 256 usecs. + */ + wake_dur = (u32)min_twt * 256; +@@ -82,9 +79,7 @@ ifx_twt_min_twt_to_wake_dur(u8 min_twt, u8 min_twt_unit) + return wake_dur; + } + +-/* +- * Wake Interval derivation from Wake Interval Mantissa & Exponent +- */ ++/* Wake Interval derivation from Wake Interval Mantissa & Exponent */ + static inline u32 + ifx_twt_float_to_uint32(u8 exponent, u16 mantissa) + { +@@ -95,7 +90,7 @@ int ifx_twt_setup(struct wireless_dev *wdev, struct ifx_twt twt) + { + struct brcmf_cfg80211_vif *vif; + struct brcmf_if *ifp; +- ifx_twt_setup_t val; ++ struct ifx_twt_setup val; + s32 err; + + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); +@@ -156,18 +151,18 @@ int ifx_twt_setup(struct wireless_dev *wdev, struct ifx_twt twt) + + /* Wake Duration or Service Period */ + val.desc.wake_dur = ifx_twt_min_twt_to_wake_dur(twt.min_twt, +- twt.min_twt_unit); ++ twt.min_twt_unit); + /* Wake Interval or Service Interval */ + val.desc.wake_int = ifx_twt_float_to_uint32(twt.exponent, +- twt.mantissa); ++ twt.mantissa); + /* TWT Negotiation_type */ + val.desc.negotiation_type = (u8)twt.negotiation_type; + err = brcmf_fil_xtlv_data_set(ifp, "twt", IFX_TWT_CMD_SETUP, +- (void *)&val, sizeof(val)); ++ (void *)&val, sizeof(val)); + + brcmf_dbg(TRACE, "TWT setup\n" + "Setup command : %u\n" +- "Flow flags : 0x %02x\n" ++ "Flow flags : 0x %02x\n" + "Flow ID : %u\n" + "Broadcast TWT ID : %u\n" + "Wake Time H,L : 0x %08x %08x\n" +@@ -186,9 +181,8 @@ int ifx_twt_setup(struct wireless_dev *wdev, struct ifx_twt twt) + val.desc.wake_int, + val.desc.negotiation_type); + +- if (err < 0) { ++ if (err < 0) + brcmf_err("TWT setup failed. ret:%d\n", err); +- } + + return err; + } +@@ -197,7 +191,7 @@ int ifx_twt_teardown(struct wireless_dev *wdev, struct ifx_twt twt) + { + struct brcmf_cfg80211_vif *vif; + struct brcmf_if *ifp; +- ifx_twt_teardown_t val; ++ struct ifx_twt_teardown val; + s32 err; + + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); +@@ -224,7 +218,7 @@ int ifx_twt_teardown(struct wireless_dev *wdev, struct ifx_twt twt) + /* Teardown all Negotiated TWT */ + val.teardesc.alltwt = twt.teardown_all_twt; + err = brcmf_fil_xtlv_data_set(ifp, "twt", IFX_TWT_CMD_TEARDOWN, +- (void *)&val, sizeof(val)); ++ (void *)&val, sizeof(val)); + + brcmf_dbg(TRACE, "TWT teardown\n" + "Flow ID : %u\n" +@@ -236,9 +230,8 @@ int ifx_twt_teardown(struct wireless_dev *wdev, struct ifx_twt twt) + val.teardesc.negotiation_type, + val.teardesc.alltwt); + +- if (err < 0) { ++ if (err < 0) + brcmf_err("TWT teardown failed. ret:%d\n", err); +- } + + return err; + } +@@ -248,25 +241,25 @@ int ifx_twt_oper(struct wireless_dev *wdev, struct ifx_twt twt) + int ret = -1; + + switch (twt.twt_oper) { +- case IFX_TWT_OPER_SETUP: +- ret = ifx_twt_setup(wdev, twt); +- break; +- case IFX_TWT_OPER_TEARDOWN: +- ret = ifx_twt_teardown(wdev, twt); +- break; +- default: +- brcmf_err("Requested TWT operation (%d) is not supported\n", +- twt.twt_oper); +- ret = -EINVAL; +- goto exit; ++ case IFX_TWT_OPER_SETUP: ++ ret = ifx_twt_setup(wdev, twt); ++ break; ++ case IFX_TWT_OPER_TEARDOWN: ++ ret = ifx_twt_teardown(wdev, twt); ++ break; ++ default: ++ brcmf_err("Requested TWT operation (%d) is not supported\n", ++ twt.twt_oper); ++ ret = -EINVAL; ++ goto exit; + } + exit: + return ret; + } + + static void +-ifx_cfgvendor_twt_parse_params(const struct nlattr *attr_iter, +- struct ifx_twt *twt) ++ifx_cfgvendor_twt_parse_params(const struct nlattr *attr_iter, ++ struct ifx_twt *twt) + { + int tmp, twt_param; + const struct nlattr *twt_param_iter; +@@ -274,75 +267,73 @@ ifx_cfgvendor_twt_parse_params(const struct nlattr *attr_iter, + nla_for_each_nested(twt_param_iter, attr_iter, tmp) { + twt_param = nla_type(twt_param_iter); + switch (twt_param) { +- case IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE: +- twt->negotiation_type = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE: +- twt->setup_cmd = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN: +- twt->dialog_token = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME: +- twt->twt = nla_get_u64(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET: +- twt->twt_offset = nla_get_u64(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION: +- twt->min_twt = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT: +- twt->exponent = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA: +- twt->mantissa = nla_get_u16(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR: +- twt->requestor = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER: +- twt->trigger = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT: +- twt->implicit = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE: +- twt->flow_type = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID: +- twt->flow_id = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID: +- twt->bcast_twt_id = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION: +- twt->protection = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL: +- twt->twt_channel = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED: +- twt->twt_info_frame_disabled = +- nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT: +- twt->min_twt_unit = nla_get_u8(twt_param_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT: +- twt->teardown_all_twt = +- nla_get_u8(twt_param_iter); +- break; +- default: +- brcmf_dbg(TRACE, "Unknown TWT param %d, skipping\n", +- twt_param); +- break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE: ++ twt->negotiation_type = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE: ++ twt->setup_cmd = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN: ++ twt->dialog_token = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME: ++ twt->twt = nla_get_u64(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET: ++ twt->twt_offset = nla_get_u64(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION: ++ twt->min_twt = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT: ++ twt->exponent = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA: ++ twt->mantissa = nla_get_u16(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR: ++ twt->requestor = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER: ++ twt->trigger = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT: ++ twt->implicit = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE: ++ twt->flow_type = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID: ++ twt->flow_id = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID: ++ twt->bcast_twt_id = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION: ++ twt->protection = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL: ++ twt->twt_channel = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED: ++ twt->twt_info_frame_disabled = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT: ++ twt->min_twt_unit = nla_get_u8(twt_param_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT: ++ twt->teardown_all_twt = nla_get_u8(twt_param_iter); ++ break; ++ default: ++ brcmf_dbg(TRACE, "Unknown TWT param %d, skipping\n", ++ twt_param); ++ break; + } + } + } + +-int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, +- struct wireless_dev *wdev, const void *data, int len) ++int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, ++ struct wireless_dev *wdev, const void *data, int len) + { + int tmp, attr_type; + const struct nlattr *attr_iter; +@@ -371,16 +362,16 @@ int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, + attr_type = nla_type(attr_iter); + + switch (attr_type) { +- case IFX_VENDOR_ATTR_TWT_OPER: +- twt.twt_oper = nla_get_u8(attr_iter); +- break; +- case IFX_VENDOR_ATTR_TWT_PARAMS: +- ifx_cfgvendor_twt_parse_params(attr_iter, &twt); +- break; +- default: +- brcmf_dbg(TRACE, "Unknown TWT attribute %d, skipping\n", +- attr_type); +- break; ++ case IFX_VENDOR_ATTR_TWT_OPER: ++ twt.twt_oper = nla_get_u8(attr_iter); ++ break; ++ case IFX_VENDOR_ATTR_TWT_PARAMS: ++ ifx_cfgvendor_twt_parse_params(attr_iter, &twt); ++ break; ++ default: ++ brcmf_dbg(TRACE, "Unknown TWT attribute %d, skipping\n", ++ attr_type); ++ break; + } + } + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index 35fc3aba3e71..c18afdfb29f3 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -1,5 +1,6 @@ +-/* +- * Infineon WLAN driver: vendor specific implement ++// SPDX-License-Identifier: ISC ++ ++/* Infineon WLAN driver: vendor specific implement + * + * ©2022 Cypress Semiconductor Corporation (an Infineon company) + * or an affiliate of Cypress Semiconductor Corporation. All rights reserved. +@@ -112,15 +113,15 @@ enum ifx_vendor_attr { + #define IFX_TWT_SETUP_VER 0u + #define IFX_TWT_TEARDOWN_VER 0u + /* Flow flags */ +-#define IFX_TWT_FLOW_FLAG_BROADCAST (1 << 0) +-#define IFX_TWT_FLOW_FLAG_IMPLICIT (1 << 1) +-#define IFX_TWT_FLOW_FLAG_UNANNOUNCED (1 << 2) +-#define IFX_TWT_FLOW_FLAG_TRIGGER (1 << 3) +-#define IFX_TWT_FLOW_FLAG_WAKE_TBTT_NEGO (1 << 4) +-#define IFX_TWT_FLOW_FLAG_REQUEST (1 << 5) +-#define IFX_TWT_FLOW_FLAG_PROTECT (1u << 0u) +-#define IFX_TWT_FLOW_FLAG_RESPONDER_PM (1u << 6u) +-#define IFX_TWT_FLOW_FLAG_UNSOLICITED (1u << 7u) ++#define IFX_TWT_FLOW_FLAG_BROADCAST BIT(0) ++#define IFX_TWT_FLOW_FLAG_IMPLICIT BIT(1) ++#define IFX_TWT_FLOW_FLAG_UNANNOUNCED BIT(2) ++#define IFX_TWT_FLOW_FLAG_TRIGGER BIT(3) ++#define IFX_TWT_FLOW_FLAG_WAKE_TBTT_NEGO BIT(4) ++#define IFX_TWT_FLOW_FLAG_REQUEST BIT(5) ++#define IFX_TWT_FLOW_FLAG_PROTECT BIT(0) ++#define IFX_TWT_FLOW_FLAG_RESPONDER_PM BIT(6) ++#define IFX_TWT_FLOW_FLAG_UNSOLICITED BIT(7) + /* Flow id */ + #define IFX_TWT_FLOW_ID_FID 0x07u /* flow id */ + #define IFX_TWT_FLOW_ID_GID_MASK 0x70u /* group id - broadcast TWT only */ +@@ -135,16 +136,14 @@ enum ifx_vendor_attr { + #define IFX_TWT_INFINITE_BTWT_PERSIST 0xFFFFFFFFu + /* Wake type */ + /* TODO: not yet finalized */ +-#define IFX_TWT_TIME_TYPE_BSS 0u /* The time specified in wake_time_h/l is +- * the BSS TSF time. +- */ +-#define IFX_TWT_TIME_TYPE_OFFSET 1u /* The time specified in wake_time_h/l is an offset +- * of the TSF time when the iovar is processed. +- */ +-#define IFX_TWT_TIME_TYPE_AUTO 2u /* The target wake time is chosen internally by the FW */ +- +-/* +- * enum ifx_vendor_attr_twt - Attributes for the TWT vendor command ++/* The time specified in wake_time_h/l is the BSS TSF time. */ ++#define IFX_TWT_TIME_TYPE_BSS 0u ++/* The time specified in wake_time_h/l is an offset of the TSF time when the iovar is processed. */ ++#define IFX_TWT_TIME_TYPE_OFFSET 1u ++/* The target wake time is chosen internally by the FW */ ++#define IFX_TWT_TIME_TYPE_AUTO 2u ++ ++/* enum ifx_vendor_attr_twt - Attributes for the TWT vendor command + * + * @IFX_VENDOR_ATTR_TWT_UNSPEC: Reserved value 0 + * +@@ -165,8 +164,7 @@ enum ifx_vendor_attr_twt { + IFX_VENDOR_ATTR_TWT_MAX + }; + +-/* +- * enum ifx_twt_oper - TWT operation to be specified using the vendor ++/* enum ifx_twt_oper - TWT operation to be specified using the vendor + * attribute IFX_VENDOR_ATTR_TWT_OPER + * + * @IFX_TWT_OPER_UNSPEC: Reserved value 0 +@@ -188,8 +186,7 @@ enum ifx_twt_oper { + IFX_TWT_OPER_MAX + }; + +-/* +- * enum ifx_vendor_attr_twt_param - TWT parameters ++/* enum ifx_vendor_attr_twt_param - TWT parameters + * + * @IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC: Reserved value 0 + * +@@ -248,7 +245,7 @@ enum ifx_twt_oper { + * otherwise, it shall set it to 0. + * + * @IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL: TWT channel field which is set to 0, unless +- * the HE STA sets up a subchannel selective transmission operation. ++ * the HE STA sets up a subchannel selective transmission operation. + * + * @IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED: TWT Information frame RX handing + * disabled / enabled. +@@ -413,9 +410,8 @@ struct ifx_twt { + u8 teardown_all_twt; + }; + +-/* +- * NOTES: +- * ifx_twt_sdesc_t is used to support both broadcast TWT and individual TWT. ++/* NOTES: ++ * ifx_twt_sdesc is used to support both broadcast TWT and individual TWT. + * Value in bit[0:2] in 'flow_id' field is interpreted differently: + * - flow id for individual TWT (when IFX_TWT_FLOW_FLAG_BROADCAST bit is NOT set + * in 'flow_flags' field) +@@ -426,7 +422,7 @@ struct ifx_twt { + */ + + /* TWT Setup descriptor */ +-typedef struct ifx_twt_sdesc { ++struct ifx_twt_sdesc { + /* Setup Command. */ + u8 setup_cmd; /* See TWT_SETUP_CMD_XXXX in 802.11ah.h */ + u8 flow_flags; /* Flow attributes. See WL_TWT_FLOW_FLAG_XXXX below */ +@@ -444,18 +440,18 @@ typedef struct ifx_twt_sdesc { + u8 channel; /* Twt channel - Not used for now */ + u8 negotiation_type; /* Negotiation Type: See macros TWT_NEGO_TYPE_X */ + u8 frame_recomm; /* frame recommendation for broadcast TWTs - Not used for now */ +-} ifx_twt_sdesc_t; ++}; + + /* twt teardown descriptor */ +-typedef struct ifx_twt_teardesc { ++struct ifx_twt_teardesc { + u8 negotiation_type; + u8 flow_id; /* must be between 0 and 7 */ + u8 bid; /* must be between 0 and 31 */ + u8 alltwt; /* all twt teardown - 0 or 1 */ +-} ifx_twt_teardesc_t; ++}; + + /* HE TWT Setup command */ +-typedef struct ifx_twt_setup { ++struct ifx_twt_setup { + /* structure control */ + u16 version; /* structure version */ + u16 length; /* data length (starting after this field) */ +@@ -463,21 +459,21 @@ typedef struct ifx_twt_setup { + struct ether_addr peer; /* leave it all 0s' for AP */ + u8 pad[2]; + /* setup descriptor */ +- ifx_twt_sdesc_t desc; +-} ifx_twt_setup_t; ++ struct ifx_twt_sdesc desc; ++}; + + /* HE TWT Teardown command */ +-typedef struct ifx_twt_teardown { ++struct ifx_twt_teardown { + /* structure control */ + u16 version; /* structure version */ + u16 length; /* data length (starting after this field) */ + /* peer address */ + struct ether_addr peer; /* leave it all 0s' for AP */ +- ifx_twt_teardesc_t teardesc; /* Teardown descriptor */ +-} ifx_twt_teardown_t; ++ struct ifx_twt_teardesc teardesc; /* Teardown descriptor */ ++}; + +-int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, +- struct wireless_dev *wdev, const void *data, int len); ++int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, ++ struct wireless_dev *wdev, const void *data, int len); + int ifx_cfg80211_vndr_cmds_bsscolor(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0162-cfg80211-fix-u8-overflow-in-cfg80211_update_notliste.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0162-cfg80211-fix-u8-overflow-in-cfg80211_update_notliste.patch new file mode 100644 index 000000000..f890a30ef --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0162-cfg80211-fix-u8-overflow-in-cfg80211_update_notliste.patch @@ -0,0 +1,47 @@ +From 3db36d3c4f136d964317361417b41acd6c24aac8 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 28 Sep 2022 21:56:15 +0200 +Subject: [PATCH 162/179] cfg80211: fix u8 overflow in + cfg80211_update_notlisted_nontrans() + +In the copy code of the elements, we do the following calculation +to reach the end of the MBSSID element: + + /* copy the IEs after MBSSID */ + cpy_len = mbssid[1] + 2; + +This looks fine, however, cpy_len is a u8, the same as mbssid[1], +so the addition of two can overflow. In this case the subsequent +memcpy() will overflow the allocated buffer, since it copies 256 +bytes too much due to the way the allocation and memcpy() sizes +are calculated. + +Fix this by using size_t for the cpy_len variable. + +This fixes CVE-2022-41674. + +Reported-by: Soenke Huster +Tested-by: Soenke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +--- + net/wireless/scan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 1a8b76c9dd56..d9ab37a798f4 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2238,7 +2238,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, + size_t new_ie_len; + struct cfg80211_bss_ies *new_ies; + const struct cfg80211_bss_ies *old; +- u8 cpy_len; ++ size_t cpy_len; + + lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock); + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0163-cfg80211-mac80211-reject-bad-MBSSID-elements.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0163-cfg80211-mac80211-reject-bad-MBSSID-elements.patch new file mode 100644 index 000000000..4efaac7d0 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0163-cfg80211-mac80211-reject-bad-MBSSID-elements.patch @@ -0,0 +1,56 @@ +From e6707f03393600135cffaf09e7627976aa023d50 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 28 Sep 2022 22:01:37 +0200 +Subject: [PATCH 163/179] cfg80211/mac80211: reject bad MBSSID elements + +Per spec, the maximum value for the MaxBSSID ('n') indicator is 8, +and the minimum is 1 since a multiple BSSID set with just one BSSID +doesn't make sense (the # of BSSIDs is limited by 2^n). + +Limit this in the parsing in both cfg80211 and mac80211, rejecting +any elements with an invalid value. + +This fixes potentially bad shifts in the processing of these inside +the cfg80211_gen_new_bssid() function later. + +I found this during the investigation of CVE-2022-41674 fixed by the +previous patch. + +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Fixes: 78ac51f81532 ("mac80211: support multi-bssid") +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +--- + net/mac80211/util.c | 2 ++ + net/wireless/scan.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index be1911d8089f..00543ea9c6b5 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1414,6 +1414,8 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) { + if (elem->datalen < 2) + continue; ++ if (elem->data[0] < 1 || elem->data[0] > 8) ++ continue; + + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 new_bssid[ETH_ALEN]; +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index d9ab37a798f4..84c642eae4d8 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2103,6 +2103,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) { + if (elem->datalen < 4) + continue; ++ if (elem->data[0] < 1 || (int)elem->data[0] > 8) ++ continue; + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 profile_len; + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0164-cfg80211-fix-BSS-refcounting-bugs.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0164-cfg80211-fix-BSS-refcounting-bugs.patch new file mode 100644 index 000000000..7ad627f38 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0164-cfg80211-fix-BSS-refcounting-bugs.patch @@ -0,0 +1,93 @@ +From 877c5bacad0a6da2be85552d56459d51c392d518 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 30 Sep 2022 23:44:23 +0200 +Subject: [PATCH 164/179] cfg80211: fix BSS refcounting bugs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are multiple refcounting bugs related to multi-BSSID: + - In bss_ref_get(), if the BSS has a hidden_beacon_bss, then + the bss pointer is overwritten before checking for the + transmitted BSS, which is clearly wrong. Fix this by using + the bss_from_pub() macro. + + - In cfg80211_bss_update() we copy the transmitted_bss pointer + from tmp into new, but then if we release new, we'll unref + it erroneously. We already set the pointer and ref it, but + need to NULL it since it was copied from the tmp data. + + - In cfg80211_inform_single_bss_data(), if adding to the non- + transmitted list fails, we unlink the BSS and yet still we + return it, but this results in returning an entry without + a reference. We shouldn't return it anyway if it was broken + enough to not get added there. + +This fixes CVE-2022-42720. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: a3584f56de1c ("cfg80211: Properly track transmitting and non-transmitting BSS") +Signed-off-by: Johannes Berg +--- + net/wireless/scan.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 84c642eae4d8..5d82f61fc157 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev, + lockdep_assert_held(&rdev->bss_lock); + + bss->refcount++; +- if (bss->pub.hidden_beacon_bss) { +- bss = container_of(bss->pub.hidden_beacon_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } +- if (bss->pub.transmitted_bss) { +- bss = container_of(bss->pub.transmitted_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } ++ ++ if (bss->pub.hidden_beacon_bss) ++ bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++; ++ ++ if (bss->pub.transmitted_bss) ++ bss_from_pub(bss->pub.transmitted_bss)->refcount++; + } + + static inline void bss_ref_put(struct cfg80211_registered_device *rdev, +@@ -1741,6 +1735,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, + new->refcount = 1; + INIT_LIST_HEAD(&new->hidden_list); + INIT_LIST_HEAD(&new->pub.nontrans_list); ++ /* we'll set this later if it was non-NULL */ ++ new->pub.transmitted_bss = NULL; + + if (rcu_access_pointer(tmp->pub.proberesp_ies)) { + hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN); +@@ -1981,10 +1977,15 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, + spin_lock_bh(&rdev->bss_lock); + if (cfg80211_add_nontrans_list(non_tx_data->tx_bss, + &res->pub)) { +- if (__cfg80211_unlink_bss(rdev, res)) ++ if (__cfg80211_unlink_bss(rdev, res)) { + rdev->bss_generation++; ++ res = NULL; ++ } + } + spin_unlock_bh(&rdev->bss_lock); ++ ++ if (!res) ++ return NULL; + } + + trace_cfg80211_return_bss(&res->pub); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0165-cfg80211-avoid-nontransmitted-BSS-list-corruption.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0165-cfg80211-avoid-nontransmitted-BSS-list-corruption.patch new file mode 100644 index 000000000..19950a4a9 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0165-cfg80211-avoid-nontransmitted-BSS-list-corruption.patch @@ -0,0 +1,53 @@ +From 58cff7ff5016cb0a404844b68a06b50a3d777a83 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Sat, 1 Oct 2022 00:01:44 +0200 +Subject: [PATCH 165/179] cfg80211: avoid nontransmitted BSS list corruption +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If a non-transmitted BSS shares enough information (both +SSID and BSSID!) with another non-transmitted BSS of a +different AP, then we can find and update it, and then +try to add it to the non-transmitted BSS list. We do a +search for it on the transmitted BSS, but if it's not +there (but belongs to another transmitted BSS), the list +gets corrupted. + +Since this is an erroneous situation, simply fail the +list insertion in this case and free the non-transmitted +BSS. + +This fixes CVE-2022-42721. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Signed-off-by: Johannes Berg +--- + net/wireless/scan.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index 5d82f61fc157..c50c438fc403 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -423,6 +423,15 @@ cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss, + + rcu_read_unlock(); + ++ /* ++ * This is a bit weird - it's not on the list, but already on another ++ * one! The only way that could happen is if there's some BSSID/SSID ++ * shared by multiple APs in their multi-BSSID profiles, potentially ++ * with hidden SSID mixed in ... ignore it. ++ */ ++ if (!list_empty(&nontrans_bss->nontrans_list)) ++ return -EINVAL; ++ + /* add to the list */ + list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list); + return 0; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0166-brcmfmac-Fix-potential-buffer-overflow-in-brcmf_fweh.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0166-brcmfmac-Fix-potential-buffer-overflow-in-brcmf_fweh.patch new file mode 100644 index 000000000..5ef9b6897 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0166-brcmfmac-Fix-potential-buffer-overflow-in-brcmf_fweh.patch @@ -0,0 +1,124 @@ +From 6d1e8223e6a5ef42a86869e1a92ebf74a1381424 Mon Sep 17 00:00:00 2001 +From: Dokyung Song +Date: Fri, 21 Oct 2022 15:13:59 +0900 +Subject: [PATCH 166/179] brcmfmac: Fix potential buffer overflow in + brcmf_fweh_event_worker() + +This patch fixes an intra-object buffer overflow in brcmfmac that occurs +when the device provides a 'bsscfgidx' equal to or greater than the +buffer size. The patch adds a check that leads to a safe failure if that +is the case. + +This fixes CVE-2022-3628. + +UBSAN: array-index-out-of-bounds in drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +index 52 is out of range for type 'brcmf_if *[16]' +CPU: 0 PID: 1898 Comm: kworker/0:2 Tainted: G O 5.14.0+ #132 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 +Workqueue: events brcmf_fweh_event_worker +Call Trace: + dump_stack_lvl+0x57/0x7d + ubsan_epilogue+0x5/0x40 + __ubsan_handle_out_of_bounds+0x69/0x80 + ? memcpy+0x39/0x60 + brcmf_fweh_event_worker+0xae1/0xc00 + ? brcmf_fweh_call_event_handler.isra.0+0x100/0x100 + ? rcu_read_lock_sched_held+0xa1/0xd0 + ? rcu_read_lock_bh_held+0xb0/0xb0 + ? lockdep_hardirqs_on_prepare+0x273/0x3e0 + process_one_work+0x873/0x13e0 + ? lock_release+0x640/0x640 + ? pwq_dec_nr_in_flight+0x320/0x320 + ? rwlock_bug.part.0+0x90/0x90 + worker_thread+0x8b/0xd10 + ? __kthread_parkme+0xd9/0x1d0 + ? process_one_work+0x13e0/0x13e0 + kthread+0x379/0x450 + ? _raw_spin_unlock_irq+0x24/0x30 + ? set_kthread_struct+0x100/0x100 + ret_from_fork+0x1f/0x30 +================================================================================ +general protection fault, probably for non-canonical address 0xe5601c0020023fff: 0000 [#1] SMP KASAN +KASAN: maybe wild-memory-access in range [0x2b0100010011fff8-0x2b0100010011ffff] +CPU: 0 PID: 1898 Comm: kworker/0:2 Tainted: G O 5.14.0+ #132 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 +Workqueue: events brcmf_fweh_event_worker +RIP: 0010:brcmf_fweh_call_event_handler.isra.0+0x42/0x100 +Code: 89 f5 53 48 89 fb 48 83 ec 08 e8 79 0b 38 fe 48 85 ed 74 7e e8 6f 0b 38 fe 48 89 ea 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> 3c 02 00 0f 85 8b 00 00 00 4c 8b 7d 00 44 89 e0 48 ba 00 00 00 +RSP: 0018:ffffc9000259fbd8 EFLAGS: 00010207 +RAX: dffffc0000000000 RBX: ffff888115d8cd50 RCX: 0000000000000000 +RDX: 0560200020023fff RSI: ffffffff8304bc91 RDI: ffff888115d8cd50 +RBP: 2b0100010011ffff R08: ffff888112340050 R09: ffffed1023549809 +R10: ffff88811aa4c047 R11: ffffed1023549808 R12: 0000000000000045 +R13: ffffc9000259fca0 R14: ffff888112340050 R15: ffff888112340000 +FS: 0000000000000000(0000) GS:ffff88811aa00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 000000004053ccc0 CR3: 0000000112740000 CR4: 0000000000750ef0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +PKRU: 55555554 +Call Trace: + brcmf_fweh_event_worker+0x117/0xc00 + ? brcmf_fweh_call_event_handler.isra.0+0x100/0x100 + ? rcu_read_lock_sched_held+0xa1/0xd0 + ? rcu_read_lock_bh_held+0xb0/0xb0 + ? lockdep_hardirqs_on_prepare+0x273/0x3e0 + process_one_work+0x873/0x13e0 + ? lock_release+0x640/0x640 + ? pwq_dec_nr_in_flight+0x320/0x320 + ? rwlock_bug.part.0+0x90/0x90 + worker_thread+0x8b/0xd10 + ? __kthread_parkme+0xd9/0x1d0 + ? process_one_work+0x13e0/0x13e0 + kthread+0x379/0x450 + ? _raw_spin_unlock_irq+0x24/0x30 + ? set_kthread_struct+0x100/0x100 + ret_from_fork+0x1f/0x30 +Modules linked in: 88XXau(O) 88x2bu(O) +---[ end trace 41d302138f3ff55a ]--- +RIP: 0010:brcmf_fweh_call_event_handler.isra.0+0x42/0x100 +Code: 89 f5 53 48 89 fb 48 83 ec 08 e8 79 0b 38 fe 48 85 ed 74 7e e8 6f 0b 38 fe 48 89 ea 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> 3c 02 00 0f 85 8b 00 00 00 4c 8b 7d 00 44 89 e0 48 ba 00 00 00 +RSP: 0018:ffffc9000259fbd8 EFLAGS: 00010207 +RAX: dffffc0000000000 RBX: ffff888115d8cd50 RCX: 0000000000000000 +RDX: 0560200020023fff RSI: ffffffff8304bc91 RDI: ffff888115d8cd50 +RBP: 2b0100010011ffff R08: ffff888112340050 R09: ffffed1023549809 +R10: ffff88811aa4c047 R11: ffffed1023549808 R12: 0000000000000045 +R13: ffffc9000259fca0 R14: ffff888112340050 R15: ffff888112340000 +FS: 0000000000000000(0000) GS:ffff88811aa00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 000000004053ccc0 CR3: 0000000112740000 CR4: 0000000000750ef0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +PKRU: 55555554 +Kernel panic - not syncing: Fatal exception + +Reported-by: Dokyung Song +Reported-by: Jisoo Jang +Reported-by: Minsuk Kang +Reviewed-by: Arend van Spriel +Cc: +Signed-off-by: Dokyung Song +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20221021061359.GA550858@laguna +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +index b463bcf11863..cd0626a00333 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +@@ -228,6 +228,10 @@ static void brcmf_fweh_event_worker(struct work_struct *work) + brcmf_fweh_event_name(event->code), event->code, + event->emsg.ifidx, event->emsg.bsscfgidx, + event->emsg.addr); ++ if (event->emsg.bsscfgidx >= BRCMF_MAX_IFS) { ++ bphy_err(drvr, "invalid bsscfg index: %u\n", event->emsg.bsscfgidx); ++ goto event_free; ++ } + + /* convert event message */ + emsg_be = &event->emsg; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0167-non-upstream-vendor-cmd-addition-for-wl-oce-enable.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0167-non-upstream-vendor-cmd-addition-for-wl-oce-enable.patch new file mode 100644 index 000000000..f6e5ae76a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0167-non-upstream-vendor-cmd-addition-for-wl-oce-enable.patch @@ -0,0 +1,164 @@ +From 5e15eaed0b521726950e0c9394f88e401cfbb11b Mon Sep 17 00:00:00 2001 +From: JasonHuang +Date: Mon, 21 Nov 2022 02:41:14 -0600 +Subject: [PATCH 167/179] non-upstream: vendor cmd addition for "wl oce enable" + +User can set/get oce enable through iw vendor subcmd 0xf. + +Signed-off-by: JasonHuang +--- + .../broadcom/brcm80211/brcmfmac/vendor.c | 7 +++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 49 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 40 ++++++++++++++- + 3 files changed, 95 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index 79b4e8742f42..21964c80e963 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -283,6 +283,13 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + ifx_cfg80211_vndr_cmds_twt), + .maxattr = IFX_VENDOR_ATTR_TWT_MAX + }, ++ { ++ IFX_SUBCMD(OCE_ENABLE, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ ifx_cfg80211_vndr_cmds_oce_enable) ++ }, + { + IFX_SUBCMD(BSSCOLOR, + (WIPHY_VENDOR_CMD_NEED_WDEV | +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index c9aa4f61694f..bf49a750408e 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -519,3 +519,52 @@ int ifx_cfg80211_vndr_cmds_ldpc_cap(struct wiphy *wiphy, + + return ret; + } ++ ++int ifx_cfg80211_vndr_cmds_oce_enable(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len) ++{ ++ int ret = 0; ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ struct bcm_iov_buf *oce_iov; ++ struct bcm_xtlv *oce_xtlv; ++ u8 val = *(u8 *)data; ++ u8 param[16] = {0}; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ oce_iov = (struct bcm_iov_buf *)param; ++ oce_iov->version = cpu_to_le16(IFX_OCE_IOV_VERSION); ++ oce_iov->id = cpu_to_le16(IFX_OCE_CMD_ENABLE); ++ oce_xtlv = (struct bcm_xtlv *)oce_iov->data; ++ ++ if (val == 0xa) { ++ /* To get fw iovars of the form "wl oce enable" ++ * using iw, call the parent iovar "oce" with the subcmd ++ * filled and passed along ++ * ./iw dev wlan0 vendor recv 0x000319 0xf 0xa ++ */ ++ ret = brcmf_fil_iovar_data_get(ifp, "oce", ++ param, sizeof(param)); ++ if (ret) { ++ brcmf_err("get oce enable error:%d\n", ret); ++ } else { ++ brcmf_dbg(INFO, ++ "get oce enable: %d\n", oce_xtlv->data[0]); ++ ifx_cfg80211_vndr_send_cmd_reply(wiphy, oce_xtlv->data, ++ sizeof(int)); ++ } ++ } else { ++ oce_iov->len = cpu_to_le16(8); ++ oce_xtlv->id = cpu_to_le16(IFX_OCE_XTLV_ENABLE); ++ oce_xtlv->len = cpu_to_le16(1); ++ oce_xtlv->data[0] = val; ++ ret = brcmf_fil_iovar_data_set(ifp, "oce", ++ param, sizeof(param)); ++ if (ret) ++ brcmf_err("set oce enable error:%d\n", ret); ++ } ++ ++ return ret; ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index c18afdfb29f3..e32deb5338ce 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -60,6 +60,13 @@ + .policy = (_POLICY), \ + .doit = (_FN) + ++struct bcm_iov_buf { ++ u16 version; ++ u16 len; ++ u16 id; ++ u16 data[1]; ++}; ++ + enum ifx_nl80211_vendor_subcmds { + /* TODO: IFX Vendor subcmd enum IDs between 2-15 are reserved + * to be filled later with BRCM Vendor subcmds that are +@@ -85,7 +92,7 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(LDPC_CAP) = 12, + SCMD(AMSDU) = 13, + SCMD(TWT) = 14, +- SCMD(RSV15) = 15, ++ SCMD(OCE_ENABLE) = 15, + SCMD(BSSCOLOR) = 16, + SCMD(MAX) = 17 + }; +@@ -354,6 +361,34 @@ enum { + IFX_HE_CMD_LAST + }; + ++#define IFX_OCE_IOV_MAJOR_VER 1 ++#define IFX_OCE_IOV_MINOR_VER 1 ++#define IFX_OCE_IOV_MAJOR_VER_SHIFT 8 ++#define IFX_OCE_IOV_VERSION \ ++ ((IFX_OCE_IOV_MAJOR_VER << IFX_OCE_IOV_MAJOR_VER_SHIFT) | \ ++ IFX_OCE_IOV_MINOR_VER) ++ ++enum { ++ IFX_OCE_CMD_ENABLE = 1, ++ IFX_OCE_CMD_PROBE_DEF_TIME = 2, ++ IFX_OCE_CMD_FD_TX_PERIOD = 3, ++ IFX_OCE_CMD_FD_TX_DURATION = 4, ++ IFX_OCE_CMD_RSSI_TH = 5, ++ IFX_OCE_CMD_RWAN_LINKS = 6, ++ IFX_OCE_CMD_CU_TRIGGER = 7, ++ IFX_OCE_CMD_LAST ++}; ++ ++enum { ++ IFX_OCE_XTLV_ENABLE = 0x1, ++ IFX_OCE_XTLV_PROBE_DEF_TIME = 0x2, ++ IFX_OCE_XTLV_FD_TX_PERIOD = 0x3, ++ IFX_OCE_XTLV_FD_TX_DURATION = 0x4, ++ IFX_OCE_XTLV_RSSI_TH = 0x5, ++ IFX_OCE_XTLV_RWAN_LINKS = 0x6, ++ IFX_OCE_XTLV_CU_TRIGGER = 0x7 ++}; ++ + static const struct nla_policy + ifx_vendor_attr_twt_param_policy[IFX_VENDOR_ATTR_TWT_PARAM_MAX + 1] = { + [IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC] = {.type = NLA_U8}, +@@ -486,6 +521,9 @@ int ifx_cfg80211_vndr_cmds_amsdu(struct wiphy *wiphy, + int ifx_cfg80211_vndr_cmds_ldpc_cap(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len); ++int ifx_cfg80211_vndr_cmds_oce_enable(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len); + + #endif /* IFX_VENDOR_H */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0168-non-upstream-vendor-cmd-addition-for-wl-randmac.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0168-non-upstream-vendor-cmd-addition-for-wl-randmac.patch new file mode 100644 index 000000000..a51a81f58 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0168-non-upstream-vendor-cmd-addition-for-wl-randmac.patch @@ -0,0 +1,154 @@ +From 87f4e3fe8b5928c8c2bfd51f7dbbd59a7bd74872 Mon Sep 17 00:00:00 2001 +From: Ian Lin +Date: Wed, 23 Nov 2022 22:48:13 -0600 +Subject: [PATCH 168/179] non-upstream: vendor cmd addition for "wl randmac" + +User can set/get randmc through iw vendor subcmd 0x11 + + +Signed-off-by: Ian Lin +--- + .../broadcom/brcm80211/brcmfmac/vendor.c | 7 +++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 55 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 30 +++++++++- + 3 files changed, 91 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index 21964c80e963..2beda60c95ad 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -297,6 +297,13 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + VENDOR_CMD_RAW_DATA, + ifx_cfg80211_vndr_cmds_bsscolor) + }, ++ { ++ IFX_SUBCMD(RANDMAC, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ ifx_cfg80211_vndr_cmds_randmac) ++ }, + }; + + const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index bf49a750408e..c2bd8662362f 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -568,3 +568,58 @@ int ifx_cfg80211_vndr_cmds_oce_enable(struct wiphy *wiphy, + + return ret; + } ++ ++int ifx_cfg80211_vndr_cmds_randmac(struct wiphy *wiphy, ++ struct wireless_dev *wdev, const void *data, int len) ++{ ++ int ret = 0; ++ struct ifx_randmac iov_buf = {0}; ++ u8 val = *(u8 *)data; ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ iov_buf.version = WL_RANDMAC_API_VERSION; ++ iov_buf.subcmd_id = WL_RANDMAC_SUBCMD_ENABLE; ++ iov_buf.len = offsetof(struct ifx_randmac, data); ++ ++ if (val == 0x1) { ++ /* To set fw iovars of the form "wl randmac enable" using iw, call the ++ * parent iovar "randmac" with the subcmd filled and passed along ++ * ./iw dev wlan0 vendor send 0x000319 0x11 0x1 ++ */ ++ ret = brcmf_fil_bsscfg_data_set(ifp, "randmac", (void *)&iov_buf, iov_buf.len); ++ if (ret) ++ brcmf_err("Failed to set randmac enable: %d\n", ret); ++ } else if (val == 0x0) { ++ iov_buf.subcmd_id = WL_RANDMAC_SUBCMD_DISABLE; ++ /* To set fw iovars of the form "wl randmac disable" using iw, call the ++ * parent iovar "randmac" with the subcmd filled and passed along ++ * ./iw dev wlan0 vendor send 0x000319 0x11 0x0 ++ */ ++ ret = brcmf_fil_bsscfg_data_set(ifp, "randmac", (void *)&iov_buf, iov_buf.len); ++ if (ret) ++ brcmf_err("Failed to set randmac disable: %d\n", ret); ++ } else if (val == 0xa) { ++ int result_data = 0; ++ struct ifx_randmac *iov_resp = NULL; ++ u8 buf[64] = {0}; ++ /* To get fw iovars of the form "wl randmac" using iw, call the ++ * parent iovar "randmac" with the subcmd filled and passed along ++ * ./iw dev wlan0 vendor recv 0x000319 0x11 0xa ++ */ ++ memcpy(buf, (void *)&iov_buf, iov_buf.len); ++ ret = brcmf_fil_iovar_data_get(ifp, "randmac", (void *)buf, sizeof(buf)); ++ if (ret) { ++ brcmf_err("Failed to get randmac enable or disable: %d\n", ret); ++ } else { ++ iov_resp = (struct ifx_randmac *)buf; ++ if (iov_resp->subcmd_id == WL_RANDMAC_SUBCMD_ENABLE) ++ result_data = 1; ++ ifx_cfg80211_vndr_send_cmd_reply(wiphy, &result_data, sizeof(int)); ++ } ++ } ++ return ret; ++} ++ +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index e32deb5338ce..e8c25cde3d4f 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -94,7 +94,8 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(TWT) = 14, + SCMD(OCE_ENABLE) = 15, + SCMD(BSSCOLOR) = 16, +- SCMD(MAX) = 17 ++ SCMD(RANDMAC) = 17, ++ SCMD(MAX) = 18 + }; + + /* enum ifx_vendor_attr - IFX nl80211 vendor attributes +@@ -507,6 +508,30 @@ struct ifx_twt_teardown { + struct ifx_twt_teardesc teardesc; /* Teardown descriptor */ + }; + ++/* randmac define/enum/struct ++ */ ++#define WL_RANDMAC_API_VERSION 0x0100 /**< version 1.0 */ ++#define WL_RANDMAC_API_MIN_VERSION 0x0100 /**< version 1.0 */ ++ ++/** subcommands that can apply to randmac */ ++enum { ++ WL_RANDMAC_SUBCMD_NONE = 0, ++ WL_RANDMAC_SUBCMD_GET_VERSION = 1, ++ WL_RANDMAC_SUBCMD_ENABLE = 2, ++ WL_RANDMAC_SUBCMD_DISABLE = 3, ++ WL_RANDMAC_SUBCMD_CONFIG = 4, ++ WL_RANDMAC_SUBCMD_STATS = 5, ++ WL_RANDMAC_SUBCMD_CLEAR_STATS = 6, ++ WL_RANDMAC_SUBCMD_MAX ++}; ++ ++struct ifx_randmac { ++ u16 version; ++ u16 len; /* total length */ ++ u16 subcmd_id; /* subcommand id */ ++ u8 data[0]; /* subcommand data */ ++}; ++ + int ifx_cfg80211_vndr_cmds_twt(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int len); + int ifx_cfg80211_vndr_cmds_bsscolor(struct wiphy *wiphy, +@@ -524,6 +549,9 @@ int ifx_cfg80211_vndr_cmds_ldpc_cap(struct wiphy *wiphy, + int ifx_cfg80211_vndr_cmds_oce_enable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len); ++int ifx_cfg80211_vndr_cmds_randmac(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len); + + #endif /* IFX_VENDOR_H */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0169-brcmfmac-compile-warning-fix.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0169-brcmfmac-compile-warning-fix.patch new file mode 100644 index 000000000..bc2adc3da --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0169-brcmfmac-compile-warning-fix.patch @@ -0,0 +1,91 @@ +From 0948c8f462e0e35494ad90cd8615055d4ead9281 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Wed, 30 Nov 2022 19:42:13 -0600 +Subject: [PATCH 169/179] brcmfmac: compile warning fix + +Fixes: SWLINUX-3039 +Signed-off-by: Carter Chen +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 +++--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 1 - + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c | 8 +++++--- + 4 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 8346f357b8ec..628bd607a77d 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6184,8 +6184,8 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, + memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], + le16_to_cpu(action_frame->len)); + +- brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n", +- *cookie, le16_to_cpu(action_frame->len), freq); ++ brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, ch=%d\n", ++ *cookie, le16_to_cpu(action_frame->len), af_params->channel); + + ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg), + af_params, vif, chan); +@@ -6666,7 +6666,7 @@ brcmf_cfg80211_set_bitrate(struct wiphy *wiphy, struct net_device *ndev, + s32 ret = TIME_OK; + uint hegi; + u16 mcs_mask; +- u8 band, mcs; ++ u8 band, mcs = 0; + + ifp = netdev_priv(ndev); + ret = brcmf_fil_iovar_data_get(ifp, "he", he, sizeof(he)); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +index fe1d8d323fa7..0739b6a44b19 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -1265,7 +1265,6 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg, + { + struct brcmf_p2p_info *p2p = &cfg->p2p; + struct afx_hdl *afx_hdl = &p2p->afx_hdl; +- struct brcmu_chan ch; + u8 *ie; + s32 err; + u8 p2p_dev_addr[ETH_ALEN]; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index 1b811655cacc..95374f29e372 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -1624,7 +1624,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) + } + } else { + brcmf_err("overflowed glomd len(%d), ignore descriptor\n", +- dlen); ++ bus->glomd->len); + dlen = 0; + } + dptr = bus->glomd->data; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index 2beda60c95ad..af7ab86cf27c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -156,15 +156,17 @@ static int brcmf_cfg80211_vndr_cmds_frameburst(struct wiphy *wiphy, + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); + ifp = vif->ifp; + +- if (val == 0x0 || val == 0x1) ++ if (val == 0x0 || val == 0x1) { + ret = brcmf_cfg80211_vndr_cmds_int_set(ifp, val, + BRCMF_C_SET_FAKEFRAG); +- else if (val == 0xff) ++ } else if (val == 0xff) { + ret = brcmf_cfg80211_vndr_cmds_int_get(ifp, + BRCMF_C_GET_FAKEFRAG, + wiphy); +- else ++ } else { + brcmf_err("Invalid Input\n"); ++ ret = -EINVAL; ++ } + + return ret; + } +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0170-Fix-invalid-RAM-address-warning-for-PCIE-platforms.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0170-Fix-invalid-RAM-address-warning-for-PCIE-platforms.patch new file mode 100644 index 000000000..165fb734a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0170-Fix-invalid-RAM-address-warning-for-PCIE-platforms.patch @@ -0,0 +1,26 @@ +From 8a56e480a074eca34c573dd666c190e1e799d065 Mon Sep 17 00:00:00 2001 +From: Ramesh Rangavittal +Date: Tue, 25 Oct 2022 15:42:23 -0500 +Subject: [PATCH 170/179] Fix invalid RAM address warning for PCIE platforms + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index e0657c369e12..7e79d888e319 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -2099,6 +2099,9 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, + + /* Convert nvram_len to words to determine the length token */ + nvram_lenw = nvram_len / 4; ++ /* subtract word used to store the token itself on non-blhs devices */ ++ if (!devinfo->ci->blhs) ++ nvram_lenw -= 1; + nvram_csm = (~nvram_lenw << 16) | (nvram_lenw & 0x0000FFFF); + brcmf_fw_nvram_free(nvram); + } else { +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0171-brcmfmac-Fix-dpp-very-low-tput-issue.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0171-brcmfmac-Fix-dpp-very-low-tput-issue.patch new file mode 100644 index 000000000..db290d3db --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0171-brcmfmac-Fix-dpp-very-low-tput-issue.patch @@ -0,0 +1,58 @@ +From cc139e60d4e0081e111a9b0a0f38eb9178965fe9 Mon Sep 17 00:00:00 2001 +From: "Shankar Amar (IFINS CSS ICW ENG SW WFSW 1)" +Date: Thu, 1 Dec 2022 07:57:33 +0000 +Subject: [PATCH 171/179] brcmfmac: Fix dpp very low tput issue + +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 28 +++++++++++++++---- + 1 file changed, 23 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 628bd607a77d..c7e3f090dbcc 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2458,6 +2458,22 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + mfp = BRCMF_MFP_REQUIRED; + else if (rsn_cap & RSN_CAP_MFPC_MASK) + mfp = BRCMF_MFP_CAPABLE; ++ ++ /* In case of dpp, very low tput is observed if MFPC is set in ++ * firmmare. Firmware needs to ensure that MFPC is not set when ++ * MFPR was requested from fmac. However since this change being ++ * specific to DPP, fmac needs to set wpa_auth prior to mfp, so ++ * that firmware can use this info to prevent MFPC being set in ++ * case of dpp. ++ */ ++ if (val == WFA_AUTH_DPP) { ++ 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); ++ return err; ++ } ++ } + brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp); + + offset += RSN_CAP_LEN; +@@ -2475,11 +2491,13 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + } + + skip_mfp_config: +- 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); +- return err; ++ if (val != WFA_AUTH_DPP) { ++ 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); ++ return err; ++ } + } + + return err; +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0172-non-upstream-keep-IFX-license-header-for-non-upstrea.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0172-non-upstream-keep-IFX-license-header-for-non-upstrea.patch new file mode 100644 index 000000000..bcdf333fd --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0172-non-upstream-keep-IFX-license-header-for-non-upstrea.patch @@ -0,0 +1,65 @@ +From 7f06779d0c2bd76ca93cbed695afeb2c2a960f24 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Wed, 21 Dec 2022 21:39:56 -0600 +Subject: [PATCH 172/179] non-upstream: keep IFX license header for + non-upstream files + +Fixes: SWLINUX-3108 +Signed-off-by: Carter Chen +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.c | 2 -- + .../net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.h | 1 - + drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c | 4 +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h | 4 +--- + 4 files changed, 2 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.c +index ef6283622697..40bb59fbfb5c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.c +@@ -1,5 +1,3 @@ +-// 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 +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.h +index f0e6b38cf77f..28910878ead5 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio.h +@@ -1,4 +1,3 @@ +-/* 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 +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index c2bd8662362f..da050dfe0377 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -1,8 +1,6 @@ +-// SPDX-License-Identifier: ISC +- + /* Infineon WLAN driver: vendor specific implement + * +- * ©2022 Cypress Semiconductor Corporation (an Infineon company) ++ * Copyright 2022 Cypress Semiconductor Corporation (an Infineon company) + * or an affiliate 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 +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index e8c25cde3d4f..b0864f5eb504 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -1,8 +1,6 @@ +-// SPDX-License-Identifier: ISC +- + /* Infineon WLAN driver: vendor specific implement + * +- * ©2022 Cypress Semiconductor Corporation (an Infineon company) ++ * Copyright 2022 Cypress Semiconductor Corporation (an Infineon company) + * or an affiliate 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 +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0173-non-upstream-internal-sup-uses-join-command-to-send-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0173-non-upstream-internal-sup-uses-join-command-to-send-.patch new file mode 100644 index 000000000..eb9fce72d --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0173-non-upstream-internal-sup-uses-join-command-to-send-.patch @@ -0,0 +1,34 @@ +From d9e59d54d27d997354f81243d408ef92d6115ef7 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Mon, 19 Dec 2022 00:32:52 -0600 +Subject: [PATCH 173/179] non-upstream: internal sup uses join command to send + (re)assoc req + +Fixes: SWLINUX-3089 +Signed-off-by: Carter Chen + + + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index c7e3f090dbcc..1e67ca13ac24 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2892,7 +2892,10 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, + + brcmf_set_join_pref(ifp, &sme->bss_select); + +- if (sme->prev_bssid) { ++ /* The internal supplicant judges to use assoc or reassoc itself. ++ * it is not necessary to specify REASSOC ++ */ ++ if ((sme->prev_bssid) && !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) { + brcmf_dbg(CONN, "Trying to REASSOC\n"); + join_params_size = sizeof(ext_join_params->assoc_le); + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_REASSOC, +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0174-non-upstream-Supporting-IFX_vendor-commands-of-MBO.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0174-non-upstream-Supporting-IFX_vendor-commands-of-MBO.patch new file mode 100644 index 000000000..57c954ad0 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0174-non-upstream-Supporting-IFX_vendor-commands-of-MBO.patch @@ -0,0 +1,357 @@ +From 03127bc701a0be551e6999ef2b1e3049b3993163 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Tue, 29 Nov 2022 00:22:07 -0600 +Subject: [PATCH 174/179] non-upstream: Supporting IFX_vendor commands of MBO + +User can use wpa_cli mbo commands to replace wl mbo commands + +Fixes: SWLINUX-3020 +Signed-off-by: Carter Chen + + + +--- + .../broadcom/brcm80211/brcmfmac/vendor.c | 8 + + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 139 ++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 97 +++++++++++- + .../broadcom/brcm80211/brcmfmac/xtlv.c | 19 +++ + .../broadcom/brcm80211/brcmfmac/xtlv.h | 2 + + 5 files changed, 264 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index af7ab86cf27c..9d6fc7ca70ce 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -306,6 +306,14 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + VENDOR_CMD_RAW_DATA, + ifx_cfg80211_vndr_cmds_randmac) + }, ++ { ++ IFX_SUBCMD(MBO, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ ifx_vendor_attr_mbo_policy, ++ ifx_cfg80211_vndr_cmds_mbo), ++ .maxattr = IFX_VENDOR_ATTR_MBO_MAX ++ }, + }; + + const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index da050dfe0377..f9d70e398e07 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -35,6 +35,7 @@ + #include "debug.h" + #include "fwil.h" + #include "vendor_ifx.h" ++#include "xtlv.h" + + static int ifx_cfg80211_vndr_send_cmd_reply(struct wiphy *wiphy, + const void *data, int len) +@@ -621,3 +622,141 @@ int ifx_cfg80211_vndr_cmds_randmac(struct wiphy *wiphy, + return ret; + } + ++int ifx_cfg80211_vndr_cmds_mbo(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len) ++{ ++ int ret = 0; ++ int tmp, attr_type, mbo_param; ++ const struct nlattr *attr_iter, *mbo_param_iter; ++ ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ struct bcm_iov_buf *mbo_iov; ++ struct bcm_xtlv *mbo_xtlv; ++ u8 param[64] = {0}; ++ u16 buf_len = 0, buf_len_start = 0; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ mbo_iov = (struct bcm_iov_buf *)param; ++ mbo_iov->version = cpu_to_le16(IFX_MBO_IOV_VERSION); ++ mbo_xtlv = (struct bcm_xtlv *)mbo_iov->data; ++ buf_len_start = sizeof(param) - sizeof(struct bcm_iov_buf); ++ buf_len = buf_len_start; ++ ++ nla_for_each_attr(attr_iter, data, len, tmp) { ++ attr_type = nla_type(attr_iter); ++ ++ switch (attr_type) { ++ case IFX_VENDOR_ATTR_MBO_CMD: ++ mbo_iov->id = cpu_to_le16(nla_get_u8(attr_iter)); ++ break; ++ case IFX_VENDOR_ATTR_MBO_PARAMS: ++ nla_for_each_nested(mbo_param_iter, attr_iter, tmp) { ++ mbo_param = nla_type(mbo_param_iter); ++ ++ switch (mbo_param) { ++ case IFX_VENDOR_ATTR_MBO_PARAM_OPCLASS: ++ { ++ u8 op_class; ++ ++ op_class = nla_get_u8(mbo_param_iter); ++ brcmf_pack_xtlv(IFX_VENDOR_ATTR_MBO_PARAM_OPCLASS, ++ &op_class, sizeof(op_class), ++ (char **)&mbo_xtlv, &buf_len); ++ } ++ break; ++ case IFX_VENDOR_ATTR_MBO_PARAM_CHAN: ++ { ++ u8 chan; ++ ++ chan = nla_get_u8(mbo_param_iter); ++ brcmf_pack_xtlv(IFX_VENDOR_ATTR_MBO_PARAM_CHAN, ++ &chan, sizeof(chan), ++ (char **)&mbo_xtlv, &buf_len); ++ } ++ break; ++ case IFX_VENDOR_ATTR_MBO_PARAM_PREFERENCE: ++ { ++ u8 pref; ++ ++ pref = nla_get_u8(mbo_param_iter); ++ brcmf_pack_xtlv(IFX_VENDOR_ATTR_MBO_PARAM_PREFERENCE, ++ &pref, sizeof(pref), ++ (char **)&mbo_xtlv, &buf_len); ++ } ++ break; ++ case IFX_VENDOR_ATTR_MBO_PARAM_REASON_CODE: ++ { ++ u8 reason; ++ ++ reason = nla_get_u8(mbo_param_iter); ++ brcmf_pack_xtlv(IFX_VENDOR_ATTR_MBO_PARAM_REASON_CODE, ++ &reason, sizeof(reason), ++ (char **)&mbo_xtlv, &buf_len); ++ } ++ break; ++ case IFX_VENDOR_ATTR_MBO_PARAM_CELL_DATA_CAP: ++ { ++ u8 cell_data_cap; ++ ++ cell_data_cap = nla_get_u8(mbo_param_iter); ++ brcmf_pack_xtlv(IFX_VENDOR_ATTR_MBO_PARAM_CELL_DATA_CAP, ++ &cell_data_cap, sizeof(cell_data_cap), ++ (char **)&mbo_xtlv, &buf_len); ++ } ++ break; ++ case IFX_VENDOR_ATTR_MBO_PARAM_COUNTERS: ++ break; ++ case IFX_VENDOR_ATTR_MBO_PARAM_ENABLE: ++ { ++ u8 enable; ++ ++ enable = nla_get_u8(mbo_param_iter); ++ brcmf_pack_xtlv(IFX_VENDOR_ATTR_MBO_PARAM_ENABLE, ++ &enable, sizeof(enable), ++ (char **)&mbo_xtlv, &buf_len); ++ } ++ break; ++ case IFX_VENDOR_ATTR_MBO_PARAM_SUB_ELEM_TYPE: ++ { ++ u8 type; ++ ++ type = nla_get_u8(mbo_param_iter); ++ brcmf_pack_xtlv(IFX_VENDOR_ATTR_MBO_PARAM_SUB_ELEM_TYPE, ++ &type, sizeof(type), ++ (char **)&mbo_xtlv, &buf_len); ++ } ++ break; ++ case IFX_VENDOR_ATTR_MBO_PARAM_BTQ_TRIG_START_OFFSET: ++ case IFX_VENDOR_ATTR_MBO_PARAM_BTQ_TRIG_RSSI_DELTA: ++ case IFX_VENDOR_ATTR_MBO_PARAM_ANQP_CELL_SUPP: ++ case IFX_VENDOR_ATTR_MBO_PARAM_BIT_MASK: ++ case IFX_VENDOR_ATTR_MBO_PARAM_ASSOC_DISALLOWED: ++ case IFX_VENDOR_ATTR_MBO_PARAM_CELLULAR_DATA_PREF: ++ return -EOPNOTSUPP; ++ default: ++ brcmf_err("unknown mbo param attr:%d\n", mbo_param); ++ return -EINVAL; ++ } ++ } ++ break; ++ default: ++ brcmf_err("Unknown MBO attribute %d, skipping\n", ++ attr_type); ++ return -EINVAL; ++ } ++ } ++ ++ buf_len = buf_len_start - buf_len; ++ mbo_xtlv->len = cpu_to_le16(buf_len); ++ mbo_iov->len = cpu_to_le16(buf_len); ++ buf_len += sizeof(struct bcm_iov_buf); ++ ret = brcmf_fil_iovar_data_set(ifp, "mbo", param, buf_len); ++ ++ if (ret) ++ brcmf_err("set mbo enable error:%d\n", ret); ++ ++ return ret; ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index b0864f5eb504..353d7d7a4624 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -93,7 +93,8 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(OCE_ENABLE) = 15, + SCMD(BSSCOLOR) = 16, + SCMD(RANDMAC) = 17, +- SCMD(MAX) = 18 ++ SCMD(MBO) = 18, ++ SCMD(MAX) = 19 + }; + + /* enum ifx_vendor_attr - IFX nl80211 vendor attributes +@@ -113,6 +114,97 @@ enum ifx_vendor_attr { + IFX_VENDOR_ATTR_MAX = 11 + }; + ++#define IFX_MBO_IOV_MAJOR_VER 1 ++#define IFX_MBO_IOV_MINOR_VER 1 ++#define IFX_MBO_IOV_MAJOR_VER_SHIFT 8 ++#define IFX_MBO_IOV_VERSION \ ++ ((IFX_MBO_IOV_MAJOR_VER << IFX_MBO_IOV_MAJOR_VER_SHIFT) | \ ++ IFX_MBO_IOV_MINOR_VER) ++ ++enum ifx_vendor_attr_mbo_param { ++ IFX_VENDOR_ATTR_MBO_PARAM_UNSPEC = 0, ++ IFX_VENDOR_ATTR_MBO_PARAM_OPCLASS = 1, ++ IFX_VENDOR_ATTR_MBO_PARAM_CHAN = 2, ++ IFX_VENDOR_ATTR_MBO_PARAM_PREFERENCE = 3, ++ IFX_VENDOR_ATTR_MBO_PARAM_REASON_CODE = 4, ++ IFX_VENDOR_ATTR_MBO_PARAM_CELL_DATA_CAP = 5, ++ IFX_VENDOR_ATTR_MBO_PARAM_COUNTERS = 6, ++ IFX_VENDOR_ATTR_MBO_PARAM_ENABLE = 7, ++ IFX_VENDOR_ATTR_MBO_PARAM_SUB_ELEM_TYPE = 8, ++ IFX_VENDOR_ATTR_MBO_PARAM_BTQ_TRIG_START_OFFSET = 9, ++ IFX_VENDOR_ATTR_MBO_PARAM_BTQ_TRIG_RSSI_DELTA = 10, ++ IFX_VENDOR_ATTR_MBO_PARAM_ANQP_CELL_SUPP = 11, ++ IFX_VENDOR_ATTR_MBO_PARAM_BIT_MASK = 12, ++ IFX_VENDOR_ATTR_MBO_PARAM_ASSOC_DISALLOWED = 13, ++ IFX_VENDOR_ATTR_MBO_PARAM_CELLULAR_DATA_PREF = 14, ++ IFX_VENDOR_ATTR_MBO_PARAM_MAX = 15 ++}; ++ ++static const struct nla_policy ++ifx_vendor_attr_mbo_param_policy[IFX_VENDOR_ATTR_MBO_PARAM_MAX + 1] = { ++ [IFX_VENDOR_ATTR_MBO_PARAM_UNSPEC] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_OPCLASS] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_CHAN] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_PREFERENCE] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_REASON_CODE] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_CELL_DATA_CAP] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_COUNTERS] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_ENABLE] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_SUB_ELEM_TYPE] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_BTQ_TRIG_START_OFFSET] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_BTQ_TRIG_RSSI_DELTA] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_ANQP_CELL_SUPP] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_BIT_MASK] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_ASSOC_DISALLOWED] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_CELLULAR_DATA_PREF] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAM_MAX] = {.type = NLA_U8}, ++}; ++ ++enum ifx_vendor_attr_mbo { ++ IFX_VENDOR_ATTR_MBO_UNSPEC, ++ IFX_VENDOR_ATTR_MBO_CMD, ++ IFX_VENDOR_ATTR_MBO_PARAMS, ++ IFX_VENDOR_ATTR_MBO_MAX ++}; ++ ++static const struct nla_policy ifx_vendor_attr_mbo_policy[IFX_VENDOR_ATTR_MBO_MAX + 1] = { ++ [IFX_VENDOR_ATTR_MBO_UNSPEC] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_CMD] = {.type = NLA_U8}, ++ [IFX_VENDOR_ATTR_MBO_PARAMS] = ++ NLA_POLICY_NESTED(ifx_vendor_attr_mbo_param_policy), ++ [IFX_VENDOR_ATTR_MBO_MAX] = {.type = NLA_U8}, ++}; ++ ++enum { ++ IFX_MBO_CMD_ADD_CHAN_PREF = 1, ++ IFX_MBO_CMD_DEL_CHAN_PREF = 2, ++ IFX_MBO_CMD_LIST_CHAN_PREF = 3, ++ IFX_MBO_CMD_CELLULAR_DATA_CAP = 4, ++ IFX_MBO_CMD_DUMP_COUNTERS = 5, ++ IFX_MBO_CMD_CLEAR_COUNTERS = 6, ++ IFX_MBO_CMD_FORCE_ASSOC = 7, ++ IFX_MBO_CMD_BSSTRANS_REJECT = 8, ++ IFX_MBO_CMD_SEND_NOTIF = 9, ++ IFX_MBO_CMD_LAST ++}; ++ ++enum { ++ IFX_MBO_XTLV_OPCLASS = 0x1, ++ IFX_MBO_XTLV_CHAN = 0x2, ++ IFX_MBO_XTLV_PREFERENCE = 0x3, ++ IFX_MBO_XTLV_REASON_CODE = 0x4, ++ IFX_MBO_XTLV_CELL_DATA_CAP = 0x5, ++ IFX_MBO_XTLV_COUNTERS = 0x6, ++ IFX_MBO_XTLV_ENABLE = 0x7, ++ IFX_MBO_XTLV_SUB_ELEM_TYPE = 0x8, ++ IFX_MBO_XTLV_BTQ_TRIG_START_OFFSET = 0x9, ++ IFX_MBO_XTLV_BTQ_TRIG_RSSI_DELTA = 0xa, ++ IFX_MBO_XTLV_ANQP_CELL_SUPP = 0xb, ++ IFX_MBO_XTLV_BIT_MASK = 0xc, ++ IFX_MBO_XTLV_ASSOC_DISALLOWED = 0xd, ++ IFX_MBO_XTLV_CELLULAR_DATA_PREF = 0xe ++}; ++ + /* TWT define/enum/struct + */ + /* TWT cmd version*/ +@@ -550,6 +642,9 @@ int ifx_cfg80211_vndr_cmds_oce_enable(struct wiphy *wiphy, + int ifx_cfg80211_vndr_cmds_randmac(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len); ++int ifx_cfg80211_vndr_cmds_mbo(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len); + + #endif /* IFX_VENDOR_H */ + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c +index 2f3c451148db..03192de92e37 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c +@@ -80,3 +80,22 @@ void brcmf_xtlv_pack_header(struct brcmf_xtlv *xtlv, u16 id, u16 len, + memcpy(data_buf, data, len); + } + ++u32 brcmf_pack_xtlv(u16 id, char *data, u32 len, ++ char **buf, u16 *buflen) ++{ ++ u32 iolen; ++ ++ iolen = brcmf_xtlv_data_size(len, BRCMF_XTLV_OPTION_ALIGN32); ++ ++ if (iolen > *buflen) { ++ WARN(true, "xtlv buffer is too short"); ++ return 0; ++ } ++ ++ brcmf_xtlv_pack_header((void *)*buf, id, len, data, ++ BRCMF_XTLV_OPTION_ALIGN32); ++ ++ *buf = *buf + iolen; ++ *buflen -= iolen; ++ return iolen; ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.h +index e1930ce1b642..d460a7a3c774 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.h +@@ -27,5 +27,7 @@ enum brcmf_xtlv_option { + int brcmf_xtlv_data_size(int dlen, u16 opts); + void brcmf_xtlv_pack_header(struct brcmf_xtlv *xtlv, u16 id, u16 len, + const u8 *data, u16 opts); ++u32 brcmf_pack_xtlv(u16 id, char *data, u32 len, ++ char **buf, u16 *buflen); + + #endif /* __BRCMF_XTLV_H */ +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0175-brcmfmac-Set-corresponding-cqm-event-handlers-based-.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0175-brcmfmac-Set-corresponding-cqm-event-handlers-based-.patch new file mode 100644 index 000000000..aa8f99cfb --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0175-brcmfmac-Set-corresponding-cqm-event-handlers-based-.patch @@ -0,0 +1,134 @@ +From 7f991797f4db1f9e33f070af2c63e2a8c262f667 Mon Sep 17 00:00:00 2001 +From: Suresh Sanaboina +Date: Mon, 30 Jan 2023 23:23:30 -0600 +Subject: [PATCH 175/179] brcmfmac: Set corresponding cqm event handlers based + on rssi_event implemented version supported by FW + +Fixes: SWLINUX-3150 + +Signed-off-by: Suresh Sanaboina + + + +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 50 +++++++++++++------ + .../broadcom/brcm80211/brcmfmac/fwil_types.h | 5 +- + 2 files changed, 38 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 1e67ca13ac24..5be678c972d8 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6754,27 +6754,33 @@ brcmf_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp; +- struct wl_rssi_event rssi = {}; ++ struct wl_rssi_event rssi; + int err = 0; + + ifp = netdev_priv(dev); ++ if (rssi_thold == cfg->cqm_info.rssi_threshold) ++ return err; ++ + if (rssi_thold == 0) { +- cfg->cqm_info.enable = 0; +- cfg->cqm_info.rssi_threshold = 0; ++ rssi.rate_limit_msec = cpu_to_le32(0); ++ rssi.num_rssi_levels = 0; ++ rssi.version = WL_RSSI_EVENT_IFX_VERSION; + } else { +- cfg->cqm_info.enable = 1; +- cfg->cqm_info.rssi_threshold = rssi_thold; +- +- rssi.rate_limit_msec = 0; +- rssi.rssi_levels[rssi.num_rssi_levels++] = S8_MIN; +- rssi.rssi_levels[rssi.num_rssi_levels++] = +- cfg->cqm_info.rssi_threshold; +- rssi.rssi_levels[rssi.num_rssi_levels++] = S8_MAX; ++ rssi.rate_limit_msec = cpu_to_le32(0); ++ rssi.num_rssi_levels = 3; ++ rssi.rssi_levels[0] = S8_MIN; ++ rssi.rssi_levels[1] = rssi_thold; ++ rssi.rssi_levels[2] = S8_MAX; ++ rssi.version = WL_RSSI_EVENT_IFX_VERSION; + } + + err = brcmf_fil_iovar_data_set(ifp, "rssi_event", &rssi, sizeof(rssi)); +- if (err < 0) ++ if (err < 0) { + brcmf_err("set rssi_event iovar failed (%d)\n", err); ++ } else { ++ cfg->cqm_info.enable = rssi_thold ? 1 : 0; ++ cfg->cqm_info.rssi_threshold = rssi_thold; ++ } + + brcmf_dbg(TRACE, "enable = %d, rssi_threshold = %d\n", + cfg->cqm_info.enable, cfg->cqm_info.rssi_threshold); +@@ -7850,6 +7856,16 @@ static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) + + static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) + { ++ struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); ++ struct wl_rssi_event rssi_event = {}; ++ int err = 0; ++ ++ /* get supported version from firmware side */ ++ err = brcmf_fil_iovar_data_get(ifp, "rssi_event", &rssi_event, ++ sizeof(rssi_event)); ++ if (err) ++ brcmf_err("fail to get supported rssi_event version, err=%d\n", err); ++ + brcmf_fweh_register(cfg->pub, BRCMF_E_LINK, + brcmf_notify_connect_status); + brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND, +@@ -7884,8 +7900,12 @@ 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); ++ if (rssi_event.version == WL_RSSI_EVENT_IFX_VERSION) ++ brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, ++ brcmf_notify_rssi_change_ind); ++ else ++ 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, +@@ -7894,8 +7914,6 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) + brcmf_notify_mgmt_tx_status); + brcmf_fweh_register(cfg->pub, BRCMF_E_MGMT_FRAME_OFF_CHAN_COMPLETE, + brcmf_notify_mgmt_tx_status); +- brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, +- brcmf_notify_rssi_change_ind); + brcmf_fweh_register(cfg->pub, BRCMF_E_BCNLOST_MSG, + brcmf_notify_beacon_loss); + brcmf_fweh_register(cfg->pub, BRCMF_E_TWT_SETUP, +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +index 4365ca9eab5c..9b1fc6048b35 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +@@ -205,6 +205,8 @@ enum { + #define DL_TYPE_CLM 2 + + #define MAX_RSSI_LEVELS 8 ++#define WL_RSSI_EVENT_BRCM_VERSION 0 ++#define WL_RSSI_EVENT_IFX_VERSION 1 + + /* join preference types for join_pref iovar */ + enum brcmf_join_pref_types { +@@ -1127,7 +1129,8 @@ struct wl_rssi_event { + u32 rate_limit_msec; + u8 num_rssi_levels; + s8 rssi_levels[MAX_RSSI_LEVELS]; +- s8 pad[3]; ++ u8 version; ++ s8 pad[2]; + }; + + #endif /* FWIL_TYPES_H_ */ +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0176-non-upstream-isolate-power_save-off-and-mpc-0.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0176-non-upstream-isolate-power_save-off-and-mpc-0.patch new file mode 100644 index 000000000..a0cf9b71c --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0176-non-upstream-isolate-power_save-off-and-mpc-0.patch @@ -0,0 +1,173 @@ +From 0a76959421c318aa90be942332982e1c3f0652a7 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Mon, 6 Feb 2023 01:33:51 -0600 +Subject: [PATCH 176/179] non-upstream: isolate power_save off and mpc 0 + +while using iw power_save off command to call power_mgmt. +make it don't set mpc together. + +add a vendor command to support set/get mpc value via IFX OUI +iw dev wlan0 vendor send 0x000319 0x13 0x1 +iw dev wlan0 vendor recv 0x000319 0x13 0x10 + +Fixes: SWLINUX-3178 + +Signed-off-by: Carter Chen +Signed-off-by: Shelley Yang +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 12 ++----- + .../broadcom/brcm80211/brcmfmac/vendor.c | 7 +++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 31 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 30 +++++++++++++++++- + 4 files changed, 70 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 5be678c972d8..b7e3f4fc5f97 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1226,16 +1226,12 @@ 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)) { +- 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); +- ++ err = brcmf_fil_iovar_int_set(ifp, ++ "mpc", ++ ifp->drvr->req_mpc); + if (err) { + bphy_err(drvr, "fail to set mpc\n"); + return; +@@ -3679,8 +3675,6 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, + pm = PM_OFF; + } + +- brcmf_set_mpc(ifp, ifp->drvr->req_mpc); +- + brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled")); + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm); +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index 9d6fc7ca70ce..efe9368bb5f1 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -314,6 +314,13 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + ifx_cfg80211_vndr_cmds_mbo), + .maxattr = IFX_VENDOR_ATTR_MBO_MAX + }, ++ { ++ IFX_SUBCMD(MPC, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ ifx_cfg80211_vndr_cmds_mpc) ++ }, + }; + + const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index f9d70e398e07..1840abe15cab 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -760,3 +760,34 @@ int ifx_cfg80211_vndr_cmds_mbo(struct wiphy *wiphy, + + return ret; + } ++ ++int ifx_cfg80211_vndr_cmds_mpc(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len) ++{ ++ int ret = 0; ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ int val = *(s32 *)data; ++ s32 buf = 0; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ ++ if (val == 0xa) { ++ ret = brcmf_fil_iovar_int_get(ifp, "mpc", &buf); ++ if (ret) { ++ brcmf_err("get mpc error:%d\n", ret); ++ return ret; ++ } ++ ++ brcmf_dbg(INFO, "get mpc: %d\n", buf); ++ ifx_cfg80211_vndr_send_cmd_reply(wiphy, &buf, sizeof(int)); ++ } else { ++ ret = brcmf_fil_iovar_int_set(ifp, "mpc", val); ++ if (ret) ++ brcmf_err("set mpc error:%d\n", ret); ++ } ++ ++ return ret; ++} +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index 353d7d7a4624..a83ad615135f 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -73,8 +73,32 @@ enum ifx_nl80211_vendor_subcmds { + * @IFX_VENDOR_SCMD_DCMD: equivilent to SCMD_PRIV_STR in DHD. + * + * @IFX_VENDOR_SCMD_FRAMEBURST: align ID to DHD. ++ * ++ * @IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE: Vendor command to enable/disable HE MU-EDCA opt. ++ * ++ * @IFX_VENDOR_SCMD_LDPC_CAP: Vendor command enable/disable LDPC Capability. ++ * ++ * @IFX_VENDOR_SCMD_AMSDU: Vendor command to enable/disable AMSDU on all the TID queues. ++ * ++ * @IFX_VENDOR_SCMD_TWT: Vendor subcommand to configure TWT. ++ * Uses attributes defined in enum ifx_vendor_attr_twt. ++ * ++ * @IFX_VENDOR_SCMD_OCE_ENABLE: Vendor command to enable/disable OCE Capability. ++ * ++ * @IFX_VENDOR_SCMD_BSS_COLOR: Vendor command to get BSSCOLOR value. ++ * ++ * @IFX_VENDOR_SCMD_RANDMAC: Vendor command to enable/disable RANDMAC Capability. ++ * ++ * @IFX_VENDOR_SCMD_MBO: Vendor subcommand to configure MBO. ++ * Uses attributes defined in enum ifx_vendor_attr_mbo. ++ * ++ * @IFX_VENDOR_SCMD_MPC: Vendor command to set/get MPC setting. ++ * ++ * @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list. ++ * Make sure it located at the end of the list. + */ + /* Reserved 2-5 */ ++ + SCMD(UNSPEC) = 0, + SCMD(DCMD) = 1, + SCMD(RSV2) = 2, +@@ -94,7 +118,8 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(BSSCOLOR) = 16, + SCMD(RANDMAC) = 17, + SCMD(MBO) = 18, +- SCMD(MAX) = 19 ++ SCMD(MPC) = 19, ++ SCMD(MAX) = 20 + }; + + /* enum ifx_vendor_attr - IFX nl80211 vendor attributes +@@ -645,6 +670,9 @@ int ifx_cfg80211_vndr_cmds_randmac(struct wiphy *wiphy, + int ifx_cfg80211_vndr_cmds_mbo(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len); ++int ifx_cfg80211_vndr_cmds_mpc(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len); + + #endif /* IFX_VENDOR_H */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0177-brcmfmac-Add-NULL-checks-to-fix-multiple-NULL-pointe.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0177-brcmfmac-Add-NULL-checks-to-fix-multiple-NULL-pointe.patch new file mode 100644 index 000000000..96e8e066a --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0177-brcmfmac-Add-NULL-checks-to-fix-multiple-NULL-pointe.patch @@ -0,0 +1,93 @@ +From 37e1b49d7f6f0032be77027b64a1a682e2d46df8 Mon Sep 17 00:00:00 2001 +From: Ramesh Rangavittal +Date: Fri, 3 Feb 2023 00:35:51 -0600 +Subject: [PATCH 177/179] brcmfmac: Add NULL checks to fix multiple NULL + pointer dereferences + +Fixes: SWLINUX-3196 + +Signed-off-by: Ramesh Rangavittal + + + +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 26 +++++++++++++++++-- + 1 file 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 b7e3f4fc5f97..aec0e2dc41ca 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3720,7 +3720,13 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, + channel = bi->ctl_ch; + band = BRCMU_CHAN_BAND_TO_NL80211(ch.band); + freq = ieee80211_channel_to_frequency(channel, band); ++ if (!freq) ++ return -EINVAL; ++ + bss_data.chan = ieee80211_get_channel(wiphy, freq); ++ if (!bss_data.chan) ++ return -EINVAL; ++ + bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20; + bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime()); + +@@ -3834,8 +3840,16 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg, + + band = wiphy->bands[BRCMU_CHAN_BAND_TO_NL80211(ch.band)]; + freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band); ++ if (!freq) { ++ err = -EINVAL; ++ goto cleanup; ++ } + cfg->channel = freq; + notify_channel = ieee80211_get_channel(wiphy, freq); ++ if (!notify_channel) { ++ err = -EINVAL; ++ goto cleanup; ++ } + + notify_capability = le16_to_cpu(bi->capability); + notify_interval = le16_to_cpu(bi->beacon_period); +@@ -3856,12 +3870,12 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg, + + if (!bss) { + err = -ENOMEM; +- goto CleanUp; ++ goto cleanup; + } + + cfg80211_put_bss(wiphy, bss); + +-CleanUp: ++cleanup: + + kfree(buf); + +@@ -6396,7 +6410,11 @@ static int brcmf_cfg80211_get_channel(struct wiphy *wiphy, + } + + freq = ieee80211_channel_to_frequency(ch.control_ch_num, band); ++ if (!freq) ++ return -EINVAL; + chandef->chan = ieee80211_get_channel(wiphy, freq); ++ if (!chandef->chan) ++ return -EINVAL; + chandef->width = width; + chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band); + chandef->center_freq2 = 0; +@@ -7293,7 +7311,11 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, + + band = wiphy->bands[BRCMU_CHAN_BAND_TO_NL80211(ch.band)]; + freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band); ++ if (!freq) ++ err = -EINVAL; + notify_channel = ieee80211_get_channel(wiphy, freq); ++ if (!notify_channel) ++ err = -EINVAL; + + done: + kfree(buf); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0178-brcmfmac-fix-compiler-error.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0178-brcmfmac-fix-compiler-error.patch new file mode 100644 index 000000000..789cb53de --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0178-brcmfmac-fix-compiler-error.patch @@ -0,0 +1,38 @@ +From bff7bf21e1cc3b2e67dd64bc879d35f4698b656f Mon Sep 17 00:00:00 2001 +From: Shelley Yang +Date: Mon, 13 Feb 2023 04:15:32 -0600 +Subject: [PATCH 178/179] brcmfmac: fix compiler error + +Signed-off-by: Shelley Yang + + + +--- + 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 aec0e2dc41ca..06ae35d49134 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3821,7 +3821,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg, + buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); + if (buf == NULL) { + err = -ENOMEM; +- goto CleanUp; ++ goto cleanup; + } + + *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); +@@ -3830,7 +3830,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg, + buf, WL_BSS_INFO_MAX); + if (err) { + bphy_err(drvr, "WLC_GET_BSS_INFO failed: %d\n", err); +- goto CleanUp; ++ goto cleanup; + } + + bi = (struct brcmf_bss_info_le *)(buf + 4); +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/patches.cypress/0179-non-upstream-supporting-giartrx-IFX-vendor-ID.patch b/patch/kernel/archive/sunxi-5.15/patches.cypress/0179-non-upstream-supporting-giartrx-IFX-vendor-ID.patch new file mode 100644 index 000000000..59c09ffcc --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/patches.cypress/0179-non-upstream-supporting-giartrx-IFX-vendor-ID.patch @@ -0,0 +1,116 @@ +From d4d1a61163b546346961f958a57ca3c60bdfd686 Mon Sep 17 00:00:00 2001 +From: Carter Chen +Date: Fri, 17 Feb 2023 06:53:42 -0600 +Subject: [PATCH 179/179] non-upstream: supporting giartrx IFX vendor ID + +add a vendor command to support set/get giantrx value via IFX OUI +iw dev wlan0 vendor send 0x000319 0x13 0x1 +iw dev wlan0 vendor recv 0x000319 0x13 0xa + +Fixes: SWLINUX-3157 + +Signed-off-by: Carter Chen + + + +--- + .../broadcom/brcm80211/brcmfmac/vendor.c | 7 ++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 33 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 8 ++++- + 3 files changed, 47 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +index efe9368bb5f1..ff2d03e22e0b 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c +@@ -321,6 +321,13 @@ const struct wiphy_vendor_command brcmf_vendor_cmds[] = { + VENDOR_CMD_RAW_DATA, + ifx_cfg80211_vndr_cmds_mpc) + }, ++ { ++ IFX_SUBCMD(GIANTRX, ++ (WIPHY_VENDOR_CMD_NEED_WDEV | ++ WIPHY_VENDOR_CMD_NEED_NETDEV), ++ VENDOR_CMD_RAW_DATA, ++ ifx_cfg80211_vndr_cmds_giantrx) ++ }, + }; + + const struct nl80211_vendor_cmd_info brcmf_vendor_events[] = { +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +index 1840abe15cab..38e3043694c1 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +@@ -791,3 +791,36 @@ int ifx_cfg80211_vndr_cmds_mpc(struct wiphy *wiphy, + + return ret; + } ++ ++int ifx_cfg80211_vndr_cmds_giantrx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len) ++{ ++ int ret = 0; ++ struct brcmf_cfg80211_vif *vif; ++ struct brcmf_if *ifp; ++ int val = *(s32 *)data; ++ s32 buf = 0; ++ ++ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); ++ ifp = vif->ifp; ++ ++ if (val == 0xa) { ++ ret = brcmf_fil_iovar_int_get(ifp, "giantrx", &buf); ++ if (ret) { ++ brcmf_err("get giantrx error:%d\n", ret); ++ return ret; ++ } ++ ++ brcmf_dbg(INFO, "get giantrx: %d\n", buf); ++ ifx_cfg80211_vndr_send_cmd_reply(wiphy, &buf, sizeof(int)); ++ } else { ++ brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); ++ ret = brcmf_fil_iovar_int_set(ifp, "giantrx", val); ++ brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); ++ if (ret) ++ brcmf_err("set giantrx error:%d\n", ret); ++ } ++ return ret; ++} ++ +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +index a83ad615135f..791f76a6d036 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +@@ -94,6 +94,8 @@ enum ifx_nl80211_vendor_subcmds { + * + * @IFX_VENDOR_SCMD_MPC: Vendor command to set/get MPC setting. + * ++ * @IFX_VENDOR_SCMD_GIANTRX: Vendor command to set/get GIANTRX setting. ++ * + * @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list. + * Make sure it located at the end of the list. + */ +@@ -119,7 +121,8 @@ enum ifx_nl80211_vendor_subcmds { + SCMD(RANDMAC) = 17, + SCMD(MBO) = 18, + SCMD(MPC) = 19, +- SCMD(MAX) = 20 ++ SCMD(GIANTRX) = 20, ++ SCMD(MAX) = 21 + }; + + /* enum ifx_vendor_attr - IFX nl80211 vendor attributes +@@ -673,6 +676,9 @@ int ifx_cfg80211_vndr_cmds_mbo(struct wiphy *wiphy, + int ifx_cfg80211_vndr_cmds_mpc(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int len); ++int ifx_cfg80211_vndr_cmds_giantrx(struct wiphy *wiphy, ++ struct wireless_dev *wdev, ++ const void *data, int len); + + #endif /* IFX_VENDOR_H */ + +-- +2.17.1 + diff --git a/patch/kernel/archive/sunxi-5.15/series.conf b/patch/kernel/archive/sunxi-5.15/series.conf index 349523367..692284084 100644 --- a/patch/kernel/archive/sunxi-5.15/series.conf +++ b/patch/kernel/archive/sunxi-5.15/series.conf @@ -676,3 +676,184 @@ patches.armbian/arm-dts-sun8i-r40-add-nodes-for-audio-codec.patch patches.armbian/arm-dts-sun8i-r40-bananapi-m2-ultra-enable-audio-codec.patch patches.armbian/arm-dts-sun8i-v40-bananapi-m2-berry-enable-audio-codec.patch + + +patches.cypress/0020-non-upstream-Support-custom-PCIE-BAR-window-size.patch +patches.cypress/0105-brcmfmac-support-4373-pcie.patch +patches.cypress/0119-brcmfmac-do-not-disable-controller-in-apmode-stop.patch +patches.cypress/0087-brcmfmac-Add-SDIO-verdor-device-id-for-CYW89459-in-h.patch +patches.cypress/0118-brcmfmac-fixes-scan-invalid-channel-when-enable-host.patch +patches.cypress/0178-brcmfmac-fix-compiler-error.patch +patches.cypress/0054-brcmfmac-Fix-to-add-brcmf_clear_assoc_ies-when-rmmod.patch +patches.cypress/0172-non-upstream-keep-IFX-license-header-for-non-upstrea.patch +patches.cypress/0161-non-upstream-Refine-TWT-code-for-checkpatch.patch +patches.cypress/0006-non-upstream-make-setting-SDIO-workqueue-WQ_HIGHPRI-.patch +patches.cypress/0032-brcmfmac-add-54591-PCIE-device.patch +patches.cypress/0106-brcmfmac-extsae-supports-SAE-OKC-roam.patch +patches.cypress/0149-non-upstream-adding-vendor_cmds-are-with-IFX_OUI.patch +patches.cypress/0072-brcmfmac-Fix-connecting-enterprise-AP-failure.patch +patches.cypress/0058-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch +patches.cypress/0011-non-upstream-disable-command-decode-in-sdio_aos-for-.patch +patches.cypress/0081-brcmfmac-add-support-for-CYW43439-SDIO-chipset.patch +patches.cypress/0148-non-upstream-add-IFX-vendor-OUI-file.patch +patches.cypress/0162-cfg80211-fix-u8-overflow-in-cfg80211_update_notliste.patch +patches.cypress/0050-brcmfmac-fix-invalid-address-access-when-enabling-SC.patch +patches.cypress/0112-brcmfmac-skip-6G-oob-scan-report.patch +patches.cypress/0174-non-upstream-Supporting-IFX_vendor-commands-of-MBO.patch +patches.cypress/0015-non-upstream-add-sleep-in-bus-suspend-and-cfg80211-r.patch +patches.cypress/0121-brcmfmac-fixes-invalid-channel-still-in-the-channel-.patch +patches.cypress/0002-brcmfmac-support-AP-isolation.patch +patches.cypress/0017-non-upstream-fix-scheduling-while-atomic-issue-when-.patch +patches.cypress/0164-cfg80211-fix-BSS-refcounting-bugs.patch +patches.cypress/0128-brcmfmac-add-WPA3_AUTH_1X_SUITE_B_SHA384-related-sup.patch +patches.cypress/0059-brcmfmac-fix-SDIO-bus-errors-during-high-temp-tests.patch +patches.cypress/0027-nl80211-add-authorized-flag-to-CONNECT-event.patch +patches.cypress/0095-brcmfmac-revise-SoftAP-channel-setting.patch +patches.cypress/0157-non-upstream-vendor-cmd-addition-for-wl-he-bsscolor.patch +patches.cypress/0147-brcmfmac-add-interface-to-set-bsscolor-for-bring-up-.patch +patches.cypress/0141-brcmfmac-add-sanity-check-for-potential-underflow-an.patch +patches.cypress/0179-non-upstream-supporting-giartrx-IFX-vendor-ID.patch +patches.cypress/0067-brcmfmac-Remove-the-call-to-dtim_assoc-IOVAR.patch +patches.cypress/0040-non-upstream-disable-command-decode-in-sdio_aos-for-.patch +patches.cypress/0094-brcmfmac-Set-SDIO-workqueue-as-WQ_HIGHPRI.patch +patches.cypress/0107-nl80211-add-roaming-offload-support.patch +patches.cypress/0103-brcmfmac-add-support-for-CYW55560-PCIe-chipset.patch +patches.cypress/0132-brcmfmac-update-the-statically-defined-HE-MAC-PHY-Ca.patch +patches.cypress/0013-non-upstream-Enable-Process-and-forward-PHY_TEMP-eve.patch +patches.cypress/0117-revert-brcmfmac-Set-timeout-value-when-configuring-p.patch +patches.cypress/0038-non-upstream-workaround-for-4373-USB-WMM-5.2.27-test.patch +patches.cypress/0171-brcmfmac-Fix-dpp-very-low-tput-issue.patch +patches.cypress/0035-non-upstream-fix-43012-driver-reload-failure-after-D.patch +patches.cypress/0116-Changing-info-messages-under-debug-BRCMF_INFO_VAL.patch +patches.cypress/0082-brcmfmac-add-BT-shared-SDIO-support.patch +patches.cypress/0108-brcm80211-add-FT-11r-OKC-roaming-offload-support.patch +patches.cypress/0045-non-upstream-ignore-FW-BADARG-error-when-removing-no.patch +patches.cypress/0053-brcmfmac-Fix-to-add-skb-free-for-TIM-update-info-whe.patch +patches.cypress/0071-non-upstream-Revert-brcm80211-select-WANT_DEV_COREDU.patch +patches.cypress/0175-brcmfmac-Set-corresponding-cqm-event-handlers-based-.patch +patches.cypress/0051-brcmfmac-add-a-timer-to-read-console-periodically-in.patch +patches.cypress/0170-Fix-invalid-RAM-address-warning-for-PCIE-platforms.patch +patches.cypress/0055-brcmfmac-dump-dongle-memory-when-attaching-failed.patch +patches.cypress/0151-brcmfmac-skip-6GHz-capab-registration-with-cfg80211-.patch +patches.cypress/0134-brcmfmac-update-BIP-setting-and-wsec_info-for-GMAC-a.patch +patches.cypress/0056-brcmfmac-update-address-mode-via-test-tool-for-AP-mo.patch +patches.cypress/0019-brcmfmac-Support-multiple-AP-interfaces-and-fix-STA-.patch +patches.cypress/0077-brcmfmac-Fix-authentication-latency-caused-by-OBSS-s.patch +patches.cypress/0042-brcmfmac-support-the-forwarding-packet.patch +patches.cypress/0166-brcmfmac-Fix-potential-buffer-overflow-in-brcmf_fweh.patch +patches.cypress/0039-non-upstream-disable-command-decode-in-sdio_aos-for-.patch +patches.cypress/0079-brcmfmac-fix-sdio-watchdog-timer-start-fail-issue.patch +patches.cypress/0131-Remove-WARN_ON-while-no-6g-bw_cap.patch +patches.cypress/0110-Disable-out-of-band-device-wake-based-DeepSleep-Stat.patch +patches.cypress/0065-brcmfmac-support-station-interface-creation-version-.patch +patches.cypress/0060-brcmfmac-Add-dump_survey-cfg80211-ops-for-HostApd-Au.patch +patches.cypress/0154-brcmfmac-ext_owe-supporting.patch +patches.cypress/0124-brcmfmac-add-support-for-CYW55560-SDIO-chipset.patch +patches.cypress/0005-non-upstream-remove-WOWL-configuration-in-disconnect.patch +patches.cypress/0004-non-upstream-support-wake-on-ping-packet.patch +patches.cypress/0014-non-upstream-fix-continuous-802.1x-tx-pending-timeou.patch +patches.cypress/0066-brcmfmac-To-fix-crash-when-platform-does-not-contain.patch +patches.cypress/0008-non-upstream-Changes-to-improve-USB-Tx-throughput.patch +patches.cypress/0010-non-upstream-configure-wowl-parameters-in-suspend-fu.patch +patches.cypress/0083-brcmfmac-add-CYW43439-SR-related-changes.patch +patches.cypress/0024-nl80211-add-authorized-flag-back-to-ROAM-event.patch +patches.cypress/0007-non-upstream-avoid-network-disconnection-during-susp.patch +patches.cypress/0086-brcmfmac-fix-P2P-device-discovery-failure.patch +patches.cypress/0044-brcmfmac-don-t-allow-arp-nd-offload-to-be-enabled-if.patch +patches.cypress/0173-non-upstream-internal-sup-uses-join-command-to-send-.patch +patches.cypress/0062-brcmfmac-correctly-remove-all-p2p-vif.patch +patches.cypress/0146-brcmfmac-set-HE-6GHz-capabilities-for-bring-up-SAP.patch +patches.cypress/0084-brcmfmac-add-support-for-CYW43439-with-blank-OTP.patch +patches.cypress/0169-brcmfmac-compile-warning-fix.patch +patches.cypress/0142-brcmfmac-Fixing-vulnerability.patch +patches.cypress/0061-revert-brcmfmac-set-state-of-hanger-slot-to-FREE-whe.patch +patches.cypress/0120-brcmfmac-support-11ax-and-6G-band.patch +patches.cypress/0075-brcmfmac-Fix-PCIE-suspend-resume-issue.patch +patches.cypress/0001-non-upstream-add-sg-parameters-dts-parsing.patch +patches.cypress/0167-non-upstream-vendor-cmd-addition-for-wl-oce-enable.patch +patches.cypress/0026-brcmfmac-set-authorized-flag-in-ROAM-event-for-PMK-c.patch +patches.cypress/0047-brcmfmac-move-firmware-path-to-cypress-folder.patch +patches.cypress/0092-brcmfmac-support-54590-54594-PCIe-device-id.patch +patches.cypress/0022-brcmfmac-increase-dcmd-maximum-buffer-size.patch +patches.cypress/0023-brcmfmac-set-net-carrier-on-via-test-tool-for-AP-mod.patch +patches.cypress/0143-brcmfmac-Implementing-set_bitrate_mask-cfg80211-ops-.patch +patches.cypress/0129-non-upstream-Handle-the-6G-case-in-the-bw_cap-chansp.patch +patches.cypress/0130-net-brcm80211-Fix-race-on-timer_add-in-wifi-driver.patch +patches.cypress/0153-brcmfmac-remove-workaround-cause-the-FW-can-support-.patch +patches.cypress/0099-brcmfmac-fixes-CYW4373-SDIO-CMD53-error.patch +patches.cypress/0144-brcm80211-add-FT-PSK-roaming-offload-support.patch +patches.cypress/0063-brcmfmac-fix-firmware-trap-while-dumping-obss-stats.patch +patches.cypress/0109-brcmfmac-support-extsae-with-psk-1x-offloading.patch +patches.cypress/0138-brcmfmac-update-firmware-loading-name-for-CY5557x.patch +patches.cypress/0030-brcmfmac-To-support-printing-USB-console-messages.patch +patches.cypress/0113-Revert-brcmfmac-Improve-the-delay-during-scan.patch +patches.cypress/0049-non-upstream-free-eventmask_msg-after-updating-event.patch +patches.cypress/0114-brcmfmac-Improve-the-delay-during-scan.patch +patches.cypress/0029-brcmfmac-add-support-for-Opportunistic-Key-Caching.patch +patches.cypress/0102-brcmfmac-add-Cypress-PCIe-vendor-ID.patch +patches.cypress/0036-brcmfmac-reset-PMU-backplane-all-cores-in-CYW4373-du.patch +patches.cypress/0046-brcmfmac-Support-DPP-feature.patch +patches.cypress/0052-brcmfmac-return-error-when-getting-invalid-max_flowr.patch +patches.cypress/0093-Revert-non-upstream-make-setting-SDIO-workqueue-WQ_H.patch +patches.cypress/0125-brcmfmac-Modified-Kconfig-help-format.patch +patches.cypress/0158-non-upstream-vendor-cmd-addition-for-wl-he-muedca_op.patch +patches.cypress/0152-brcmfmac-set-HE-rate-only-if-HE-MCS-set-and-valid.patch +patches.cypress/0089-brcmfmac-Fix-AP-interface-delete-issue.patch +patches.cypress/0069-brcmfmac-Fix-for-when-connect-request-is-not-success.patch +patches.cypress/0016-brcmfmac-add-CYW43570-PCIE-device.patch +patches.cypress/0043-brcmfmac-add-a-variable-for-packet-forwarding-condit.patch +patches.cypress/0177-brcmfmac-Add-NULL-checks-to-fix-multiple-NULL-pointe.patch +patches.cypress/0156-non-upstream-Add-IFX-TWT-Offload-support.patch +patches.cypress/0111-brcmfmac-Improve-the-delay-during-scan.patch +patches.cypress/0091-brcmfmac-Fix-structure-size-for-WPA3-external-SAE.patch +patches.cypress/0048-brcmfmac-add-support-for-sof-time-stammping-for-tx-p.patch +patches.cypress/0009-brcmfmac-introduce-module-parameter-to-configure-def.patch +patches.cypress/0160-non-upstream-vendor-cmd-addition-for-wl-ldpc_cap.patch +patches.cypress/0126-brcmfmac-Fix-incorrect-WARN_ON-causing-set_pmk-failu.patch +patches.cypress/0034-non-upstream-fix-43012-insmod-after-rmmod-in-DS1-fai.patch +patches.cypress/0031-non-upstream-Fix-no-P2P-IE-in-probe-requests-issue.patch +patches.cypress/0041-non-upstream-disable-command-decode-in-sdio_aos-for-.patch +patches.cypress/0097-brcmfmac-use-request_firmware_direct-for-loading-boa.patch +patches.cypress/0135-brcmfmac-send-roam-request-when-supplicant-triggers-.patch +patches.cypress/0127-brcmfmac-report-cqm-rssi-event-based-on-rssi-change-.patch +patches.cypress/0028-brcmfmac-set-authorized-flag-in-CONNECT-event-for-PM.patch +patches.cypress/0073-brcmfmac-Fix-for-skbuf-allocation-failure-in-memory-.patch +patches.cypress/0068-brcmfmac-fix-CERT-P2P-5.1.10-failure.patch +patches.cypress/0064-brcmfmac-add-creating-station-interface-support.patch +patches.cypress/0025-brcmfmac-set-authorized-flag-in-ROAM-event-for-offlo.patch +patches.cypress/0096-brcmfmac-Optimize-CYW4373-SDIO-current.patch +patches.cypress/0003-non-upstream-make-firmware-eap_restrict-a-module-par.patch +patches.cypress/0176-non-upstream-isolate-power_save-off-and-mpc-0.patch +patches.cypress/0098-brcmfmac-enable-pmk-catching-for-ext-sae-wpa3-ap.patch +patches.cypress/0090-brcmfmac-Revise-channel-info-for-WPA3-external-SAE.patch +patches.cypress/0155-brcmfmac-Avoid-adding-two-sets-of-HE-Capab-and-Oper-.patch +patches.cypress/0100-brcmfmac-add-PCIe-mailbox-support-for-core-revision-.patch +patches.cypress/0168-non-upstream-vendor-cmd-addition-for-wl-randmac.patch +patches.cypress/0140-brcmfmac-SAP-mode-parsing-sae_h2e-setting-from-beaco.patch +patches.cypress/0070-brcmfmac-Avoiding-Connection-delay.patch +patches.cypress/0150-brcmfmac-introduce-a-module-parameter-to-disable-the.patch +patches.cypress/0080-brcmfmac-Frameburst-vendor-command-addition.patch +patches.cypress/0021-brcmfmac-support-for-virtual-interface-creation-from.patch +patches.cypress/0139-brcmfmac-use-SR-core-id-to-decide-SR-capability-for-.patch +patches.cypress/0137-brcmfmac-trying-to-get-GCMP-cap-before-doing-set-it.patch +patches.cypress/0133-brcmfmac-fix-set_pmk-warning-message.patch +patches.cypress/0074-brcmfmac-Update-SSID-of-hidden-AP-while-informing-it.patch +patches.cypress/0076-brcmfmac-disable-mpc-when-power_save-is-disabled.patch +patches.cypress/0165-cfg80211-avoid-nontransmitted-BSS-list-corruption.patch +patches.cypress/0159-non-upstream-vendor-cmd-addition-for-wl-amsdu.patch +patches.cypress/0115-brcmfmac-add-FW-AP-selection-mod-param.patch +patches.cypress/0101-brcmfmac-add-support-for-TRX-firmware-download.patch +patches.cypress/0163-cfg80211-mac80211-reject-bad-MBSSID-elements.patch +patches.cypress/0018-brcmfmac-Support-89459-pcie.patch +patches.cypress/0104-brcmfmac-add-bootloader-console-buffer-support-for-P.patch +patches.cypress/0145-brcmfmac-enable-6G-split-scanning-feature.patch +patches.cypress/0123-brcmfmac-support-signal-monitor-feature-for-wpa_supp.patch +patches.cypress/0085-brcmfmac-support-43439-Cypress-Vendor-and-Device-ID.patch +patches.cypress/0012-brcmfmac-increase-default-max-WOWL-patterns-to-16.patch +patches.cypress/0078-brcmfmac-support-external-SAE-authentication-in-stat.patch +patches.cypress/0136-brcmfmac-send-BCNLOST_MSG-event-on-beacon-loss-for-s.patch +patches.cypress/0057-brcmfmac-load-54591-firmware-for-chip-ID-0x4355.patch +patches.cypress/0033-non-upstream-support-DS1-exit-firmware-re-download.patch +patches.cypress/0037-non-upstream-calling-skb_orphan-before-sending-skb-t.patch +patches.cypress/0088-brcmfmac-Add-CYW89459-HW-ID-and-modify-sdio-F2-block.patch +patches.cypress/0122-non-upstream-Fix-lspci-not-enumerating-wifi-device-a.patch diff --git a/patch/kernel/archive/sunxi-5.15/series.cypress b/patch/kernel/archive/sunxi-5.15/series.cypress new file mode 100644 index 000000000..ca3a76f00 --- /dev/null +++ b/patch/kernel/archive/sunxi-5.15/series.cypress @@ -0,0 +1,179 @@ +patches.cypress/0020-non-upstream-Support-custom-PCIE-BAR-window-size.patch +patches.cypress/0105-brcmfmac-support-4373-pcie.patch +patches.cypress/0119-brcmfmac-do-not-disable-controller-in-apmode-stop.patch +patches.cypress/0087-brcmfmac-Add-SDIO-verdor-device-id-for-CYW89459-in-h.patch +patches.cypress/0118-brcmfmac-fixes-scan-invalid-channel-when-enable-host.patch +patches.cypress/0178-brcmfmac-fix-compiler-error.patch +patches.cypress/0054-brcmfmac-Fix-to-add-brcmf_clear_assoc_ies-when-rmmod.patch +patches.cypress/0172-non-upstream-keep-IFX-license-header-for-non-upstrea.patch +patches.cypress/0161-non-upstream-Refine-TWT-code-for-checkpatch.patch +patches.cypress/0006-non-upstream-make-setting-SDIO-workqueue-WQ_HIGHPRI-.patch +patches.cypress/0032-brcmfmac-add-54591-PCIE-device.patch +patches.cypress/0106-brcmfmac-extsae-supports-SAE-OKC-roam.patch +patches.cypress/0149-non-upstream-adding-vendor_cmds-are-with-IFX_OUI.patch +patches.cypress/0072-brcmfmac-Fix-connecting-enterprise-AP-failure.patch +patches.cypress/0058-brcmfmac-Fix-interoperating-DPP-and-other-encryption.patch +patches.cypress/0011-non-upstream-disable-command-decode-in-sdio_aos-for-.patch +patches.cypress/0081-brcmfmac-add-support-for-CYW43439-SDIO-chipset.patch +patches.cypress/0148-non-upstream-add-IFX-vendor-OUI-file.patch +patches.cypress/0162-cfg80211-fix-u8-overflow-in-cfg80211_update_notliste.patch +patches.cypress/0050-brcmfmac-fix-invalid-address-access-when-enabling-SC.patch +patches.cypress/0112-brcmfmac-skip-6G-oob-scan-report.patch +patches.cypress/0174-non-upstream-Supporting-IFX_vendor-commands-of-MBO.patch +patches.cypress/0015-non-upstream-add-sleep-in-bus-suspend-and-cfg80211-r.patch +patches.cypress/0121-brcmfmac-fixes-invalid-channel-still-in-the-channel-.patch +patches.cypress/0002-brcmfmac-support-AP-isolation.patch +patches.cypress/0017-non-upstream-fix-scheduling-while-atomic-issue-when-.patch +patches.cypress/0164-cfg80211-fix-BSS-refcounting-bugs.patch +patches.cypress/0128-brcmfmac-add-WPA3_AUTH_1X_SUITE_B_SHA384-related-sup.patch +patches.cypress/0059-brcmfmac-fix-SDIO-bus-errors-during-high-temp-tests.patch +patches.cypress/0027-nl80211-add-authorized-flag-to-CONNECT-event.patch +patches.cypress/0095-brcmfmac-revise-SoftAP-channel-setting.patch +patches.cypress/0157-non-upstream-vendor-cmd-addition-for-wl-he-bsscolor.patch +patches.cypress/0147-brcmfmac-add-interface-to-set-bsscolor-for-bring-up-.patch +patches.cypress/0141-brcmfmac-add-sanity-check-for-potential-underflow-an.patch +patches.cypress/0179-non-upstream-supporting-giartrx-IFX-vendor-ID.patch +patches.cypress/0067-brcmfmac-Remove-the-call-to-dtim_assoc-IOVAR.patch +patches.cypress/0040-non-upstream-disable-command-decode-in-sdio_aos-for-.patch +patches.cypress/0094-brcmfmac-Set-SDIO-workqueue-as-WQ_HIGHPRI.patch +patches.cypress/0107-nl80211-add-roaming-offload-support.patch +patches.cypress/0103-brcmfmac-add-support-for-CYW55560-PCIe-chipset.patch +patches.cypress/0132-brcmfmac-update-the-statically-defined-HE-MAC-PHY-Ca.patch +patches.cypress/0013-non-upstream-Enable-Process-and-forward-PHY_TEMP-eve.patch +patches.cypress/0117-revert-brcmfmac-Set-timeout-value-when-configuring-p.patch +patches.cypress/0038-non-upstream-workaround-for-4373-USB-WMM-5.2.27-test.patch +patches.cypress/0171-brcmfmac-Fix-dpp-very-low-tput-issue.patch +patches.cypress/0035-non-upstream-fix-43012-driver-reload-failure-after-D.patch +patches.cypress/0116-Changing-info-messages-under-debug-BRCMF_INFO_VAL.patch +patches.cypress/0082-brcmfmac-add-BT-shared-SDIO-support.patch +patches.cypress/0108-brcm80211-add-FT-11r-OKC-roaming-offload-support.patch +patches.cypress/0045-non-upstream-ignore-FW-BADARG-error-when-removing-no.patch +patches.cypress/0053-brcmfmac-Fix-to-add-skb-free-for-TIM-update-info-whe.patch +patches.cypress/0071-non-upstream-Revert-brcm80211-select-WANT_DEV_COREDU.patch +patches.cypress/0175-brcmfmac-Set-corresponding-cqm-event-handlers-based-.patch +patches.cypress/0051-brcmfmac-add-a-timer-to-read-console-periodically-in.patch +patches.cypress/0170-Fix-invalid-RAM-address-warning-for-PCIE-platforms.patch +patches.cypress/0055-brcmfmac-dump-dongle-memory-when-attaching-failed.patch +patches.cypress/0151-brcmfmac-skip-6GHz-capab-registration-with-cfg80211-.patch +patches.cypress/0134-brcmfmac-update-BIP-setting-and-wsec_info-for-GMAC-a.patch +patches.cypress/0056-brcmfmac-update-address-mode-via-test-tool-for-AP-mo.patch +patches.cypress/0019-brcmfmac-Support-multiple-AP-interfaces-and-fix-STA-.patch +patches.cypress/0077-brcmfmac-Fix-authentication-latency-caused-by-OBSS-s.patch +patches.cypress/0042-brcmfmac-support-the-forwarding-packet.patch +patches.cypress/0166-brcmfmac-Fix-potential-buffer-overflow-in-brcmf_fweh.patch +patches.cypress/0039-non-upstream-disable-command-decode-in-sdio_aos-for-.patch +patches.cypress/0079-brcmfmac-fix-sdio-watchdog-timer-start-fail-issue.patch +patches.cypress/0131-Remove-WARN_ON-while-no-6g-bw_cap.patch +patches.cypress/0110-Disable-out-of-band-device-wake-based-DeepSleep-Stat.patch +patches.cypress/0065-brcmfmac-support-station-interface-creation-version-.patch +patches.cypress/0060-brcmfmac-Add-dump_survey-cfg80211-ops-for-HostApd-Au.patch +patches.cypress/0154-brcmfmac-ext_owe-supporting.patch +patches.cypress/0124-brcmfmac-add-support-for-CYW55560-SDIO-chipset.patch +patches.cypress/0005-non-upstream-remove-WOWL-configuration-in-disconnect.patch +patches.cypress/0004-non-upstream-support-wake-on-ping-packet.patch +patches.cypress/0014-non-upstream-fix-continuous-802.1x-tx-pending-timeou.patch +patches.cypress/0066-brcmfmac-To-fix-crash-when-platform-does-not-contain.patch +patches.cypress/0008-non-upstream-Changes-to-improve-USB-Tx-throughput.patch +patches.cypress/0010-non-upstream-configure-wowl-parameters-in-suspend-fu.patch +patches.cypress/0083-brcmfmac-add-CYW43439-SR-related-changes.patch +patches.cypress/0024-nl80211-add-authorized-flag-back-to-ROAM-event.patch +patches.cypress/0007-non-upstream-avoid-network-disconnection-during-susp.patch +patches.cypress/0086-brcmfmac-fix-P2P-device-discovery-failure.patch +patches.cypress/0044-brcmfmac-don-t-allow-arp-nd-offload-to-be-enabled-if.patch +patches.cypress/0173-non-upstream-internal-sup-uses-join-command-to-send-.patch +patches.cypress/0062-brcmfmac-correctly-remove-all-p2p-vif.patch +patches.cypress/0146-brcmfmac-set-HE-6GHz-capabilities-for-bring-up-SAP.patch +patches.cypress/0084-brcmfmac-add-support-for-CYW43439-with-blank-OTP.patch +patches.cypress/0169-brcmfmac-compile-warning-fix.patch +patches.cypress/0142-brcmfmac-Fixing-vulnerability.patch +patches.cypress/0061-revert-brcmfmac-set-state-of-hanger-slot-to-FREE-whe.patch +patches.cypress/0120-brcmfmac-support-11ax-and-6G-band.patch +patches.cypress/0075-brcmfmac-Fix-PCIE-suspend-resume-issue.patch +patches.cypress/0001-non-upstream-add-sg-parameters-dts-parsing.patch +patches.cypress/0167-non-upstream-vendor-cmd-addition-for-wl-oce-enable.patch +patches.cypress/0026-brcmfmac-set-authorized-flag-in-ROAM-event-for-PMK-c.patch +patches.cypress/0047-brcmfmac-move-firmware-path-to-cypress-folder.patch +patches.cypress/0092-brcmfmac-support-54590-54594-PCIe-device-id.patch +patches.cypress/0022-brcmfmac-increase-dcmd-maximum-buffer-size.patch +patches.cypress/0023-brcmfmac-set-net-carrier-on-via-test-tool-for-AP-mod.patch +patches.cypress/0143-brcmfmac-Implementing-set_bitrate_mask-cfg80211-ops-.patch +patches.cypress/0129-non-upstream-Handle-the-6G-case-in-the-bw_cap-chansp.patch +patches.cypress/0130-net-brcm80211-Fix-race-on-timer_add-in-wifi-driver.patch +patches.cypress/0153-brcmfmac-remove-workaround-cause-the-FW-can-support-.patch +patches.cypress/0099-brcmfmac-fixes-CYW4373-SDIO-CMD53-error.patch +patches.cypress/0144-brcm80211-add-FT-PSK-roaming-offload-support.patch +patches.cypress/0063-brcmfmac-fix-firmware-trap-while-dumping-obss-stats.patch +patches.cypress/0109-brcmfmac-support-extsae-with-psk-1x-offloading.patch +patches.cypress/0138-brcmfmac-update-firmware-loading-name-for-CY5557x.patch +patches.cypress/0030-brcmfmac-To-support-printing-USB-console-messages.patch +patches.cypress/0113-Revert-brcmfmac-Improve-the-delay-during-scan.patch +patches.cypress/0049-non-upstream-free-eventmask_msg-after-updating-event.patch +patches.cypress/0114-brcmfmac-Improve-the-delay-during-scan.patch +patches.cypress/0029-brcmfmac-add-support-for-Opportunistic-Key-Caching.patch +patches.cypress/0102-brcmfmac-add-Cypress-PCIe-vendor-ID.patch +patches.cypress/0036-brcmfmac-reset-PMU-backplane-all-cores-in-CYW4373-du.patch +patches.cypress/0046-brcmfmac-Support-DPP-feature.patch +patches.cypress/0052-brcmfmac-return-error-when-getting-invalid-max_flowr.patch +patches.cypress/0093-Revert-non-upstream-make-setting-SDIO-workqueue-WQ_H.patch +patches.cypress/0125-brcmfmac-Modified-Kconfig-help-format.patch +patches.cypress/0158-non-upstream-vendor-cmd-addition-for-wl-he-muedca_op.patch +patches.cypress/0152-brcmfmac-set-HE-rate-only-if-HE-MCS-set-and-valid.patch +patches.cypress/0089-brcmfmac-Fix-AP-interface-delete-issue.patch +patches.cypress/0069-brcmfmac-Fix-for-when-connect-request-is-not-success.patch +patches.cypress/0016-brcmfmac-add-CYW43570-PCIE-device.patch +patches.cypress/0043-brcmfmac-add-a-variable-for-packet-forwarding-condit.patch +patches.cypress/0177-brcmfmac-Add-NULL-checks-to-fix-multiple-NULL-pointe.patch +patches.cypress/0156-non-upstream-Add-IFX-TWT-Offload-support.patch +patches.cypress/0111-brcmfmac-Improve-the-delay-during-scan.patch +patches.cypress/0091-brcmfmac-Fix-structure-size-for-WPA3-external-SAE.patch +patches.cypress/0048-brcmfmac-add-support-for-sof-time-stammping-for-tx-p.patch +patches.cypress/0009-brcmfmac-introduce-module-parameter-to-configure-def.patch +patches.cypress/0160-non-upstream-vendor-cmd-addition-for-wl-ldpc_cap.patch +patches.cypress/0126-brcmfmac-Fix-incorrect-WARN_ON-causing-set_pmk-failu.patch +patches.cypress/0034-non-upstream-fix-43012-insmod-after-rmmod-in-DS1-fai.patch +patches.cypress/0031-non-upstream-Fix-no-P2P-IE-in-probe-requests-issue.patch +patches.cypress/0041-non-upstream-disable-command-decode-in-sdio_aos-for-.patch +patches.cypress/0097-brcmfmac-use-request_firmware_direct-for-loading-boa.patch +patches.cypress/0135-brcmfmac-send-roam-request-when-supplicant-triggers-.patch +patches.cypress/0127-brcmfmac-report-cqm-rssi-event-based-on-rssi-change-.patch +patches.cypress/0028-brcmfmac-set-authorized-flag-in-CONNECT-event-for-PM.patch +patches.cypress/0073-brcmfmac-Fix-for-skbuf-allocation-failure-in-memory-.patch +patches.cypress/0068-brcmfmac-fix-CERT-P2P-5.1.10-failure.patch +patches.cypress/0064-brcmfmac-add-creating-station-interface-support.patch +patches.cypress/0025-brcmfmac-set-authorized-flag-in-ROAM-event-for-offlo.patch +patches.cypress/0096-brcmfmac-Optimize-CYW4373-SDIO-current.patch +patches.cypress/0003-non-upstream-make-firmware-eap_restrict-a-module-par.patch +patches.cypress/0176-non-upstream-isolate-power_save-off-and-mpc-0.patch +patches.cypress/0098-brcmfmac-enable-pmk-catching-for-ext-sae-wpa3-ap.patch +patches.cypress/0090-brcmfmac-Revise-channel-info-for-WPA3-external-SAE.patch +patches.cypress/0155-brcmfmac-Avoid-adding-two-sets-of-HE-Capab-and-Oper-.patch +patches.cypress/0100-brcmfmac-add-PCIe-mailbox-support-for-core-revision-.patch +patches.cypress/0168-non-upstream-vendor-cmd-addition-for-wl-randmac.patch +patches.cypress/0140-brcmfmac-SAP-mode-parsing-sae_h2e-setting-from-beaco.patch +patches.cypress/0070-brcmfmac-Avoiding-Connection-delay.patch +patches.cypress/0150-brcmfmac-introduce-a-module-parameter-to-disable-the.patch +patches.cypress/0080-brcmfmac-Frameburst-vendor-command-addition.patch +patches.cypress/0021-brcmfmac-support-for-virtual-interface-creation-from.patch +patches.cypress/0139-brcmfmac-use-SR-core-id-to-decide-SR-capability-for-.patch +patches.cypress/0137-brcmfmac-trying-to-get-GCMP-cap-before-doing-set-it.patch +patches.cypress/0133-brcmfmac-fix-set_pmk-warning-message.patch +patches.cypress/0074-brcmfmac-Update-SSID-of-hidden-AP-while-informing-it.patch +patches.cypress/0076-brcmfmac-disable-mpc-when-power_save-is-disabled.patch +patches.cypress/0165-cfg80211-avoid-nontransmitted-BSS-list-corruption.patch +patches.cypress/0159-non-upstream-vendor-cmd-addition-for-wl-amsdu.patch +patches.cypress/0115-brcmfmac-add-FW-AP-selection-mod-param.patch +patches.cypress/0101-brcmfmac-add-support-for-TRX-firmware-download.patch +patches.cypress/0163-cfg80211-mac80211-reject-bad-MBSSID-elements.patch +patches.cypress/0018-brcmfmac-Support-89459-pcie.patch +patches.cypress/0104-brcmfmac-add-bootloader-console-buffer-support-for-P.patch +patches.cypress/0145-brcmfmac-enable-6G-split-scanning-feature.patch +patches.cypress/0123-brcmfmac-support-signal-monitor-feature-for-wpa_supp.patch +patches.cypress/0085-brcmfmac-support-43439-Cypress-Vendor-and-Device-ID.patch +patches.cypress/0012-brcmfmac-increase-default-max-WOWL-patterns-to-16.patch +patches.cypress/0078-brcmfmac-support-external-SAE-authentication-in-stat.patch +patches.cypress/0136-brcmfmac-send-BCNLOST_MSG-event-on-beacon-loss-for-s.patch +patches.cypress/0057-brcmfmac-load-54591-firmware-for-chip-ID-0x4355.patch +patches.cypress/0033-non-upstream-support-DS1-exit-firmware-re-download.patch +patches.cypress/0037-non-upstream-calling-skb_orphan-before-sending-skb-t.patch +patches.cypress/0088-brcmfmac-Add-CYW89459-HW-ID-and-modify-sdio-F2-block.patch +patches.cypress/0122-non-upstream-Fix-lspci-not-enumerating-wifi-device-a.patch