Skip to contentSkip to conversation

ssb/bcma/BCM47XX: sprom fixes and extensions

PATCH New Hauke Mehrtens 2 participants 13 messages Feb 27, 2012 – Mar 6, 2012

Subsystems (5)
lore
Share & tools
lore

Hauke Mehrtens

author maintainer
#0 lore raw

v2 cover ssb/bcma/BCM47XX: sprom fixes and extensions

This patch series fixes some errors in the sprom structures and extends it to contain members for all sprom values for sprom version 1 to 9. This was done by looking into the open source part of the Broadcom SDK. This also adds a fallback sprom registration method to bcma. It also contains some small fixes for the bcma47xx arch code and a rewrite of the code to provide the sprom from flash. It now also provides sprom from flash for devices using bcma to control the system bus.

This patch series is based on wireles-testing. I think it is the best way to merge this through John's wireless tree as the changes in the sprom struct should be used in further patches extending the pci sprom parsing and the usage of struct sprom by the brcmsmac driver.

@Ralf could you please give me your Ack on the patches touching arch/mips/ or say to me what you do not like at these patches or the others.

v2:
* fix drivers/ssb/pci.c:334:5: warning: unused variable 'gain'
* rename ccode to alpha2
* typos
* use switch in bcm47xx_get_sprom_bcma()

Hauke Mehrtens (11):
ssb: sprom fix some sizes / signedness
ssb: remove 5GHz antenna gain from sprom
ssb: fix per path sprom vars
ssb: add alpha2
ssb: add some missing sprom attributes
bcma: export bcma_find_core
bcma: add support for sprom not found on the device
MIPS: BCM47XX: return number of written bytes in nvram_getenv
MIPS: BCM47XX: fix signature of nvram_parse_macaddr
MIPS: BCM47XX: move and extend sprom parsing
MIPS: BCM47XX: provide sprom to bcma bus

 arch/mips/bcm47xx/Makefile                   |    2 +-
 arch/mips/bcm47xx/nvram.c                    |    3 +-
 arch/mips/bcm47xx/setup.c                    |  188 ++-------
 arch/mips/bcm47xx/sprom.c                    |  620 ++++++++++++++++++++++++++
 arch/mips/include/asm/mach-bcm47xx/bcm47xx.h |    3 +
 arch/mips/include/asm/mach-bcm47xx/nvram.h   |    2 +-
 drivers/bcma/main.c                          |    3 +-
 drivers/bcma/sprom.c                         |   77 +++-
 drivers/net/wireless/b43legacy/phy.c         |    2 +-
 drivers/ssb/pci.c                            |   41 +--
 drivers/ssb/pcmcia.c                         |   12 +-
 drivers/ssb/sdio.c                           |   12 +-
 include/linux/bcma/bcma.h                    |    7 +
 include/linux/ssb/ssb.h                      |  102 ++++-
 14 files changed, 848 insertions(+), 226 deletions(-)
 create mode 100644 arch/mips/bcm47xx/sprom.c
Signature · 1 line
1.7.5.4
author maintainer
#1 lore raw

PATCH v2 1/11 ssb: sprom fix some sizes / signedness

Some parts of the sprom struct are bigger than needed. The leddc and maxpwr values are just 8 bit long and not 16. rxpo2g and rxpo5g are signed

I got these information for the open source part of the Broadcom SDK covering sprom version 1 to 9. rxpo2g contained a negative number on my bcm5354 based device, this cased an error and Broadcom SDK says this is signed.

---
 include/linux/ssb/ssb.h |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)
include/linux/ssb/ssb.h +8 -8
index bbc2612..f169621 100644
@@ -33,8 +33,8 @@ struct ssb_sprom {
 	u8 et1mdcport;		/* MDIO for enet1 */
 	u16 board_rev;		/* Board revision number from SPROM. */
 	u8 country_code;	/* Country Code */
-	u16 leddc_on_time;	/* LED Powersave Duty Cycle On Count */
-	u16 leddc_off_time;	/* LED Powersave Duty Cycle Off Count */
+	u8 leddc_on_time;	/* LED Powersave Duty Cycle On Count */
+	u8 leddc_off_time;	/* LED Powersave Duty Cycle Off Count */
 	u8 ant_available_a;	/* 2GHz antenna available bits (up to 4) */
 	u8 ant_available_bg;	/* 5GHz antenna available bits (up to 4) */
 	u16 pa0b0;
@@ -53,10 +53,10 @@ struct ssb_sprom {
 	u8 gpio1;		/* GPIO pin 1 */
 	u8 gpio2;		/* GPIO pin 2 */
 	u8 gpio3;		/* GPIO pin 3 */
-	u16 maxpwr_bg;		/* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
-	u16 maxpwr_al;		/* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
-	u16 maxpwr_a;		/* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
-	u16 maxpwr_ah;		/* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
+	u8 maxpwr_bg;		/* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
+	u8 maxpwr_al;		/* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
+	u8 maxpwr_a;		/* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
+	u8 maxpwr_ah;		/* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
 	u8 itssi_a;		/* Idle TSSI Target for A-PHY */
 	u8 itssi_bg;		/* Idle TSSI Target for B/G-PHY */
 	u8 tri2g;		/* 2.4GHz TX isolation */
@@ -67,8 +67,8 @@ struct ssb_sprom {
 	u8 txpid5gl[4];		/* 4.9 - 5.1GHz TX power index */
 	u8 txpid5g[4];		/* 5.1 - 5.5GHz TX power index */
 	u8 txpid5gh[4];		/* 5.5 - ...GHz TX power index */
-	u8 rxpo2g;		/* 2GHz RX power offset */
-	u8 rxpo5g;		/* 5GHz RX power offset */
+	s8 rxpo2g;		/* 2GHz RX power offset */
+	s8 rxpo5g;		/* 5GHz RX power offset */
 	u8 rssisav2g;		/* 2GHz RSSI params */
 	u8 rssismc2g;
 	u8 rssismf2g;
Signature · 1 line
1.7.5.4
author maintainer
#2 lore raw

PATCH v2 2/11 ssb: remove 5GHz antenna gain from sprom

In reply to Hauke Mehrtens

There is no 2.4 GHz or 5GHz antenna gain stored in sprom. The sprom just stores the gain values for antenna 1 and 2 or 1 to 4 for more recent sprom versions. On old devices antenna 2 was used for 5 GHz wifi.

---
 drivers/net/wireless/b43legacy/phy.c |    2 +-
 drivers/ssb/pci.c                    |   41 +++++++++++----------------------
 drivers/ssb/pcmcia.c                 |   12 +++------
 drivers/ssb/sdio.c                   |   12 +++------
 include/linux/ssb/ssb.h              |    7 +-----
 5 files changed, 24 insertions(+), 50 deletions(-)
drivers/net/wireless/b43legacy/phy.c +1 -1
index 96faaef..9503341 100644
@@ -1860,7 +1860,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
 	 * which accounts for the factor of 4 */
 #define REG_MAX_PWR 20
 	max_pwr = min(REG_MAX_PWR * 4
-		      - dev->dev->bus->sprom.antenna_gain.ghz24.a0
+		      - dev->dev->bus->sprom.antenna_gain.a0
 		      - 0x6, max_pwr);
 
 	/* find the desired power in Q5.2 - power_level is in dBm
drivers/ssb/pci.c +14 -27

73 lines not on this page · raw message

drivers/ssb/pcmcia.c +4 -8
index c821c6b..fbafed5 100644
@@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
 	case SSB_PCMCIA_CIS_ANTGAIN:
 		GOTO_ERROR_ON(tuple->TupleDataLen != 2,
 			"antg tpl size");
-		sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
-		sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
-		sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
-		sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
-		sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
-		sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
-		sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
-		sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
+		sprom->antenna_gain.a0 = tuple->TupleData[1];
+		sprom->antenna_gain.a1 = tuple->TupleData[1];
+		sprom->antenna_gain.a2 = tuple->TupleData[1];
+		sprom->antenna_gain.a3 = tuple->TupleData[1];
 		break;
 	case SSB_PCMCIA_CIS_BFLAGS:
 		GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
drivers/ssb/sdio.c +4 -8
index 63fd709..b2d36f7 100644
@@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_bus *bus,
 			case SSB_SDIO_CIS_ANTGAIN:
 				GOTO_ERROR_ON(tuple->size != 2,
 					      "antg tpl size");
-				sprom->antenna_gain.ghz24.a0 = tuple->data[1];
-				sprom->antenna_gain.ghz24.a1 = tuple->data[1];
-				sprom->antenna_gain.ghz24.a2 = tuple->data[1];
-				sprom->antenna_gain.ghz24.a3 = tuple->data[1];
-				sprom->antenna_gain.ghz5.a0 = tuple->data[1];
-				sprom->antenna_gain.ghz5.a1 = tuple->data[1];
-				sprom->antenna_gain.ghz5.a2 = tuple->data[1];
-				sprom->antenna_gain.ghz5.a3 = tuple->data[1];
+				sprom->antenna_gain.a0 = tuple->data[1];
+				sprom->antenna_gain.a1 = tuple->data[1];
+				sprom->antenna_gain.a2 = tuple->data[1];
+				sprom->antenna_gain.a3 = tuple->data[1];
 				break;
 			case SSB_SDIO_CIS_BFLAGS:
 				GOTO_ERROR_ON((tuple->size != 3) &&
include/linux/ssb/ssb.h +1 -6
index f169621..1de5675 100644
@@ -94,12 +94,7 @@ struct ssb_sprom {
 	 * on each band. Values in dBm/4 (Q5.2). Negative gain means the
 	 * loss in the connectors is bigger than the gain. */
 	struct {
-		struct {
-			s8 a0, a1, a2, a3;
-		} ghz24;	/* 2.4GHz band */
-		struct {
-			s8 a0, a1, a2, a3;
-		} ghz5;		/* 5GHz band */
+		s8 a0, a1, a2, a3;
 	} antenna_gain;
 
 	struct {
Signature · 1 line
1.7.5.4
author maintainer
#3 lore raw

PATCH v2 3/11 ssb: fix per path sprom vars

In reply to Hauke Mehrtens

On sprom version 4 and 5 there are 4 values for pa_2g, pa_5gl, pa_5g and pa_5gh, for sprom version 8 and 9 there are only 3. Make the per path sprom store also work for older sprom versions.

---
 include/linux/ssb/ssb.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
include/linux/ssb/ssb.h +1 -1
index 1de5675..4928419 100644
@@ -19,7 +19,7 @@ struct ssb_driver;
 struct ssb_sprom_core_pwr_info {
 	u8 itssi_2g, itssi_5g;
 	u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh;
-	u16 pa_2g[3], pa_5gl[3], pa_5g[3], pa_5gh[3];
+	u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4];
 };
 
 struct ssb_sprom {
Signature · 1 line
1.7.5.4
author maintainer
#4 lore raw

PATCH v2 4/11 ssb: add alpha2

In reply to Hauke Mehrtens

This member contains the country code encoded with two chars

---
 include/linux/ssb/ssb.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
include/linux/ssb/ssb.h +1 -0
index 4928419..d658de4 100644
@@ -33,6 +33,7 @@ struct ssb_sprom {
 	u8 et1mdcport;		/* MDIO for enet1 */
 	u16 board_rev;		/* Board revision number from SPROM. */
 	u8 country_code;	/* Country Code */
+	char alpha2[2];		/* Country Code as two chars like EU or US */
 	u8 leddc_on_time;	/* LED Powersave Duty Cycle On Count */
 	u8 leddc_off_time;	/* LED Powersave Duty Cycle Off Count */
 	u8 ant_available_a;	/* 2GHz antenna available bits (up to 4) */
Signature · 1 line
1.7.5.4
author maintainer
#5 lore raw

PATCH v2 5/11 ssb: add some missing sprom attributes

In reply to Hauke Mehrtens

This patch extends the sprom struct to contain all sprom attributes found in sprom version 1 to 9. This was done accordingly to the open source part of the Broadcom SDK.

---
 include/linux/ssb/ssb.h |   76 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 75 insertions(+), 1 deletions(-)
include/linux/ssb/ssb.h +75 -1
index d658de4..d276831 100644
@@ -32,6 +32,8 @@ struct ssb_sprom {
 	u8 et0mdcport;		/* MDIO for enet0 */
 	u8 et1mdcport;		/* MDIO for enet1 */
 	u16 board_rev;		/* Board revision number from SPROM. */
+	u16 board_num;		/* Board number from SPROM. */
+	u16 board_type;		/* Board type from SPROM. */
 	u8 country_code;	/* Country Code */
 	char alpha2[2];		/* Country Code as two chars like EU or US */
 	u8 leddc_on_time;	/* LED Powersave Duty Cycle On Count */
@@ -107,7 +109,79 @@ struct ssb_sprom {
 		} ghz5;
 	} fem;
 
-	/* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
+	u16 mcs2gpo[8];
+	u16 mcs5gpo[8];
+	u16 mcs5glpo[8];
+	u16 mcs5ghpo[8];
+	u8 opo;
+
+	u8 rxgainerr2ga[3];
+	u8 rxgainerr5gla[3];
+	u8 rxgainerr5gma[3];
+	u8 rxgainerr5gha[3];
+	u8 rxgainerr5gua[3];
+
+	u8 noiselvl2ga[3];
+	u8 noiselvl5gla[3];
+	u8 noiselvl5gma[3];
+	u8 noiselvl5gha[3];
+	u8 noiselvl5gua[3];
+
+	u8 regrev;
+	u8 txchain;
+	u8 rxchain;
+	u8 antswitch;
+	u16 cddpo;
+	u16 stbcpo;
+	u16 bw40po;
+	u16 bwduppo;
+
+	u8 tempthresh;
+	u8 tempoffset;
+	u16 rawtempsense;
+	u8 measpower;
+	u8 tempsense_slope;
+	u8 tempcorrx;
+	u8 tempsense_option;
+	u8 freqoffset_corr;
+	u8 iqcal_swp_dis;
+	u8 hw_iqcal_en;
+	u8 elna2g;
+	u8 elna5g;
+	u8 phycal_tempdelta;
+	u8 temps_period;
+	u8 temps_hysteresis;
+	u8 measpower1;
+	u8 measpower2;
+	u8 pcieingress_war;
+
+	/* power per rate from sromrev 9 */
+	u16 cckbw202gpo;
+	u16 cckbw20ul2gpo;
+	u32 legofdmbw202gpo;
+	u32 legofdmbw20ul2gpo;
+	u32 legofdmbw205glpo;
+	u32 legofdmbw20ul5glpo;
+	u32 legofdmbw205gmpo;
+	u32 legofdmbw20ul5gmpo;
+	u32 legofdmbw205ghpo;
+	u32 legofdmbw20ul5ghpo;
+	u32 mcsbw202gpo;
+	u32 mcsbw20ul2gpo;
+	u32 mcsbw402gpo;
+	u32 mcsbw205glpo;
+	u32 mcsbw20ul5glpo;
+	u32 mcsbw405glpo;
+	u32 mcsbw205gmpo;
+	u32 mcsbw20ul5gmpo;
+	u32 mcsbw405gmpo;
+	u32 mcsbw205ghpo;
+	u32 mcsbw20ul5ghpo;
+	u32 mcsbw405ghpo;
+	u16 mcs32po;
+	u16 legofdm40duppo;
+	u8 sar2g;
+	u8 sar5g;
 };
 
 /* Information about the PCB the circuitry is soldered on. */
Signature · 1 line
1.7.5.4
author maintainer
#6 lore raw

PATCH v2 6/11 bcma: export bcma_find_core

In reply to Hauke Mehrtens

This function is needed by the bcm47xx arch code to get the number of the ieee80211 core.

---
 drivers/bcma/main.c       |    3 ++-
 include/linux/bcma/bcma.h |    1 +
 2 files changed, 3 insertions(+), 1 deletions(-)
drivers/bcma/main.c +2 -1
index b8379b9..7e138ec 100644
@@ -61,7 +61,7 @@ static struct bus_type bcma_bus_type = {
 	.dev_attrs	= bcma_device_attrs,
 };
 
-static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
+struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
 {
 	struct bcma_device *core;
 
@@ -71,6 +71,7 @@ static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(bcma_find_core);
 
 static void bcma_release_core_dev(struct device *dev)
 {
include/linux/bcma/bcma.h +1 -0
index b9f65fb..46bbd08 100644
@@ -284,6 +284,7 @@ static inline void bcma_maskset16(struct bcma_device *cc,
 	bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
 }
 
+extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
 extern bool bcma_core_is_enabled(struct bcma_device *core);
 extern void bcma_core_disable(struct bcma_device *core, u32 flags);
 extern int bcma_core_enable(struct bcma_device *core, u32 flags);
Signature · 1 line
1.7.5.4
author maintainer
#7 lore raw

PATCH v2 7/11 bcma: add support for sprom not found on the device

In reply to Hauke Mehrtens

On SoCs the sprom is stored in the nvram in a special partition on the flash chip. The nvram contains the sprom for the main bus, but sometimes also for a pci devices using bcma. This patch makes it possible for the arch code to register a function to fetch the needed sprom from the nvram and provide it to the bcma code.

---
 drivers/bcma/sprom.c      |   77 ++++++++++++++++++++++++++++++++++++++++-----
 include/linux/bcma/bcma.h |    6 +++
 2 files changed, 75 insertions(+), 8 deletions(-)
drivers/bcma/sprom.c +69 -8
index ca77525..916ae25 100644
@@ -2,6 +2,8 @@
  * Broadcom specific AMBA
  * SPROM reading
  *
+ * Copyright 2011, 2012, Hauke Mehrtens <[email protected]>
+ *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
 
@@ -14,6 +16,45 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 
+static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
+
+/**
+ * bcma_arch_register_fallback_sprom - Registers a method providing a
+ * fallback SPROM if no SPROM is found.
+ *
+ * @sprom_callback: The callback function.
+ *
+ * With this function the architecture implementation may register a
+ * callback handler which fills the SPROM data structure. The fallback is
+ * used for PCI based BCMA devices, where no valid SPROM can be found
+ * in the shadow registers and to provide the SPROM for SoCs where BCMA is
+ * to controll the system bus.
+ *
+ * This function is useful for weird architectures that have a half-assed
+ * BCMA device hardwired to their PCI bus.
+ *
+ * This function is available for architecture code, only. So it is not
+ * exported.
+ */
+int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
+				     struct ssb_sprom *out))
+{
+	if (get_fallback_sprom)
+		return -EEXIST;
+	get_fallback_sprom = sprom_callback;
+
+	return 0;
+}
+
+static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
+					 struct ssb_sprom *out)
+{
+	if (!get_fallback_sprom)
+		return -ENOENT;
+
+	return get_fallback_sprom(bus, out);
+}
+
 /**************************************************
  * R/W ops.
  **************************************************/
@@ -246,23 +287,43 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 	     SSB_SROM8_FEM_ANTSWLUT_SHIFT);
 }
 
+static bool bcma_is_sprom_available(struct bcma_bus *bus)
+{
+	u32 sromctrl;
+
+	if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
+		return false;
+
+	if (bus->drv_cc.core->id.rev >= 32) {
+		sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL);
+		return sromctrl & BCMA_CC_SROM_CONTROL_PRESENT;
+	}
+	return true;
+}
+
 int bcma_sprom_get(struct bcma_bus *bus)
 {
 	u16 offset;
 	u16 *sprom;
-	u32 sromctrl;
 	int err = 0;
 
 	if (!bus->drv_cc.core)
 		return -EOPNOTSUPP;
 
-	if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
-		return -ENOENT;
-
-	if (bus->drv_cc.core->id.rev >= 32) {
-		sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL);
-		if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT))
-			return -ENOENT;
+	if (!bcma_is_sprom_available(bus)) {
+		/*
+		 * Maybe there is no SPROM on the device?
+		 * Now we ask the arch code if there is some sprom
+		 * available for this device in some other storage.
+		 */
+		err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
+		if (err) {
+			pr_warn("Using fallback SPROM failed (err %d)\n", err);
+		} else {
+			pr_debug("Using SPROM revision %d provided by"
+				 " platform.\n", bus->sprom.revision);
+			return 0;
+		}
 	}
 
 	sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
include/linux/bcma/bcma.h +6 -0
index 46bbd08..5af9a07 100644
@@ -176,6 +176,12 @@ int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
 
 extern void bcma_driver_unregister(struct bcma_driver *drv);
 
+/* Set a fallback SPROM.
+ * See kdoc at the function definition for complete documentation. */
+extern int bcma_arch_register_fallback_sprom(
+		int (*sprom_callback)(struct bcma_bus *bus,
+		struct ssb_sprom *out));
+
 struct bcma_bus {
 	/* The MMIO area. */
 	void __iomem *mmio;
Signature · 1 line
1.7.5.4
#8 lore raw

PATCH v2 7/11 bcma: add support for sprom not found on the device

Quoted 9 lines · Hauke Mehrtens

if (!bus->drv_cc.core)
return -EOPNOTSUPP;

drivers/bcma/sprom.c +0 -6
-	if (!(bus->drv_cc.capabilities&  BCMA_CC_CAP_SPROM))
-		return -ENOENT;
-
-	if (bus->drv_cc.core->id.rev>= 32) {
-		sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL);
-		if (!(sromctrl&  BCMA_CC_SROM_CONTROL_PRESENT))

drivers/bcma/sprom.c static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) · line 321

Quoted 10 lines
drivers/bcma/sprom.c +9 -1
-			return -ENOENT;
+	if (!bcma_is_sprom_available(bus)) {
+		/*
+		 * Maybe there is no SPROM on the device?
+		 * Now we ask the arch code if there is some sprom
+		 * available for this device in some other storage.
+		 */
+		err = bcma_fill_sprom_with_fallback(bus,&bus->sprom);
+		if (err) {
+			pr_warn("Using fallback SPROM failed (err %d)\n", err);

Hi Hauke,

I just noticed in this patch that the code continues when sprom fallback fails. Does that make sense? I have corrected it in my OTP patch. So if you agree or disagree you can comment on that patch.

drivers/bcma/sprom.c static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) · line 329

Quoted 8 lines
drivers/bcma/sprom.c +5 -0
+		} else {
+			pr_debug("Using SPROM revision %d provided by"
+				 " platform.\n", bus->sprom.revision);
+			return 0;
+		}
  	}
 
  	sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),

Gr. AvS

author maintainer
#9 lore raw

PATCH v2 8/11 MIPS: BCM47XX: return number of written bytes in nvram_getenv

In reply to Hauke Mehrtens
---
 arch/mips/bcm47xx/nvram.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
arch/mips/bcm47xx/nvram.c +1 -2
index a84e3bb..d43ceff 100644
@@ -107,8 +107,7 @@ int nvram_getenv(char *name, char *val, size_t val_len)
 		value = eq + 1;
 		if ((eq - var) == strlen(name) &&
 			strncmp(var, name, (eq - var)) == 0) {
-			snprintf(val, val_len, "%s", value);
-			return 0;
+			return snprintf(val, val_len, "%s", value);
 		}
 	}
 	return NVRAM_ERR_ENVNOTFOUND;
Signature · 1 line
1.7.5.4
author maintainer
#10 lore raw

PATCH v2 9/11 MIPS: BCM47XX: fix signature of nvram_parse_macaddr

In reply to Hauke Mehrtens

Explicitly enforce an char array of 6 bytes for the mac address.

---
 arch/mips/include/asm/mach-bcm47xx/nvram.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
arch/mips/include/asm/mach-bcm47xx/nvram.h +1 -1
index 184d5ec..69ef3ef 100644
@@ -37,7 +37,7 @@ struct nvram_header {
 
 extern int nvram_getenv(char *name, char *val, size_t val_len);
 
-static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
+static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6])
 {
 	if (strchr(buf, ':'))
 		sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
Signature · 1 line
1.7.5.4
author maintainer
#11 lore raw

PATCH v2 10/11 MIPS: BCM47XX: move and extend sprom parsing

In reply to Hauke Mehrtens

Move the sprom parsing from nvram into sprom.c. There are all values needed for sprom version 1 to 9 read from nvram and there are more sanity checks added. This is based on the sprom parsing in the open source part of the Broadcom SDK.

---
 arch/mips/bcm47xx/Makefile                   |    2 +-
 arch/mips/bcm47xx/setup.c                    |  151 +-------
 arch/mips/bcm47xx/sprom.c                    |  620 ++++++++++++++++++++++++++
 arch/mips/include/asm/mach-bcm47xx/bcm47xx.h |    3 +
 4 files changed, 625 insertions(+), 151 deletions(-)
 create mode 100644 arch/mips/bcm47xx/sprom.c
arch/mips/bcm47xx/Makefile +1 -1
index 4add173..4389de1 100644
@@ -3,5 +3,5 @@
 # under Linux.
 #
 
-obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
+obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
 obj-$(CONFIG_BCM47XX_SSB)	+= wgt634u.o
arch/mips/bcm47xx/setup.c +1 -150

157 lines not on this page · raw message

arch/mips/bcm47xx/sprom.c new file +620 -0

620 lines not on this page · raw message

arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +3 -0
index de95e07..5ecaf47 100644
@@ -44,4 +44,7 @@ union bcm47xx_bus {
 extern union bcm47xx_bus bcm47xx_bus;
 extern enum bcm47xx_bus_type bcm47xx_bus_type;
 
+void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix);
+void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix);
+
 #endif /* __ASM_BCM47XX_H */
Signature · 1 line
1.7.5.4
author maintainer
#12 lore raw

PATCH v2 11/11 MIPS: BCM47XX: provide sprom to bcma bus

In reply to Hauke Mehrtens

On SoCs the sprom is often stored in nvram in the flashchip. This patch registers a sprom fallback callback handler in bcma and provides the sprom needed for this device.

---
 arch/mips/bcm47xx/setup.c |   39 +++++++++++++++++++++++++++++++++++----
 1 files changed, 35 insertions(+), 4 deletions(-)
arch/mips/bcm47xx/setup.c +35 -4
index 6b0dacd..19780aa 100644
@@ -3,7 +3,7 @@
  *  Copyright (C) 2006 Felix Fietkau <[email protected]>
  *  Copyright (C) 2006 Michael Buesch <[email protected]>
  *  Copyright (C) 2010 Waldemar Brodkorb <[email protected]>
- *  Copyright (C) 2010-2011 Hauke Mehrtens <[email protected]>
+ *  Copyright (C) 2010-2012 Hauke Mehrtens <[email protected]>
  *
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
@@ -85,7 +85,7 @@ static void bcm47xx_machine_halt(void)
 }
 
 #ifdef CONFIG_BCM47XX_SSB
-static int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
+static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
 {
 	char prefix[10];
 
@@ -102,7 +102,7 @@ static int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
 }
 
 static int bcm47xx_get_invariants(struct ssb_bus *bus,
-				   struct ssb_init_invariants *iv)
+				  struct ssb_init_invariants *iv)
 {
 	char buf[20];
 
@@ -132,7 +132,7 @@ static void __init bcm47xx_register_ssb(void)
 	char buf[100];
 	struct ssb_mipscore *mcore;
 
-	err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom);
+	err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb);
 	if (err)
 		printk(KERN_WARNING "bcm47xx: someone else already registered"
 			" a ssb SPROM callback handler (err %d)\n", err);
@@ -159,10 +159,41 @@ static void __init bcm47xx_register_ssb(void)
 #endif
 
 #ifdef CONFIG_BCM47XX_BCMA
+static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
+{
+	char prefix[10];
+	struct bcma_device *core;
+
+	switch (bus->hosttype) {
+	case BCMA_HOSTTYPE_PCI:
+		snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
+			 bus->host_pci->bus->number + 1,
+			 PCI_SLOT(bus->host_pci->devfn));
+		bcm47xx_fill_sprom(out, prefix);
+		return 0;
+	case BCMA_HOSTTYPE_SOC:
+		bcm47xx_fill_sprom_ethernet(out, NULL);
+		core = bcma_find_core(bus, BCMA_CORE_80211);
+		if (core) {
+			snprintf(prefix, sizeof(prefix), "sb/%u/",
+				 core->core_index);
+			bcm47xx_fill_sprom(out, prefix);
+		}
+		return 0;
+	default:
+		pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
+		return -EINVAL;
+	}
+}
+
 static void __init bcm47xx_register_bcma(void)
 {
 	int err;
 
+	err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma);
+	if (err)
+		pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err);
+
 	err = bcma_host_soc_register(&bcm47xx_bus.bcma);
 	if (err)
 		panic("Failed to initialize BCMA bus (err %d)", err);
Signature · 1 line
1.7.5.4