diff options
Diffstat (limited to 'target')
16 files changed, 1378 insertions, 44 deletions
diff --git a/target/linux/brcm47xx/patches-3.2/0023-bcma-use-randoom-mac-address-as-long-as-reading-it-o.patch b/target/linux/brcm47xx/patches-3.2/0023-bcma-use-randoom-mac-address-as-long-as-reading-it-o.patch deleted file mode 100644 index fee1d0a5a..000000000 --- a/target/linux/brcm47xx/patches-3.2/0023-bcma-use-randoom-mac-address-as-long-as-reading-it-o.patch +++ /dev/null @@ -1,33 +0,0 @@ -From e6730c06cfc827d715f43e9bd276ae939bb86af9 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens <hauke@hauke-m.de> -Date: Fri, 22 Jul 2011 17:11:51 +0200 -Subject: [PATCH 23/26] bcma: use randoom mac address as long as reading it out does not work - - -Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> ---- - drivers/bcma/sprom.c |    5 ++++- - 1 files changed, 4 insertions(+), 1 deletions(-) - ---- a/drivers/bcma/sprom.c -+++ b/drivers/bcma/sprom.c -@@ -13,6 +13,7 @@ - #include <linux/io.h> - #include <linux/dma-mapping.h> - #include <linux/slab.h> -+#include <linux/etherdevice.h> -  - #define SPOFF(offset)	((offset) / sizeof(u16)) -  -@@ -214,8 +215,10 @@ int bcma_sprom_get(struct bcma_bus *bus) - 	if (!bus->drv_cc.core) - 		return -EOPNOTSUPP; -  --	if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) -+	if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) { -+		random_ether_addr(bus->sprom.il0mac); - 		return -ENOENT; -+	} -  - 	sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), - 			GFP_KERNEL); diff --git a/target/linux/brcm47xx/patches-3.2/0043-bcma-add-extra-sprom-check.patch b/target/linux/brcm47xx/patches-3.2/0043-bcma-add-extra-sprom-check.patch index 0dd196815..3ae571153 100644 --- a/target/linux/brcm47xx/patches-3.2/0043-bcma-add-extra-sprom-check.patch +++ b/target/linux/brcm47xx/patches-3.2/0043-bcma-add-extra-sprom-check.patch @@ -14,7 +14,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>  --- a/drivers/bcma/sprom.c  +++ b/drivers/bcma/sprom.c -@@ -210,6 +210,7 @@ int bcma_sprom_get(struct bcma_bus *bus) +@@ -209,6 +209,7 @@ int bcma_sprom_get(struct bcma_bus *bus)   {   	u16 offset;   	u16 *sprom; @@ -22,14 +22,13 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>   	int err = 0;   	if (!bus->drv_cc.core) -@@ -220,6 +221,13 @@ int bcma_sprom_get(struct bcma_bus *bus) +@@ -217,6 +218,12 @@ int bcma_sprom_get(struct bcma_bus *bus) + 	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)) -+			random_ether_addr(bus->sprom.il0mac);  +			return -ENOENT;  +	}  + diff --git a/target/linux/brcm47xx/patches-3.2/190-ssb-sprom-fix-some-sizes-signedness.patch b/target/linux/brcm47xx/patches-3.2/190-ssb-sprom-fix-some-sizes-signedness.patch new file mode 100644 index 000000000..ac73f3d4b --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/190-ssb-sprom-fix-some-sizes-signedness.patch @@ -0,0 +1,75 @@ +From 0af3fa9e4c9ea0ca0662f09183d71ea9a7eb572f Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 18 Feb 2012 14:33:08 +0100 +Subject: [PATCH 190/202] 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 +antenna_gain is unsigned + +I got these information for the open source part of the Braodcom 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. + +I was unable to find any reverences to antenna_gain.ghz5 in the +Broadcom SDK. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + include/linux/ssb/ssb.h |   20 ++++++++++---------- + 1 files changed, 10 insertions(+), 10 deletions(-) + +--- a/include/linux/ssb/ssb.h ++++ b/include/linux/ssb/ssb.h +@@ -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; +@@ -95,10 +95,10 @@ struct ssb_sprom { + 	 * loss in the connectors is bigger than the gain. */ + 	struct { + 		struct { +-			s8 a0, a1, a2, a3; ++			u8 a0, a1, a2, a3; + 		} ghz24;	/* 2.4GHz band */ + 		struct { +-			s8 a0, a1, a2, a3; ++			u8 a0, a1, a2, a3; + 		} ghz5;		/* 5GHz band */ + 	} antenna_gain; +  diff --git a/target/linux/brcm47xx/patches-3.2/191-ssb-fix-per-path-sprom-vars.patch b/target/linux/brcm47xx/patches-3.2/191-ssb-fix-per-path-sprom-vars.patch new file mode 100644 index 000000000..d5fea1aae --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/191-ssb-fix-per-path-sprom-vars.patch @@ -0,0 +1,25 @@ +From f453c08359a875df66cbbda48087e3592c29da58 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 18 Feb 2012 16:23:58 +0100 +Subject: [PATCH 191/202] ssb: fix per path sprom vars + +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. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + include/linux/ssb/ssb.h |    2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/include/linux/ssb/ssb.h ++++ b/include/linux/ssb/ssb.h +@@ -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 { diff --git a/target/linux/brcm47xx/patches-3.2/192-ssb-add-ccode.patch b/target/linux/brcm47xx/patches-3.2/192-ssb-add-ccode.patch new file mode 100644 index 000000000..1b6d5c44e --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/192-ssb-add-ccode.patch @@ -0,0 +1,22 @@ +From b0a2a5c4a88f5d83046b408714ec9b86772fa75d Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 18 Feb 2012 17:16:28 +0100 +Subject: [PATCH 192/202] ssb: add ccode + +This member contains the country code encoded with two chars + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + include/linux/ssb/ssb.h |    1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +--- a/include/linux/ssb/ssb.h ++++ b/include/linux/ssb/ssb.h +@@ -35,6 +35,7 @@ struct ssb_sprom { + 	u8 country_code;	/* Country Code */ + 	u8 leddc_on_time;	/* LED Powersave Duty Cycle On Count */ + 	u8 leddc_off_time;	/* LED Powersave Duty Cycle Off Count */ ++	char ccode[2]; + 	u8 ant_available_a;	/* 2GHz antenna available bits (up to 4) */ + 	u8 ant_available_bg;	/* 5GHz antenna available bits (up to 4) */ + 	u16 pa0b0; diff --git a/target/linux/brcm47xx/patches-3.2/193-ssb-add-some-missing-sprom-attributes.patch b/target/linux/brcm47xx/patches-3.2/193-ssb-add-some-missing-sprom-attributes.patch new file mode 100644 index 000000000..e0bcddbf3 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/193-ssb-add-some-missing-sprom-attributes.patch @@ -0,0 +1,106 @@ +From 91e6ca304fb163e2f9b15188686fc4637f2cd32a Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Fri, 17 Feb 2012 23:26:39 +0100 +Subject: [PATCH 193/202] ssb: add some missing sprom attributes + +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 Braodcom SDK. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + include/linux/ssb/ssb.h |   76 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 75 insertions(+), 1 deletions(-) + +--- a/include/linux/ssb/ssb.h ++++ b/include/linux/ssb/ssb.h +@@ -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; ++	u16 board_type; + 	u8 country_code;	/* Country Code */ + 	u8 leddc_on_time;	/* LED Powersave Duty Cycle On Count */ + 	u8 leddc_off_time;	/* LED Powersave Duty Cycle Off Count */ +@@ -112,7 +114,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. */ diff --git a/target/linux/brcm47xx/patches-3.2/194-bcma-export-bcma_find_core.patch b/target/linux/brcm47xx/patches-3.2/194-bcma-export-bcma_find_core.patch new file mode 100644 index 000000000..1722ae120 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/194-bcma-export-bcma_find_core.patch @@ -0,0 +1,43 @@ +From a07c69ed06031373726e9e5e513d0d942997c265 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 18 Feb 2012 14:22:32 +0100 +Subject: [PATCH 194/202] bcma: export bcma_find_core + +This function is needed by the bcm47xx arch code to get the number of +the ieee80211 core. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + drivers/bcma/main.c       |    3 ++- + include/linux/bcma/bcma.h |    1 + + 2 files changed, 3 insertions(+), 1 deletions(-) + +--- a/drivers/bcma/main.c ++++ b/drivers/bcma/main.c +@@ -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_cor + 	} + 	return NULL; + } ++EXPORT_SYMBOL_GPL(bcma_find_core); +  + static void bcma_release_core_dev(struct device *dev) + { +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -285,6 +285,7 @@ static inline void bcma_maskset16(struct + 	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); diff --git a/target/linux/brcm47xx/patches-3.2/195-bcma-add-support-for-sprom-not-found-on-the-device.patch b/target/linux/brcm47xx/patches-3.2/195-bcma-add-support-for-sprom-not-found-on-the-device.patch new file mode 100644 index 000000000..6991576d2 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/195-bcma-add-support-for-sprom-not-found-on-the-device.patch @@ -0,0 +1,137 @@ +From 332b8f6ca7da3197c631928b6bd1e7fdca87e109 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 18 Feb 2012 01:16:35 +0100 +Subject: [PATCH 195/202] bcma: add support for sprom not found on the device. + +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. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + drivers/bcma/sprom.c      |   80 ++++++++++++++++++++++++++++++++++++++++---- + include/linux/bcma/bcma.h |    6 +++ + 2 files changed, 78 insertions(+), 8 deletions(-) + +--- a/drivers/bcma/sprom.c ++++ b/drivers/bcma/sprom.c +@@ -16,6 +16,49 @@ +  + #define SPOFF(offset)	((offset) / sizeof(u16)) +  ++static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out); ++ ++/** ++ * ssb_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 ++ * only used for PCI based SSB devices, where no valid SPROM can be found ++ * in the shadow registers. ++ * ++ * This function is useful for weird architectures that have a half-assed ++ * SSB device hardwired to their PCI bus. ++ * ++ * Note that it does only work with PCI attached SSB devices. PCMCIA ++ * devices currently don't use this fallback. ++ * Architectures must provide the SPROM for native SSB devices anyway, so ++ * the fallback also isn't used for native devices. ++ * ++ * 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. +  **************************************************/ +@@ -205,23 +248,44 @@ static void bcma_sprom_extract_r8(struct + 		SSB_SROM8_FEM_ANTSWLUT) >> 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); ++		if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT)) ++			return false; ++	} ++	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), +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -177,6 +177,12 @@ int __bcma_driver_register(struct bcma_d +  + 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; diff --git a/target/linux/brcm47xx/patches-3.2/196-MIPS-BCM47XX-return-number-of-written-bytes-in-nvram.patch b/target/linux/brcm47xx/patches-3.2/196-MIPS-BCM47XX-return-number-of-written-bytes-in-nvram.patch new file mode 100644 index 000000000..926ec844c --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/196-MIPS-BCM47XX-return-number-of-written-bytes-in-nvram.patch @@ -0,0 +1,24 @@ +From 3ac18c5072e097ffa719994ef3b5c64e744a5405 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 18 Feb 2012 14:46:45 +0100 +Subject: [PATCH 196/202] MIPS: BCM47XX: return number of written bytes in + nvram_getenv + + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + arch/mips/bcm47xx/nvram.c |    3 +-- + 1 files changed, 1 insertions(+), 2 deletions(-) + +--- a/arch/mips/bcm47xx/nvram.c ++++ b/arch/mips/bcm47xx/nvram.c +@@ -192,8 +192,7 @@ int nvram_getenv(char *name, char *val, + 		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; diff --git a/target/linux/brcm47xx/patches-3.2/197-MIPS-BCM47XX-fix-signature-of-nvram_parse_macaddr.patch b/target/linux/brcm47xx/patches-3.2/197-MIPS-BCM47XX-fix-signature-of-nvram_parse_macaddr.patch new file mode 100644 index 000000000..ade9bcb75 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/197-MIPS-BCM47XX-fix-signature-of-nvram_parse_macaddr.patch @@ -0,0 +1,23 @@ +From c330338212785092aab7a266f24b52c132775463 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 18 Feb 2012 15:00:36 +0100 +Subject: [PATCH 197/202] MIPS: BCM47XX: fix signature of nvram_parse_macaddr + +Explicitly enforce an char array of 6 bytes for the mac address. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + arch/mips/include/asm/mach-bcm47xx/nvram.h |    2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm47xx/nvram.h ++++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h +@@ -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], diff --git a/target/linux/brcm47xx/patches-3.2/198-MIPS-BCM47XX-move-and-extend-sprom-parsing.patch b/target/linux/brcm47xx/patches-3.2/198-MIPS-BCM47XX-move-and-extend-sprom-parsing.patch new file mode 100644 index 000000000..a8272cd4c --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/198-MIPS-BCM47XX-move-and-extend-sprom-parsing.patch @@ -0,0 +1,819 @@ +From bf975de39d2c6be28421c1de2068fd8bd018b96d Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 18 Feb 2012 14:50:24 +0100 +Subject: [PATCH 198/202] MIPS: BCM47XX: move and extend sprom parsing + +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. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + arch/mips/bcm47xx/Makefile                   |    2 +- + arch/mips/bcm47xx/setup.c                    |  151 +------- + arch/mips/bcm47xx/sprom.c                    |  618 ++++++++++++++++++++++++++ + arch/mips/include/asm/mach-bcm47xx/bcm47xx.h |    3 + + 4 files changed, 623 insertions(+), 151 deletions(-) + create mode 100644 arch/mips/bcm47xx/sprom.c + +--- a/arch/mips/bcm47xx/Makefile ++++ b/arch/mips/bcm47xx/Makefile +@@ -3,5 +3,5 @@ + # under Linux. + # +  +-obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o ++obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o sprom.o + obj-$(CONFIG_BCM47XX_SSB)	+= wgt634u.o +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -91,156 +91,7 @@ static void bcm47xx_machine_halt(void) + } +  + #ifdef CONFIG_BCM47XX_SSB +-#define READ_FROM_NVRAM(_outvar, name, buf) \ +-	if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\ +-		sprom->_outvar = simple_strtoul(buf, NULL, 0); +- +-#define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \ +-	if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \ +-	    nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\ +-		sprom->_outvar = simple_strtoul(buf, NULL, 0); +- +-static inline int nvram_getprefix(const char *prefix, char *name, +-				  char *buf, int len) +-{ +-	if (prefix) { +-		char key[100]; +- +-		snprintf(key, sizeof(key), "%s%s", prefix, name); +-		return nvram_getenv(key, buf, len); +-	} +- +-	return nvram_getenv(name, buf, len); +-} +- +-static u32 nvram_getu32(const char *name, char *buf, int len) +-{ +-	int rv; +-	char key[100]; +-	u16 var0, var1; +- +-	snprintf(key, sizeof(key), "%s0", name); +-	rv = nvram_getenv(key, buf, len); +-	/* return 0 here so this looks like unset */ +-	if (rv < 0) +-		return 0; +-	var0 = simple_strtoul(buf, NULL, 0); +- +-	snprintf(key, sizeof(key), "%s1", name); +-	rv = nvram_getenv(key, buf, len); +-	if (rv < 0) +-		return 0; +-	var1 = simple_strtoul(buf, NULL, 0); +-	return var1 << 16 | var0; +-} +- +-static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) +-{ +-	char buf[100]; +-	u32 boardflags; +- +-	memset(sprom, 0, sizeof(struct ssb_sprom)); +- +-	sprom->revision = 1; /* Fallback: Old hardware does not define this. */ +-	READ_FROM_NVRAM(revision, "sromrev", buf); +-	if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 || +-	    nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0) +-		nvram_parse_macaddr(buf, sprom->il0mac); +-	if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0) +-		nvram_parse_macaddr(buf, sprom->et0mac); +-	if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0) +-		nvram_parse_macaddr(buf, sprom->et1mac); +-	READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf); +-	READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf); +-	READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf); +-	READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf); +-	READ_FROM_NVRAM(board_rev, "boardrev", buf); +-	READ_FROM_NVRAM(country_code, "ccode", buf); +-	READ_FROM_NVRAM(ant_available_a, "aa5g", buf); +-	READ_FROM_NVRAM(ant_available_bg, "aa2g", buf); +-	READ_FROM_NVRAM(pa0b0, "pa0b0", buf); +-	READ_FROM_NVRAM(pa0b1, "pa0b1", buf); +-	READ_FROM_NVRAM(pa0b2, "pa0b2", buf); +-	READ_FROM_NVRAM(pa1b0, "pa1b0", buf); +-	READ_FROM_NVRAM(pa1b1, "pa1b1", buf); +-	READ_FROM_NVRAM(pa1b2, "pa1b2", buf); +-	READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf); +-	READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf); +-	READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf); +-	READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf); +-	READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf); +-	READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf); +-	READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf); +-	READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf); +-	READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf); +-	READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf); +-	READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf); +-	READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf); +-	READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf); +-	READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf); +-	READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf); +-	READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf); +-	READ_FROM_NVRAM(tri2g, "tri2g", buf); +-	READ_FROM_NVRAM(tri5gl, "tri5gl", buf); +-	READ_FROM_NVRAM(tri5g, "tri5g", buf); +-	READ_FROM_NVRAM(tri5gh, "tri5gh", buf); +-	READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf); +-	READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf); +-	READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf); +-	READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf); +-	READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf); +-	READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf); +-	READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf); +-	READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf); +-	READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf); +-	READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf); +-	READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf); +-	READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf); +-	READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf); +-	READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf); +-	READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf); +-	READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf); +-	READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf); +-	READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf); +-	READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf); +-	READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf); +-	READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf); +-	READ_FROM_NVRAM(bxa2g, "bxa2g", buf); +-	READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf); +-	READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf); +-	READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf); +-	READ_FROM_NVRAM(bxa5g, "bxa5g", buf); +-	READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf); +- +-	sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf)); +-	sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf)); +-	sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf)); +-	sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf)); +- +-	READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf); +-	READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf); +-	READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf); +-	READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf); +-	memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24, +-	       sizeof(sprom->antenna_gain.ghz5)); +- +-	if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) { +-		boardflags = simple_strtoul(buf, NULL, 0); +-		if (boardflags) { +-			sprom->boardflags_lo = (boardflags & 0x0000FFFFU); +-			sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16; +-		} +-	} +-	if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) { +-		boardflags = simple_strtoul(buf, NULL, 0); +-		if (boardflags) { +-			sprom->boardflags2_lo = (boardflags & 0x0000FFFFU); +-			sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16; +-		} +-	} +-} +- +-int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) ++static int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) + { + 	char prefix[10]; +  +--- /dev/null ++++ b/arch/mips/bcm47xx/sprom.c +@@ -0,0 +1,618 @@ ++/* ++ *  Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> ++ *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> ++ *  Copyright (C) 2006 Michael Buesch <m@bues.ch> ++ *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> ++ *  Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> ++ * ++ *  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 ++ *  Free Software Foundation;  either version 2 of the  License, or (at your ++ *  option) any later version. ++ * ++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED ++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF ++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN ++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT, ++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF ++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT ++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ *  You should have received a copy of the  GNU General Public License along ++ *  with this program; if not, write  to the Free Software Foundation, Inc., ++ *  675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include <bcm47xx.h> ++#include <nvram.h> ++ ++static void create_key(const char *prefix, const char *postfix, ++		       const char *name, char *buf, int len) ++{ ++	if (prefix && postfix) ++		snprintf(buf, len, "%s%s%s", prefix, name, postfix); ++	else if (prefix) ++		snprintf(buf, len, "%s%s", prefix, name); ++	else if (postfix) ++		snprintf(buf, len, "%s%s", name, postfix); ++	else ++		snprintf(buf, len, "%s", name); ++} ++ ++#define NVRAM_READ_VAL(type)						\ ++static void nvram_read_ ## type (const char *prefix,			\ ++				 const char *postfix, const char *name,	\ ++				 type *val, type allset)		\ ++{									\ ++	char buf[100];							\ ++	char key[40];							\ ++	int err;							\ ++	type var;							\ ++									\ ++	create_key(prefix, postfix, name, key, sizeof(key));		\ ++									\ ++	err = nvram_getenv(key, buf, sizeof(buf));			\ ++	if (err < 0)							\ ++		return;							\ ++	err = kstrto ## type (buf, 0, &var);				\ ++	if (err) {							\ ++		pr_warn("can not parse nvram name %s with value %s"	\ ++			" got %i", key, buf, err);			\ ++		return;							\ ++	}								\ ++	if (allset && var == allset)					\ ++		return;							\ ++	*val = var;							\ ++} ++ ++NVRAM_READ_VAL(u8) ++NVRAM_READ_VAL(s8) ++NVRAM_READ_VAL(u16) ++NVRAM_READ_VAL(u32) ++ ++#undef NVRAM_READ_VAL ++ ++static void nvram_read_u32_2(const char *prefix, const char *name, ++			     u16 *val_lo, u16 *val_hi) ++{ ++	char buf[100]; ++	char key[40]; ++	int err; ++	u32 val; ++ ++	create_key(prefix, NULL, name, key, sizeof(key)); ++ ++	err = nvram_getenv(key, buf, sizeof(buf)); ++	if (err < 0) ++		return; ++	err = kstrtou32(buf, 0, &val); ++	if (err) { ++		pr_warn("can not parse nvram name %s with value %s got %i", ++			key, buf, err); ++		return; ++	} ++	*val_lo = (val & 0x0000FFFFU); ++	*val_hi = (val & 0xFFFF0000U) >> 16; ++} ++ ++static void nvram_read_leddc(const char *prefix, const char *name, ++			     u8 *leddc_on_time, u8 *leddc_off_time) ++{ ++	char buf[100]; ++	char key[40]; ++	int err; ++	u32 val; ++ ++	create_key(prefix, NULL, name, key, sizeof(key)); ++ ++	err = nvram_getenv(key, buf, sizeof(buf)); ++	if (err < 0) ++		return; ++	err = kstrtou32(buf, 0, &val); ++	if (err) { ++		pr_warn("can not parse nvram name %s with value %s got %i", ++			key, buf, err); ++		return; ++	} ++ ++	if (val == 0xffff || val == 0xffffffff) ++		return; ++ ++	*leddc_on_time = val & 0xff; ++	*leddc_off_time = (val >> 16) & 0xff; ++} ++ ++static void nvram_read_macaddr(const char *prefix, const char *name, ++			       u8 (*val)[6]) ++{ ++	char buf[100]; ++	char key[40]; ++	int err; ++ ++	create_key(prefix, NULL, name, key, sizeof(key)); ++ ++	err = nvram_getenv(key, buf, sizeof(buf)); ++	if (err < 0) ++		return; ++	nvram_parse_macaddr(buf, *val); ++} ++ ++static void nvram_read_ccode(const char *prefix, const char *name, ++			     char (*val)[2]) ++{ ++	char buf[10]; ++	char key[40]; ++	int err; ++ ++	create_key(prefix, NULL, name, key, sizeof(key)); ++ ++	err = nvram_getenv(key, buf, sizeof(buf)); ++	if (err < 0) ++		return; ++	if (buf[0] == '0') ++		return; ++	if (strlen(buf) > 2) { ++		pr_warn("ccode is too long %s", buf); ++		return; ++	} ++	memcpy(val, buf, sizeof(val)); ++} ++ ++static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom, ++					const char *prefix) ++{ ++	nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0); ++	nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0); ++	nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff); ++	nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff); ++	nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff); ++	nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff); ++	nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0); ++	nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0); ++	nvram_read_u8(prefix, NULL, "ag0", &sprom->antenna_gain.ghz24.a0, 0); ++	nvram_read_u8(prefix, NULL, "ag1", &sprom->antenna_gain.ghz24.a1, 0); ++	nvram_read_ccode(prefix, "ccode", &sprom->ccode); ++} ++ ++static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom, ++				      const char *prefix) ++{ ++	nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0); ++	nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0); ++	nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0); ++	nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0); ++	nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0); ++	nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0); ++	nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0); ++	nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0); ++	nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0); ++	nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0); ++} ++ ++static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix) ++{ ++	nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0); ++	nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0); ++} ++ ++static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom, ++				     const char *prefix) ++{ ++	nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0); ++	nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0); ++	nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0); ++	nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0); ++	nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0); ++	nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0); ++	nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0); ++	nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0); ++	nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0); ++} ++ ++static void bcm47xx_fill_sprom_r2(struct ssb_sprom *sprom, const char *prefix) ++{ ++	nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, ++			 &sprom->boardflags_hi); ++	nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); ++} ++ ++static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix) ++{ ++	nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0); ++	nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0); ++	nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0); ++	nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0); ++	nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0); ++	nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0); ++	nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0); ++	nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0); ++	nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0); ++	nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0); ++	nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0); ++	nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0); ++	nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0); ++	nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0); ++} ++ ++static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix) ++{ ++	nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, ++			 &sprom->boardflags_hi); ++	nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); ++	nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); ++	nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, ++			 &sprom->leddc_off_time); ++} ++ ++static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom, ++				     const char *prefix) ++{ ++	nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, ++			 &sprom->boardflags_hi); ++	nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, ++			 &sprom->boardflags2_hi); ++	nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); ++	nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); ++	nvram_read_u8(prefix, NULL, "ag2", &sprom->antenna_gain.ghz24.a2, 0); ++	nvram_read_u8(prefix, NULL, "ag3", &sprom->antenna_gain.ghz24.a3, 0); ++	nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf); ++	nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf); ++	nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff); ++	nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, ++			 &sprom->leddc_off_time); ++} ++ ++static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix) ++{ ++	nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0); ++	nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0); ++	nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0); ++	nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0); ++	nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0); ++	nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0); ++	nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0); ++	nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0); ++	nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0); ++	nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0); ++	nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0); ++	nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0); ++	nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0); ++	nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0); ++	nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0); ++	nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0); ++	nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0); ++	nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0); ++	nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0); ++	nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0); ++	nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0); ++	nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0); ++	nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0); ++	nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0); ++	nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0); ++	nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0); ++	nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0); ++	nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0); ++	nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0); ++	nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0); ++	nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0); ++	nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0); ++	nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0); ++	nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0); ++	nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0); ++	nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0); ++	nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0); ++	nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0); ++	nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0); ++	nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0); ++	nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0); ++} ++ ++static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix) ++{ ++	nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0); ++	nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0); ++	nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0); ++	nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0); ++	nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0); ++	nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0); ++	nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0); ++	nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0); ++	nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0); ++	nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0); ++	nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0); ++	nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0); ++	nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0); ++	nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0); ++	nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0); ++	nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0); ++} ++ ++static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix) ++{ ++	nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0); ++	nvram_read_u8(prefix, NULL, "extpagain2g", ++		      &sprom->fem.ghz2.extpa_gain, 0); ++	nvram_read_u8(prefix, NULL, "pdetrange2g", ++		      &sprom->fem.ghz2.pdet_range, 0); ++	nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0); ++	nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0); ++	nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0); ++	nvram_read_u8(prefix, NULL, "extpagain5g", ++		      &sprom->fem.ghz5.extpa_gain, 0); ++	nvram_read_u8(prefix, NULL, "pdetrange5g", ++		      &sprom->fem.ghz5.pdet_range, 0); ++	nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0); ++	nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0); ++	nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0); ++	nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0); ++	nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0); ++	nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0); ++	nvram_read_u8(prefix, NULL, "tempsense_slope", ++		      &sprom->tempsense_slope, 0); ++	nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0); ++	nvram_read_u8(prefix, NULL, "tempsense_option", ++		      &sprom->tempsense_option, 0); ++	nvram_read_u8(prefix, NULL, "freqoffset_corr", ++		      &sprom->freqoffset_corr, 0); ++	nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0); ++	nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0); ++	nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0); ++	nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0); ++	nvram_read_u8(prefix, NULL, "phycal_tempdelta", ++		      &sprom->phycal_tempdelta, 0); ++	nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0); ++	nvram_read_u8(prefix, NULL, "temps_hysteresis", ++		      &sprom->temps_hysteresis, 0); ++	nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0); ++	nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr2ga0", ++		      &sprom->rxgainerr2ga[0], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr2ga1", ++		      &sprom->rxgainerr2ga[1], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr2ga2", ++		      &sprom->rxgainerr2ga[2], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gla0", ++		      &sprom->rxgainerr5gla[0], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gla1", ++		      &sprom->rxgainerr5gla[1], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gla2", ++		      &sprom->rxgainerr5gla[2], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gma0", ++		      &sprom->rxgainerr5gma[0], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gma1", ++		      &sprom->rxgainerr5gma[1], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gma2", ++		      &sprom->rxgainerr5gma[2], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gha0", ++		      &sprom->rxgainerr5gha[0], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gha1", ++		      &sprom->rxgainerr5gha[1], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gha2", ++		      &sprom->rxgainerr5gha[2], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gua0", ++		      &sprom->rxgainerr5gua[0], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gua1", ++		      &sprom->rxgainerr5gua[1], 0); ++	nvram_read_u8(prefix, NULL, "rxgainerr5gua2", ++		      &sprom->rxgainerr5gua[2], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gla0", ++		      &sprom->noiselvl5gla[0], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gla1", ++		      &sprom->noiselvl5gla[1], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gla2", ++		      &sprom->noiselvl5gla[2], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gma0", ++		      &sprom->noiselvl5gma[0], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gma1", ++		      &sprom->noiselvl5gma[1], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gma2", ++		      &sprom->noiselvl5gma[2], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gha0", ++		      &sprom->noiselvl5gha[0], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gha1", ++		      &sprom->noiselvl5gha[1], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gha2", ++		      &sprom->noiselvl5gha[2], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gua0", ++		      &sprom->noiselvl5gua[0], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gua1", ++		      &sprom->noiselvl5gua[1], 0); ++	nvram_read_u8(prefix, NULL, "noiselvl5gua2", ++		      &sprom->noiselvl5gua[2], 0); ++	nvram_read_u8(prefix, NULL, "pcieingress_war", ++		      &sprom->pcieingress_war, 0); ++} ++ ++static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix) ++{ ++	nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0); ++	nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0); ++	nvram_read_u32(prefix, NULL, "legofdmbw202gpo", ++		       &sprom->legofdmbw202gpo, 0); ++	nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo", ++		       &sprom->legofdmbw20ul2gpo, 0); ++	nvram_read_u32(prefix, NULL, "legofdmbw205glpo", ++		       &sprom->legofdmbw205glpo, 0); ++	nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo", ++		       &sprom->legofdmbw20ul5glpo, 0); ++	nvram_read_u32(prefix, NULL, "legofdmbw205gmpo", ++		       &sprom->legofdmbw205gmpo, 0); ++	nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo", ++		       &sprom->legofdmbw20ul5gmpo, 0); ++	nvram_read_u32(prefix, NULL, "legofdmbw205ghpo", ++		       &sprom->legofdmbw205ghpo, 0); ++	nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo", ++		       &sprom->legofdmbw20ul5ghpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo", ++		       &sprom->mcsbw20ul5glpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo", ++		       &sprom->mcsbw20ul5gmpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo", ++		       &sprom->mcsbw20ul5ghpo, 0); ++	nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0); ++	nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0); ++	nvram_read_u16(prefix, NULL, "legofdm40duppo", ++		       &sprom->legofdm40duppo, 0); ++	nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0); ++	nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0); ++} ++ ++static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom, ++					  const char *prefix) ++{ ++	char postfix[2]; ++	int i; ++ ++	for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { ++		struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; ++		snprintf(postfix, sizeof(postfix), "%i", i); ++		nvram_read_u8(prefix, postfix, "maxp2ga", ++			      &pwr_info->maxpwr_2g, 0); ++		nvram_read_u8(prefix, postfix, "itt2ga", ++			      &pwr_info->itssi_2g, 0); ++		nvram_read_u8(prefix, postfix, "itt5ga", ++			      &pwr_info->itssi_5g, 0); ++		nvram_read_u16(prefix, postfix, "pa2gw0a", ++			       &pwr_info->pa_2g[0], 0); ++		nvram_read_u16(prefix, postfix, "pa2gw1a", ++			       &pwr_info->pa_2g[1], 0); ++		nvram_read_u16(prefix, postfix, "pa2gw2a", ++			       &pwr_info->pa_2g[2], 0); ++		nvram_read_u8(prefix, postfix, "maxp5ga", ++			      &pwr_info->maxpwr_5g, 0); ++		nvram_read_u8(prefix, postfix, "maxp5gha", ++			      &pwr_info->maxpwr_5gh, 0); ++		nvram_read_u8(prefix, postfix, "maxp5gla", ++			      &pwr_info->maxpwr_5gl, 0); ++		nvram_read_u16(prefix, postfix, "pa5gw0a", ++			       &pwr_info->pa_5g[0], 0); ++		nvram_read_u16(prefix, postfix, "pa5gw1a", ++			       &pwr_info->pa_5g[1], 0); ++		nvram_read_u16(prefix, postfix, "pa5gw2a", ++			       &pwr_info->pa_5g[2], 0); ++		nvram_read_u16(prefix, postfix, "pa5glw0a", ++			       &pwr_info->pa_5gl[0], 0); ++		nvram_read_u16(prefix, postfix, "pa5glw1a", ++			       &pwr_info->pa_5gl[1], 0); ++		nvram_read_u16(prefix, postfix, "pa5glw2a", ++			       &pwr_info->pa_5gl[2], 0); ++		nvram_read_u16(prefix, postfix, "pa5ghw0a", ++			       &pwr_info->pa_5gh[0], 0); ++		nvram_read_u16(prefix, postfix, "pa5ghw1a", ++			       &pwr_info->pa_5gh[1], 0); ++		nvram_read_u16(prefix, postfix, "pa5ghw2a", ++			       &pwr_info->pa_5gh[2], 0); ++	} ++} ++ ++static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, ++					const char *prefix) ++{ ++	char postfix[2]; ++	int i; ++ ++	for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { ++		struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; ++		snprintf(postfix, sizeof(postfix), "%i", i); ++		nvram_read_u16(prefix, postfix, "pa2gw3a", ++			       &pwr_info->pa_2g[3], 0); ++		nvram_read_u16(prefix, postfix, "pa5gw3a", ++			       &pwr_info->pa_5g[3], 0); ++		nvram_read_u16(prefix, postfix, "pa5glw3a", ++			       &pwr_info->pa_5gl[3], 0); ++		nvram_read_u16(prefix, postfix, "pa5ghw3a", ++			       &pwr_info->pa_5gh[3], 0); ++	} ++} ++ ++void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix) ++{ ++	nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac); ++	nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0); ++	nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0); ++ ++	nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac); ++	nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0); ++	nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0); ++ ++	nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac); ++	nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac); ++} ++ ++void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) ++{ ++	memset(sprom, 0, sizeof(struct ssb_sprom)); ++ ++	bcm47xx_fill_sprom_ethernet(sprom, prefix); ++ ++	nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0); ++ ++	switch (sprom->revision) { ++	case 1: ++		bcm47xx_fill_sprom_r1234589(sprom, prefix); ++		bcm47xx_fill_sprom_r12389(sprom, prefix); ++		bcm47xx_fill_sprom_r1(sprom, prefix); ++		break; ++	case 2: ++		bcm47xx_fill_sprom_r1234589(sprom, prefix); ++		bcm47xx_fill_sprom_r12389(sprom, prefix); ++		bcm47xx_fill_sprom_r2389(sprom, prefix); ++		bcm47xx_fill_sprom_r2(sprom, prefix); ++		break; ++	case 3: ++		bcm47xx_fill_sprom_r1234589(sprom, prefix); ++		bcm47xx_fill_sprom_r12389(sprom, prefix); ++		bcm47xx_fill_sprom_r2389(sprom, prefix); ++		bcm47xx_fill_sprom_r389(sprom, prefix); ++		bcm47xx_fill_sprom_r3(sprom, prefix); ++		break; ++	case 4: ++	case 5: ++		bcm47xx_fill_sprom_r1234589(sprom, prefix); ++		bcm47xx_fill_sprom_r4589(sprom, prefix); ++		bcm47xx_fill_sprom_r458(sprom, prefix); ++		bcm47xx_fill_sprom_r45(sprom, prefix); ++		bcm47xx_fill_sprom_path_r4589(sprom, prefix); ++		bcm47xx_fill_sprom_path_r45(sprom, prefix); ++		break; ++	case 8: ++		bcm47xx_fill_sprom_r1234589(sprom, prefix); ++		bcm47xx_fill_sprom_r12389(sprom, prefix); ++		bcm47xx_fill_sprom_r2389(sprom, prefix); ++		bcm47xx_fill_sprom_r389(sprom, prefix); ++		bcm47xx_fill_sprom_r4589(sprom, prefix); ++		bcm47xx_fill_sprom_r458(sprom, prefix); ++		bcm47xx_fill_sprom_r89(sprom, prefix); ++		bcm47xx_fill_sprom_path_r4589(sprom, prefix); ++		break; ++	case 9: ++		bcm47xx_fill_sprom_r1234589(sprom, prefix); ++		bcm47xx_fill_sprom_r12389(sprom, prefix); ++		bcm47xx_fill_sprom_r2389(sprom, prefix); ++		bcm47xx_fill_sprom_r389(sprom, prefix); ++		bcm47xx_fill_sprom_r4589(sprom, prefix); ++		bcm47xx_fill_sprom_r89(sprom, prefix); ++		bcm47xx_fill_sprom_r9(sprom, prefix); ++		bcm47xx_fill_sprom_path_r4589(sprom, prefix); ++		break; ++	default: ++		pr_warn("Unsupported SPROM revision %d detected. Will extract" ++			" v1\n", sprom->revision); ++		sprom->revision = 1; ++		bcm47xx_fill_sprom_r1(sprom, prefix); ++	} ++} +--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h ++++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +@@ -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 */ diff --git a/target/linux/brcm47xx/patches-3.2/199-MIPS-BCM47XX-provide-sprom-to-bcma-bus.patch b/target/linux/brcm47xx/patches-3.2/199-MIPS-BCM47XX-provide-sprom-to-bcma-bus.patch new file mode 100644 index 000000000..e3d252792 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/199-MIPS-BCM47XX-provide-sprom-to-bcma-bus.patch @@ -0,0 +1,94 @@ +From 112b2e12edda60f495b57e8a1d85eb95e2662845 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Thu, 16 Feb 2012 23:44:26 +0100 +Subject: [PATCH 199/202] MIPS: BCM47XX: provide sprom to bcma bus + +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. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + arch/mips/bcm47xx/setup.c |   39 +++++++++++++++++++++++++++++++++++---- + 1 files changed, 35 insertions(+), 4 deletions(-) + +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -3,7 +3,7 @@ +  *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> +  *  Copyright (C) 2006 Michael Buesch <m@bues.ch> +  *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> +- *  Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de> ++ *  Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> +  * +  *  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 +@@ -91,7 +91,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]; +  +@@ -108,7 +108,7 @@ static int bcm47xx_get_sprom(struct ssb_ + } +  + static int bcm47xx_get_invariants(struct ssb_bus *bus, +-				   struct ssb_init_invariants *iv) ++				  struct ssb_init_invariants *iv) + { + 	char buf[20]; +  +@@ -163,7 +163,7 @@ static void __init bcm47xx_register_ssb( + 	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); +@@ -197,10 +197,41 @@ static void __init bcm47xx_register_ssb( + #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; ++ ++	if (bus->hosttype == 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; ++	} else if (bus->hosttype == 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; ++	} else { ++		printk(KERN_WARNING "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) ++		printk(KERN_WARNING "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)\n", err); diff --git a/target/linux/brcm47xx/patches-3.2/400-arch-bcm47xx.patch b/target/linux/brcm47xx/patches-3.2/400-arch-bcm47xx.patch index 5dd7fd771..5412aa61e 100644 --- a/target/linux/brcm47xx/patches-3.2/400-arch-bcm47xx.patch +++ b/target/linux/brcm47xx/patches-3.2/400-arch-bcm47xx.patch @@ -1,6 +1,6 @@  --- a/arch/mips/bcm47xx/nvram.c  +++ b/arch/mips/bcm47xx/nvram.c -@@ -199,3 +199,30 @@ int nvram_getenv(char *name, char *val, +@@ -198,3 +198,30 @@ int nvram_getenv(char *name, char *val,   	return NVRAM_ERR_ENVNOTFOUND;   }   EXPORT_SYMBOL(nvram_getenv); @@ -33,7 +33,7 @@  +EXPORT_SYMBOL(nvram_get);  --- a/arch/mips/bcm47xx/setup.c  +++ b/arch/mips/bcm47xx/setup.c -@@ -469,3 +469,20 @@ static int __init bcm47xx_register_flash +@@ -351,3 +351,20 @@ static int __init bcm47xx_register_flash   	return -1;   }   fs_initcall(bcm47xx_register_flash); diff --git a/target/linux/brcm47xx/patches-3.2/812-disable_wgt634u_crap.patch b/target/linux/brcm47xx/patches-3.2/812-disable_wgt634u_crap.patch index 6bc34549f..a71e6bdf3 100644 --- a/target/linux/brcm47xx/patches-3.2/812-disable_wgt634u_crap.patch +++ b/target/linux/brcm47xx/patches-3.2/812-disable_wgt634u_crap.patch @@ -3,7 +3,7 @@  @@ -4,4 +4,3 @@   # - obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o + obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o sprom.o  -obj-$(CONFIG_BCM47XX_SSB)	+= wgt634u.o  --- a/arch/mips/bcm47xx/wgt634u.c  +++ /dev/null diff --git a/target/linux/brcm47xx/patches-3.2/820-wgt634u-nvram-fix.patch b/target/linux/brcm47xx/patches-3.2/820-wgt634u-nvram-fix.patch index 88a40e2bc..3ccaa9557 100644 --- a/target/linux/brcm47xx/patches-3.2/820-wgt634u-nvram-fix.patch +++ b/target/linux/brcm47xx/patches-3.2/820-wgt634u-nvram-fix.patch @@ -9,8 +9,8 @@ out the configuration than the in kernel cfe config reader.   # under Linux.   # --obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o -+obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o cfe_env.o +-obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o sprom.o ++obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o sprom.o cfe_env.o  --- /dev/null  +++ b/arch/mips/bcm47xx/cfe_env.c  @@ -0,0 +1,229 @@ @@ -293,7 +293,7 @@ out the configuration than the in kernel cfe config reader.   	/* Look for name=value and return value */   	var = &nvram_buf[sizeof(struct nvram_header)];   	end = nvram_buf + sizeof(nvram_buf) - 2; -@@ -210,6 +237,9 @@ char *nvram_get(const char *name) +@@ -209,6 +236,9 @@ char *nvram_get(const char *name)   	if (!nvram_buf[0])   		early_nvram_init(); diff --git a/target/linux/brcm47xx/patches-3.2/980-wnr834b_no_cardbus_invariant.patch b/target/linux/brcm47xx/patches-3.2/980-wnr834b_no_cardbus_invariant.patch index 2207a5ced..14ac90eff 100644 --- a/target/linux/brcm47xx/patches-3.2/980-wnr834b_no_cardbus_invariant.patch +++ b/target/linux/brcm47xx/patches-3.2/980-wnr834b_no_cardbus_invariant.patch @@ -1,6 +1,6 @@  --- a/arch/mips/bcm47xx/setup.c  +++ b/arch/mips/bcm47xx/setup.c -@@ -278,6 +278,10 @@ static int bcm47xx_get_invariants(struct +@@ -129,6 +129,10 @@ static int bcm47xx_get_invariants(struct   	if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)   		iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);  | 
