Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save FelixFrog/5d83fb96d97fbcc012a76ab109d170e9 to your computer and use it in GitHub Desktop.
Save FelixFrog/5d83fb96d97fbcc012a76ab109d170e9 to your computer and use it in GitHub Desktop.
bcm4377 mailbox patches
From 33f7204019f71a060048fde1230a23a71c9659d8 Mon Sep 17 00:00:00 2001
From: Francesco Ognibene <[email protected]>
Date: Thu, 10 Jun 2021 15:09:41 +0200
Subject: [PATCH 1/3] brcmfmac move brcmf_mp_device into its own header
---
.../broadcom/brcm80211/brcmfmac/common.h | 36 +++---------------
.../broadcom/brcm80211/brcmfmac/settings.h | 37 +++++++++++++++++++
2 files changed, 42 insertions(+), 31 deletions(-)
create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index 8b5f499..6cde5ee 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -8,15 +8,14 @@
#include <linux/platform_device.h>
#include <linux/platform_data/brcmfmac.h>
#include "fwil_types.h"
+#include "settings.h"
#define BRCMF_FW_ALTPATH_LEN 256
-/* Definitions for the module global and device specific settings are defined
- * here. Two structs are used for them. brcmf_mp_global_t and brcmf_mp_device.
- * The mp_global is instantiated once in a global struct and gets initialized
- * by the common_attach function which should be called before any other
- * (module) initiliazation takes place. The device specific settings is part
- * of the drvr struct and should be initialized on every brcmf_attach.
+/* Definition for the module global settings are defined here. One struct is
+ * used called brcmf_mp_global_t. The mp_global is instantiated once in a
+ * global struct and gets initialized by the common_attach function which
+ * should be called before any other (module) initiliazation takes place.
*/
/**
@@ -30,31 +29,6 @@ struct brcmf_mp_global_t {
extern struct brcmf_mp_global_t brcmf_mp_global;
-/**
- * struct brcmf_mp_device - Device module paramaters.
- *
- * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant).
- * @feature_disable: Feature_disable bitmask.
- * @fcmode: FWS flow control.
- * @roamoff: Firmware roaming off?
- * @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.
- */
-struct brcmf_mp_device {
- bool p2p_enable;
- unsigned int feature_disable;
- int fcmode;
- bool roamoff;
- bool iapp;
- bool ignore_probe_fail;
- struct brcmfmac_pd_cc *country_codes;
- const char *board_type;
- union {
- struct brcmfmac_sdio_pd sdio;
- } bus;
-};
-
void brcmf_c_set_joinpref_default(struct brcmf_if *ifp);
struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h
new file mode 100644
index 0000000..7bab0d3
--- /dev/null
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: ISC */
+/* Copyright (c) 2014 Broadcom Corporation */
+
+#ifndef BRCMFMAC_SETTINGS_H
+#define BRCMFMAC_SETTINGS_H
+
+/* Definition for the device specific settings are defined here. One struct
+ * is used called brcmf_mp_device. The device specific settings is part of
+ * the drvr struct and should be initialized on every brcmf_attach.
+ */
+
+/**
+ * struct brcmf_mp_device - Device module parameters.
+ *
+ * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant).
+ * @feature_disable: Feature_disable bitmask.
+ * @fcmode: FWS flow control.
+ * @roamoff: Firmware roaming off?
+ * @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.
+ */
+struct brcmf_mp_device {
+ bool p2p_enable;
+ unsigned int feature_disable;
+ int fcmode;
+ bool roamoff;
+ bool iapp;
+ bool ignore_probe_fail;
+ struct brcmfmac_pd_cc *country_codes;
+ const char *board_type;
+ union {
+ struct brcmfmac_sdio_pd sdio;
+ } bus;
+};
+
+#endif /* BRCMFMAC_SETTINGS_H */
--
2.31.1
From 13298bbd1abf9a4607ab4fc8ec86ceff779deed2 Mon Sep 17 00:00:00 2001
From: Francesco Ognibene <[email protected]>
Date: Thu, 10 Jun 2021 15:11:24 +0200
Subject: [PATCH 2/3] brcmfmac Add ability to manually specify FW rambase
---
.../broadcom/brcm80211/brcmfmac/chip.c | 19 ++++++++++++-------
.../broadcom/brcm80211/brcmfmac/chip.h | 7 +++++--
.../broadcom/brcm80211/brcmfmac/common.c | 5 +++++
.../broadcom/brcm80211/brcmfmac/common.h | 1 -
.../broadcom/brcm80211/brcmfmac/pcie.c | 4 ++--
.../broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
.../broadcom/brcm80211/brcmfmac/settings.h | 4 ++++
7 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 45037de..96dceaa 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -734,7 +734,7 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
return 0;
}
-int brcmf_chip_get_raminfo(struct brcmf_chip *pub)
+int brcmf_chip_get_raminfo(struct brcmf_chip *pub, struct brcmf_mp_device *settings)
{
struct brcmf_chip_priv *ci = container_of(pub, struct brcmf_chip_priv,
pub);
@@ -745,7 +745,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);
- ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
+ ci->pub.rambase = (settings &&
+ settings->rambase_addr > 0) ? settings->rambase_addr
+ : brcmf_chip_tcm_rambase(ci);
if (!ci->pub.rambase) {
brcmf_err("RAM base not provided with ARM CR4 core\n");
return -EINVAL;
@@ -756,7 +758,9 @@ int brcmf_chip_get_raminfo(struct brcmf_chip *pub)
mem_core = container_of(mem, struct brcmf_core_priv,
pub);
ci->pub.ramsize = brcmf_chip_sysmem_ramsize(mem_core);
- ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
+ ci->pub.rambase = (settings &&
+ settings->rambase_addr > 0) ? settings->rambase_addr
+ : brcmf_chip_tcm_rambase(ci);
if (!ci->pub.rambase) {
brcmf_err("RAM base not provided with ARM CA7 core\n");
return -EINVAL;
@@ -942,7 +946,7 @@ int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)
return 0;
}
-static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
+static int brcmf_chip_recognition(struct brcmf_chip_priv *ci, struct brcmf_mp_device *settings)
{
struct brcmf_core *core;
u32 regdata;
@@ -1015,7 +1019,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
brcmf_chip_set_passive(&ci->pub);
}
- return brcmf_chip_get_raminfo(&ci->pub);
+ return brcmf_chip_get_raminfo(&ci->pub, settings);
}
static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
@@ -1089,7 +1093,8 @@ static int brcmf_chip_setup(struct brcmf_chip_priv *chip)
}
struct brcmf_chip *brcmf_chip_attach(void *ctx,
- const struct brcmf_buscore_ops *ops)
+ const struct brcmf_buscore_ops *ops,
+ struct brcmf_mp_device *settings)
{
struct brcmf_chip_priv *chip;
int err = 0;
@@ -1118,7 +1123,7 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx,
if (err < 0)
goto fail;
- err = brcmf_chip_recognition(chip);
+ err = brcmf_chip_recognition(chip, settings);
if (err < 0)
goto fail;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
index 8fa3865..7da0ef3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
@@ -7,6 +7,8 @@
#include <linux/types.h>
+#include "settings.h"
+
#define CORE_CC_REG(base, field) \
(base + offsetof(struct chipcregs, field))
@@ -69,9 +71,10 @@ struct brcmf_buscore_ops {
void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
};
-int brcmf_chip_get_raminfo(struct brcmf_chip *pub);
+int brcmf_chip_get_raminfo(struct brcmf_chip *pub, struct brcmf_mp_device *settings);
struct brcmf_chip *brcmf_chip_attach(void *ctx,
- const struct brcmf_buscore_ops *ops);
+ const struct brcmf_buscore_ops *ops,
+ struct brcmf_mp_device *settings);
void brcmf_chip_detach(struct brcmf_chip *chip);
struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index e3758bd..46a5252 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 uint brcmf_rambase_addr;
+module_param_named(rambase_addr, brcmf_rambase_addr, uint, 0);
+MODULE_PARM_DESC(rambase_addr, "Manually specify FW shared rambase address");
+
#ifdef DEBUG
/* always succeed brcmf_bus_started() */
static int brcmf_ignore_probe_fail;
@@ -416,6 +420,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
#ifdef DEBUG
settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
#endif
+ settings->rambase_addr = brcmf_rambase_addr;
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 6cde5ee..0da7eee 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -6,7 +6,6 @@
#define BRCMFMAC_COMMON_H
#include <linux/platform_device.h>
-#include <linux/platform_data/brcmfmac.h>
#include "fwil_types.h"
#include "settings.h"
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 143a705..665b549 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -1774,7 +1774,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len;
kfree(fwreq);
- ret = brcmf_chip_get_raminfo(devinfo->ci);
+ ret = brcmf_chip_get_raminfo(devinfo->ci, devinfo->settings);
if (ret) {
brcmf_err(bus, "Failed to get RAM info\n");
goto fail;
@@ -1886,7 +1886,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
devinfo->pdev = pdev;
pcie_bus_dev = NULL;
- devinfo->ci = brcmf_chip_attach(devinfo, &brcmf_pcie_buscore_ops);
+ devinfo->ci = brcmf_chip_attach(devinfo, &brcmf_pcie_buscore_ops, devinfo->settings);
if (IS_ERR(devinfo->ci)) {
ret = PTR_ERR(devinfo->ci);
devinfo->ci = NULL;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 16ed325..753c7a5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3967,7 +3967,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
goto fail;
}
- bus->ci = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops);
+ bus->ci = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops, sdiodev->settings);
if (IS_ERR(bus->ci)) {
brcmf_err("brcmf_chip_attach failed!\n");
bus->ci = NULL;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h
index 7bab0d3..160e32f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/settings.h
@@ -4,6 +4,8 @@
#ifndef BRCMFMAC_SETTINGS_H
#define BRCMFMAC_SETTINGS_H
+#include <linux/platform_data/brcmfmac.h>
+
/* Definition for the device specific settings are defined here. One struct
* is used called brcmf_mp_device. The device specific settings is part of
* the drvr struct and should be initialized on every brcmf_attach.
@@ -19,6 +21,7 @@
* @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.
+ * @rambase_addr: Manually specified FW shared rambase address.
*/
struct brcmf_mp_device {
bool p2p_enable;
@@ -32,6 +35,7 @@ struct brcmf_mp_device {
union {
struct brcmfmac_sdio_pd sdio;
} bus;
+ u32 rambase_addr;
};
#endif /* BRCMFMAC_SETTINGS_H */
--
2.31.1
From bda2a6a5dfb2a9eb2e38c7e3710ad50cf2ed70c4 Mon Sep 17 00:00:00 2001
From: Francesco Ognibene <[email protected]>
Date: Thu, 10 Jun 2021 15:22:03 +0200
Subject: [PATCH 3/3] brcmfmac Added support for the brcm4377
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 7 +-
.../broadcom/brcm80211/brcmfmac/chip.c | 4 +
.../broadcom/brcm80211/brcmfmac/p2p.c | 14 ++-
.../broadcom/brcm80211/brcmfmac/pcie.c | 118 +++++++++++++++---
.../broadcom/brcm80211/include/brcm_hw_ids.h | 2 +
5 files changed, 125 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index f4405d7..4158b38 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5136,8 +5136,13 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
ie_offset = DOT11_MGMT_HDR_LEN +
DOT11_BCN_PRB_FIXED_LEN;
ie_len = len - ie_offset;
- if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
+ if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
+ if (vif == NULL) {
+ bphy_err(drvr, "No p2p device available for probe response\n");
+ return -ENODEV;
+ }
+ }
err = brcmf_vif_set_mgmt_ie(vif,
BRCMF_VNDR_IE_PRBRSP_FLAG,
&buf[ie_offset],
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 96dceaa..b1dbac1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -727,6 +727,8 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
case BRCM_CC_4364_CHIP_ID:
case CY_CC_4373_CHIP_ID:
return 0x160000;
+ case BRCM_CC_4377_CHIP_ID:
+ return 0x170000;
default:
brcmf_err("unknown chip: %s\n", ci->pub.name);
break;
@@ -1431,5 +1433,7 @@ 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 BRCM_CC_4377_CHIP_ID:
+ return false;
}
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 34cd8a7..d20e5b2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -565,7 +565,8 @@ static s32 brcmf_p2p_deinit_discovery(struct brcmf_p2p_info *p2p)
/* Set the discovery state to SCAN */
vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
- (void)brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
+ if (vif != NULL)
+ (void)brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
/* Disable P2P discovery in the firmware */
vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
@@ -1351,6 +1352,8 @@ brcmf_p2p_gon_req_collision(struct brcmf_p2p_info *p2p, u8 *mac)
* if not (sa addr > da addr),
* this device will process gon request and drop gon req of peer.
*/
+ if(p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == NULL)
+ return false;
ifp = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->ifp;
if (memcmp(mac, ifp->mac_addr, ETH_ALEN) < 0) {
brcmf_dbg(INFO, "Block transmit gon req !!!\n");
@@ -1559,6 +1562,10 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
else
vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
+ if (vif == NULL) {
+ bphy_err(drvr, " no P2P interface available\n");
+ goto exit;
+ }
err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params,
sizeof(*af_params));
if (err) {
@@ -1734,8 +1741,11 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
uint delta_ms;
unsigned long dwell_jiffies = 0;
bool dwell_overflow = false;
-
u32 requested_dwell = le32_to_cpu(af_params->dwell_time);
+
+ if(p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == NULL)
+ goto exit;
+
action_frame = &af_params->action_frame;
action_frame_len = le16_to_cpu(action_frame->len);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 665b549..fa86358 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -58,6 +58,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(4377, "brcmfmac4377-pcie");
static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602),
@@ -79,6 +80,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(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377),
};
#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
@@ -110,6 +112,12 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0 0x140
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1 0x144
+#define BRCMF_PCIE_64_PCIE2REG_INTMASK 0xC14
+#define BRCMF_PCIE_64_PCIE2REG_MAILBOXINT 0xC30
+#define BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK 0xC34
+#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0 0xA20
+#define BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1 0xA24
+
#define BRCMF_PCIE2_INTA 0x01
#define BRCMF_PCIE2_INTB 0x02
@@ -138,6 +146,40 @@ static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
BRCMF_PCIE_MB_INT_D2H3_DB0 | \
BRCMF_PCIE_MB_INT_D2H3_DB1)
+#define BRCMF_PCIE_64_MB_INT_D2H0_DB0 1
+#define BRCMF_PCIE_64_MB_INT_D2H0_DB1 2
+#define BRCMF_PCIE_64_MB_INT_D2H1_DB0 4
+#define BRCMF_PCIE_64_MB_INT_D2H1_DB1 8
+#define BRCMF_PCIE_64_MB_INT_D2H2_DB0 0x10
+#define BRCMF_PCIE_64_MB_INT_D2H2_DB1 0x20
+#define BRCMF_PCIE_64_MB_INT_D2H3_DB0 0x40
+#define BRCMF_PCIE_64_MB_INT_D2H3_DB1 0x80
+#define BRCMF_PCIE_64_MB_INT_D2H4_DB0 0x100
+#define BRCMF_PCIE_64_MB_INT_D2H4_DB1 0x200
+#define BRCMF_PCIE_64_MB_INT_D2H5_DB0 0x400
+#define BRCMF_PCIE_64_MB_INT_D2H5_DB1 0x800
+#define BRCMF_PCIE_64_MB_INT_D2H6_DB0 0x1000
+#define BRCMF_PCIE_64_MB_INT_D2H6_DB1 0x2000
+#define BRCMF_PCIE_64_MB_INT_D2H7_DB0 0x4000
+#define BRCMF_PCIE_64_MB_INT_D2H7_DB1 0x8000
+
+#define BRCMF_PCIE_64_MB_INT_D2H_DB (BRCMF_PCIE_64_MB_INT_D2H0_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H0_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H1_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H1_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H2_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H2_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H3_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H3_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H4_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H4_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H5_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H5_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H6_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H6_DB1 | \
+ BRCMF_PCIE_64_MB_INT_D2H7_DB0 | \
+ BRCMF_PCIE_64_MB_INT_D2H7_DB1)
+
#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
@@ -529,6 +571,37 @@ brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
}
+static u32
+brcmf_pcie_reg_map(struct brcmf_pciedev_info *devinfo, u32 reg)
+{
+ switch(reg) {
+ case BRCMF_PCIE_PCIE2REG_INTMASK:
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_INTMASK;
+ return reg;
+ case BRCMF_PCIE_PCIE2REG_MAILBOXINT:
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_MAILBOXINT;
+ return reg;
+ case BRCMF_PCIE_PCIE2REG_MAILBOXMASK:
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK;
+ return reg;
+ case BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0:
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_0;
+ return reg;
+ case BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1:
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ return BRCMF_PCIE_64_PCIE2REG_H2D_MAILBOX_1;
+ return reg;
+ default:
+ return reg;
+ }
+}
+
+
+
#define WRITECC32(devinfo, reg, value) brcmf_pcie_write_reg32(devinfo, \
CHIPCREGOFFS(reg), value)
@@ -544,6 +617,7 @@ brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid)
core = brcmf_chip_get_core(devinfo->ci, coreid);
if (core) {
bar0_win = core->base;
+
pci_write_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW, bar0_win);
if (pci_read_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW,
&bar0_win) == 0) {
@@ -810,30 +884,34 @@ 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_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK), 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_MB_INT_FN0_0 |
- BRCMF_PCIE_MB_INT_FN0_1);
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_64_PCIE2REG_MAILBOXMASK,
+ BRCMF_PCIE_64_MB_INT_D2H_DB);
+ else
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
+ BRCMF_PCIE_MB_INT_D2H_DB |
+ BRCMF_PCIE_MB_INT_FN0_0 |
+ BRCMF_PCIE_MB_INT_FN0_1);
}
static void brcmf_pcie_hostready(struct brcmf_pciedev_info *devinfo)
{
if (devinfo->shared.flags & BRCMF_PCIE_SHARED_HOSTRDY_DB1)
brcmf_pcie_write_reg32(devinfo,
- BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1, 1);
+ brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1), 1);
}
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_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT))) {
brcmf_pcie_intr_disable(devinfo);
brcmf_dbg(PCIE, "Enter\n");
return IRQ_WAKE_THREAD;
@@ -845,18 +923,23 @@ static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg)
static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
{
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
- u32 status;
+ u32 status, mask;
+
+ if(devinfo->ci->chip == BRCM_CC_4377_CHIP_ID)
+ mask = BRCMF_PCIE_64_MB_INT_D2H_DB;
+ else
+ mask = BRCMF_PCIE_MB_INT_D2H_DB;
devinfo->in_irq = true;
- status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
+ status = brcmf_pcie_read_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT));
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_reg_map(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);
- if (status & BRCMF_PCIE_MB_INT_D2H_DB) {
+ if (status & mask) {
if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
brcmf_proto_msgbuf_rx_trigger(
&devinfo->pdev->dev);
@@ -915,8 +998,8 @@ 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_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT));
+ brcmf_pcie_write_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT), status);
devinfo->irq_allocated = false;
}
@@ -968,7 +1051,7 @@ static int brcmf_pcie_ring_mb_ring_bell(void *ctx)
brcmf_dbg(PCIE, "RING !\n");
/* Any arbitrary value will do, lets use 1 */
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0, 1);
+ brcmf_pcie_write_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0), 1);
return 0;
}
@@ -1720,9 +1803,9 @@ 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_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT));
if (val != 0xffffffff)
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
+ brcmf_pcie_write_reg32(devinfo, brcmf_pcie_reg_map(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT),
val);
return 0;
@@ -2054,7 +2137,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
brcmf_dbg(PCIE, "Enter, dev=%p, bus=%p\n", dev, bus);
/* Check if device is still up and running, if so we are ready */
- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
+ if (brcmf_pcie_read_reg32(devinfo, brcmf_pcie_reg_map(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;
@@ -2120,6 +2203,7 @@ 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(BRCM_PCIE_4377_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 00309b2..ed6231d 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,7 @@
#define BRCM_CC_43664_CHIP_ID 43664
#define BRCM_CC_43666_CHIP_ID 43666
#define BRCM_CC_4371_CHIP_ID 0x4371
+#define BRCM_CC_4377_CHIP_ID 0x4377
#define CY_CC_4373_CHIP_ID 0x4373
#define CY_CC_43012_CHIP_ID 43012
@@ -84,6 +85,7 @@
#define BRCM_PCIE_4366_2G_DEVICE_ID 0x43c4
#define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5
#define BRCM_PCIE_4371_DEVICE_ID 0x440d
+#define BRCM_PCIE_4377_DEVICE_ID 0x4488
/* brcmsmac IDs */
--
2.31.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment