[PATCH v2] bcm63xx: override the PCI device ID if fallback SPROM is used
Daniel González Cabanelas
dgcbueu at gmail.com
Thu Jan 28 17:35:53 EST 2021
The PCI device ID detected by the wifi drivers on devices using a fallback
SPROM is wrong. Currently the chipnum is used for this parameter.
Most SSB based Broadcom wifi chips are 2.4 and 5GHz capable. But on
devices without a physical SPROM, the only one way to detect if the device
suports both bands or only the 5GHz band, is by reading the device ID from
the fallback SPROM.
In some devices, this may lead to a non working wifi on a 5GHz-only card,
or in the best case a working 2.4GHz-only in a dual band wifi card.
The offset for the deviceid in SSB SPROMs is 0x0008, whereas in BCMA is
0x0060. This is true for any SPROM version.
Override the PCI device ID with the one defined at the fallback SPROM, to
detect the correct wifi card model and allow using the 5GHz band if
supported.
The patch have been tested with the following wifi radios:
BCM43222: b43: both 2.4/5GHz working
brcm-wl: both 2.4/5GHz working
BCM43225: b43: 2.4GHz, working
brcmsmac: working
brcm-wl: it lacks support
BCM43217: b43: 2.4GHz, working
brcmsmac: it lacks support
brcm-wl: it lacks support
Signed-off-by: Daniel González Cabanelas <dgcbueu at gmail.com>
---
changes in v2:
- Now the fix is applied on all SPROMs.
- A different approach is used, the dev_id is overriden in the sprom
driver itself, and not delegated on the wifi drivers. This allows
the brcm-wl driver also to detect the right card model.
...-device-ID-if-fallback-SPROM-is-used.patch | 87 +++++++++++++++++++
1 file changed, 87 insertions(+)
create mode 100644 target/linux/bcm63xx/patches-5.4/804-override-PCI-device-ID-if-fallback-SPROM-is-used.patch
diff --git a/target/linux/bcm63xx/patches-5.4/804-override-PCI-device-ID-if-fallback-SPROM-is-used.patch b/target/linux/bcm63xx/patches-5.4/804-override-PCI-device-ID-if-fallback-SPROM-is-used.patch
new file mode 100644
index 0000000000..a0c1f3f4d0
--- /dev/null
+++ b/target/linux/bcm63xx/patches-5.4/804-override-PCI-device-ID-if-fallback-SPROM-is-used.patch
@@ -0,0 +1,87 @@
+--- a/arch/mips/bcm63xx/sprom.c
++++ b/arch/mips/bcm63xx/sprom.c
+@@ -45,6 +45,9 @@
+ .boardflags_hi = 0x0000,
+ };
+
++/* The deviceid in SSB is at offset 0x0008, whereas in BCMA is at 0x0060 */
++static bool deviceid_ssb_offs = false;
++
+ #if defined (CONFIG_SSB_PCIHOST)
+ static __initconst u16 bcm4306_sprom[] = {
+ 0x4001, 0x0000, 0x0453, 0x14e4, 0x4320, 0x8000, 0x0002, 0x0002,
+@@ -413,6 +416,8 @@
+ bus->host_pci->bus->number,
+ PCI_SLOT(bus->host_pci->devfn));
+ memcpy(out, &fallback_sprom.sprom, sizeof(struct ssb_sprom));
++ if (fallback_sprom.sprom.dev_id)
++ bus->host_pci->device = fallback_sprom.sprom.dev_id;
+ return 0;
+ } else {
+ printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
+@@ -432,6 +437,8 @@
+ bus->host_pci->bus->number,
+ PCI_SLOT(bus->host_pci->devfn));
+ memcpy(out, &fallback_sprom.sprom, sizeof(struct ssb_sprom));
++ if (fallback_sprom.sprom.dev_id)
++ bus->host_pci->device = fallback_sprom.sprom.dev_id;
+ return 0;
+ } else {
+ printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
+@@ -519,6 +526,8 @@
+ SSB_SPROM1_ETHPHY_ET1A_SHIFT);
+ SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
+ SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
++ if (deviceid_ssb_offs)
++ SPEX(dev_id, SSB_SPROM1_PID, 0xFFFF, 0);
+ SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
+ SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
+ if (out->revision == 1)
+@@ -614,6 +623,8 @@
+ SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
+ SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
+ SSB_SPROM4_ETHPHY_ET1A_SHIFT);
++ if (deviceid_ssb_offs)
++ SPEX(dev_id, SSB_SPROM1_PID, 0xFFFF, 0);
+ SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
+ SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
+ if (out->revision == 4) {
+@@ -683,6 +694,10 @@
+ BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
+ ARRAY_SIZE(out->core_pwr_info));
+
++ if (deviceid_ssb_offs)
++ SPEX(dev_id, SSB_SPROM1_PID, 0xFFFF, 0);
++ else
++ SPEX(dev_id, 0x0060, 0xFFFF, 0);
+ SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
+ SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
+ SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
+@@ -938,22 +953,27 @@
+ case SPROM_BCM4306:
+ memcpy(&template_sprom, &bcm4306_sprom, sizeof(bcm4306_sprom));
+ size = ARRAY_SIZE(bcm4306_sprom);
++ deviceid_ssb_offs = true;
+ break;
+ case SPROM_BCM4318:
+ memcpy(&template_sprom, &bcm4318_sprom, sizeof(bcm4318_sprom));
+ size = ARRAY_SIZE(bcm4318_sprom);
++ deviceid_ssb_offs = true;
+ break;
+ case SPROM_BCM4321:
+ memcpy(&template_sprom, &bcm4321_sprom, sizeof(bcm4321_sprom));
+ size = ARRAY_SIZE(bcm4321_sprom);
++ deviceid_ssb_offs = true;
+ break;
+ case SPROM_BCM4322:
+ memcpy(&template_sprom, &bcm4322_sprom, sizeof(bcm4322_sprom));
+ size = ARRAY_SIZE(bcm4322_sprom);
++ deviceid_ssb_offs = true;
+ break;
+ case SPROM_BCM43222:
+ memcpy(&template_sprom, &bcm43222_sprom, sizeof(bcm43222_sprom));
+ size = ARRAY_SIZE(bcm43222_sprom);
++ deviceid_ssb_offs = true;
+ break;
+ #endif
+ #if defined(CONFIG_BCMA_HOST_PCI)
--
2.30.0
More information about the openwrt-devel
mailing list