2012-02-19 18:33:02

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 00/11] 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.

Hauke Mehrtens (11):
ssb: sprom fix some sizes / signedness
ssb: remove 5GHz antenna gain from sprom
ssb: fix per path sprom vars
ssb: add ccode
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 | 618 ++++++++++++++++++++++++++
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 | 75 +++-
drivers/net/wireless/b43legacy/phy.c | 2 +-
drivers/ssb/pci.c | 40 +--
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, 844 insertions(+), 225 deletions(-)
create mode 100644 arch/mips/bcm47xx/sprom.c

--
1.7.5.4



2012-02-19 18:33:16

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 02/11] ssb: remove 5GHz antenna gain from sprom

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.

Signed-off-by: Hauke Mehrtens <[email protected]>
---
drivers/net/wireless/b43legacy/phy.c | 2 +-
drivers/ssb/pci.c | 40 ++++++++++++----------------------
drivers/ssb/pcmcia.c | 12 +++------
drivers/ssb/sdio.c | 12 +++------
include/linux/ssb/ssb.h | 7 +-----
5 files changed, 24 insertions(+), 49 deletions(-)

diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index 96faaef..9503341 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -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
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index befa89e..9d8e39d 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -390,20 +390,12 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);

/* Extract the antenna gain values. */
- gain = r123_extract_antgain(out->revision, in,
- SSB_SPROM1_AGAIN_BG,
- SSB_SPROM1_AGAIN_BG_SHIFT);
- out->antenna_gain.ghz24.a0 = gain;
- out->antenna_gain.ghz24.a1 = gain;
- out->antenna_gain.ghz24.a2 = gain;
- out->antenna_gain.ghz24.a3 = gain;
- gain = r123_extract_antgain(out->revision, in,
- SSB_SPROM1_AGAIN_A,
- SSB_SPROM1_AGAIN_A_SHIFT);
- out->antenna_gain.ghz5.a0 = gain;
- out->antenna_gain.ghz5.a1 = gain;
- out->antenna_gain.ghz5.a2 = gain;
- out->antenna_gain.ghz5.a3 = gain;
+ out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
+ SSB_SPROM1_AGAIN_BG,
+ SSB_SPROM1_AGAIN_BG_SHIFT);
+ out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
+ SSB_SPROM1_AGAIN_A,
+ SSB_SPROM1_AGAIN_A_SHIFT);
}

/* Revs 4 5 and 8 have partially shared layout */
@@ -504,16 +496,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
}

/* Extract the antenna gain values. */
- SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
+ SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
- SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
+ SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
- SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
+ SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
- SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
+ SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
- memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
- sizeof(out->antenna_gain.ghz5));

sprom_extract_r458(out, in);

@@ -602,16 +592,14 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);

/* Extract the antenna gain values. */
- SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
+ SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
- SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
+ SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
- SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
+ SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
- SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
+ SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
- memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
- sizeof(out->antenna_gain.ghz5));

/* Extract cores power info info */
for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index c821c6b..fbafed5 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -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) &&
diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c
index 63fd709..b2d36f7 100644
--- a/drivers/ssb/sdio.c
+++ b/drivers/ssb/sdio.c
@@ -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) &&
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index f169621..1de5675 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -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 {
--
1.7.5.4


2012-02-19 20:02:07

by Hauke Mehrtens

[permalink] [raw]
Subject: Re: [PATCH 04/11] ssb: add ccode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/19/2012 08:50 PM, Michael B?sch wrote:
> On Sun, 19 Feb 2012 20:28:35 +0100 Hauke Mehrtens
> <[email protected]> wrote:
>>>> u8 country_code; /* Country Code */ + char ccode[2]; /*
>>>> Country Code as two chars like EU or US */
>>>
>>> This usually is referred to as "alpha2". So we should name it
>>> like that, too.
>> I can not find any references to "alpha2" in the spec
>
> http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
>
OK, I will rename it.

Hauke
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJPQVUWAAoJEIZ0px9YPRMyiJgP/i8PzgoVBhlPcUwdDwigbDVw
oUcRWdLs6Elo1cvfao0Txu3ntB02bT7wKn262AYgRUUPerp2CmvF9jEXziSLFV5L
/GEzkm2+yyM+dYNatL+6De9qNZGdzzJNR4lHZ/7aAFzE/0PY9Pg5OvY8cZdJDPb5
jQK97Vjdd1mfpFYpEJYUw24JOa/fF4+Ve/yHSjSJ3djf60h7i2GVWf/QBlQXNRc5
TEKb95wQUwXmGDjgkO41ZtmtN0XA506FzU5uy6kLFKTuiWM6EDcKQWhlfw+S90pR
7PpbyAvzLyZKpiOutV9SHgW0eimhFmEo9H7f3bwkBLDjkJKmEKrK3pqZ3pz8VQdK
JfOijxPnd91UAPUkIvDv7aFgrAt+HCYYq5T6KFsLvk4kLLX36Sgoxe3f+htBd2Mj
+as0i2xFBWniifAnPA1oWRGJsNvDAFDuix8XSaNqkz9RxCEZ+35KE4jw9rsqUwKJ
vYPmKZsen9YmI72N82eT/nww31Ppkc4p9JdvHn8qsa3G/QjA/fYm3r7ymOrOcA4o
Wb1MBx9584jukks1/HgVueUf77rj0q5A99bvuMuKpwrvtX0HlWBUdvG90oUJl5wL
cF0almhAj2oB4DfHaaAseFlq52WRF2VSXS296VZ8k7EZfnFELxtHrDXC7ku9jaut
92sDSHze8ron+1PmclEm
=BIVY
-----END PGP SIGNATURE-----

2012-02-19 18:34:14

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 11/11] 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 <[email protected]>
---
arch/mips/bcm47xx/setup.c | 39 +++++++++++++++++++++++++++++++++++----
1 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 6b0dacd..6f8b073 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -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;
+
+ 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)", err);
--
1.7.5.4


2012-02-19 19:50:42

by Michael Büsch

[permalink] [raw]
Subject: Re: [PATCH 04/11] ssb: add ccode

On Sun, 19 Feb 2012 20:28:35 +0100
Hauke Mehrtens <[email protected]> wrote:
> >> u8 country_code; /* Country Code */
> >> + char ccode[2]; /* Country Code as two chars like EU or US */
> >
> > This usually is referred to as "alpha2". So we should name it like that, too.
> I can not find any references to "alpha2" in the spec

http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2

--
Greetings, Michael.


Attachments:
signature.asc (836.00 B)

2012-02-23 21:27:47

by Hauke Mehrtens

[permalink] [raw]
Subject: Re: [PATCH 01/11] ssb: sprom fix some sizes / signedness

On 02/23/2012 07:14 PM, Rafał Miłecki wrote:
> 2012/2/19 Hauke Mehrtens <[email protected]>:
>> @@ -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 */
>
> Just a note in case you're going to develop ssb/bcma/b43/brcm code.
> Please note we're trying to switch from properties you modified to
> struct ssb_sprom_core_pwr_info.
These vars are available in sprom 1-3,8,9 and the ones in struct
ssb_sprom_core_pwr_info just for sprom 4,5,8,9. The old are probably not
used by newer chips any more. I just found these because I generated my
parsing code from broadcom open source code and got a compiler warning
because of wrong sizes.
>
> The patch still looks fine.
>


2012-02-19 22:16:46

by Gábor Stefanik

[permalink] [raw]
Subject: Re: [PATCH 05/11] ssb: add some missing sprom attributes

On Sun, Feb 19, 2012 at 7:32 PM, Hauke Mehrtens <[email protected]> wrote:
> 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.

Typo.

>
> Signed-off-by: Hauke Mehrtens <[email protected]>
> ---
> ?include/linux/ssb/ssb.h | ? 76 ++++++++++++++++++++++++++++++++++++++++++++++-
> ?1 files changed, 75 insertions(+), 1 deletions(-)
>
> diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
> index 44e486e..992c47a 100644
> --- 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; ? ? ? ? ?/* Board number number from SPROM. */

Please remove the repeated repeated word.

> + ? ? ? u16 board_type; ? ? ? ? /* Board type number from SPROM. */
> ? ? ? ?u8 country_code; ? ? ? ?/* Country Code */
> ? ? ? ?char ccode[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. */
> --
> 1.7.5.4
>
>
> _______________________________________________
> b43-dev mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/b43-dev



--
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)

2012-02-19 18:34:17

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 10/11] 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 <[email protected]>
---
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

diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile
index 4add173..4389de1 100644
--- 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
+obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index aab6b0c..6b0dacd 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -85,156 +85,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];

diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c
new file mode 100644
index 0000000..396f064
--- /dev/null
+++ b/arch/mips/bcm47xx/sprom.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (C) 2004 Florian Schirmer <[email protected]>
+ * Copyright (C) 2006 Felix Fietkau <[email protected]>
+ * Copyright (C) 2006 Michael Buesch <[email protected]>
+ * Copyright (C) 2010 Waldemar Brodkorb <[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
+ * 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_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0);
+ nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.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_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0);
+ nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.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);
+ }
+}
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
index de95e07..5ecaf47 100644
--- 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 */
--
1.7.5.4


2012-02-19 18:33:58

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 08/11] MIPS: BCM47XX: return number of written bytes in nvram_getenv


Signed-off-by: Hauke Mehrtens <[email protected]>
---
arch/mips/bcm47xx/nvram.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index a84e3bb..d43ceff 100644
--- a/arch/mips/bcm47xx/nvram.c
+++ b/arch/mips/bcm47xx/nvram.c
@@ -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;
--
1.7.5.4


2012-02-19 18:33:03

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 01/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 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.

Signed-off-by: Hauke Mehrtens <[email protected]>
---
include/linux/ssb/ssb.h | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index bbc2612..f169621 100644
--- 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;
--
1.7.5.4


2012-02-19 18:33:30

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 04/11] ssb: add ccode

This member contains the country code encoded with two chars

Signed-off-by: Hauke Mehrtens <[email protected]>
---
include/linux/ssb/ssb.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 4928419..44e486e 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -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 ccode[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) */
--
1.7.5.4


2012-02-20 11:10:12

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 11/11] MIPS: BCM47XX: provide sprom to bcma bus

Hello.

On 19-02-2012 22:32, Hauke Mehrtens wrote:

> 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<[email protected]>
> ---
> arch/mips/bcm47xx/setup.c | 39 +++++++++++++++++++++++++++++++++++----
> 1 files changed, 35 insertions(+), 4 deletions(-)

> diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
> index 6b0dacd..6f8b073 100644
> --- a/arch/mips/bcm47xx/setup.c
> +++ b/arch/mips/bcm47xx/setup.c
[...]
> @@ -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;
> +
> + if (bus->hosttype == BCMA_HOSTTYPE_PCI) {

Why not *switch* statement? It seems more natural in this situation...

> + 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"

pr_warn(). And don't break the message to help grepping.

> + " a bcma SPROM callback handler (err %d)\n", err);
> +

WBR, Sergei

2012-02-19 18:33:44

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 06/11] 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 <[email protected]>
---
drivers/bcma/main.c | 3 ++-
include/linux/bcma/bcma.h | 1 +
2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index b8379b9..7e138ec 100644
--- 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_core(struct bcma_bus *bus, u16 coreid)
}
return NULL;
}
+EXPORT_SYMBOL_GPL(bcma_find_core);

static void bcma_release_core_dev(struct device *dev)
{
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index b9f65fb..46bbd08 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -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);
--
1.7.5.4


2012-02-19 19:28:54

by Hauke Mehrtens

[permalink] [raw]
Subject: Re: [PATCH 04/11] ssb: add ccode

On 02/19/2012 07:49 PM, Michael B?sch wrote:
> On Sun, 19 Feb 2012 19:32:18 +0100
> Hauke Mehrtens <[email protected]> wrote:
>
>> This member contains the country code encoded with two chars
>>
>> Signed-off-by: Hauke Mehrtens <[email protected]>
>> ---
>> include/linux/ssb/ssb.h | 1 +
>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>
>> diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
>> index 4928419..44e486e 100644
>> --- a/include/linux/ssb/ssb.h
>> +++ b/include/linux/ssb/ssb.h
>> @@ -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 ccode[2]; /* Country Code as two chars like EU or US */
>
> This usually is referred to as "alpha2". So we should name it like that, too.
I can not find any references to "alpha2" in the spec, the broadcom
code, ssb, bcma or b43. ccode was the name broadcom gave this value so I
took it.
http://bcm-v4.sipsolutions.net/SPROM wrongly maps ccode to country_code,
but cc is stored into country_code in ssb.

Hauke

2012-02-19 18:33:16

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 03/11] 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 <[email protected]>
---
include/linux/ssb/ssb.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 1de5675..4928419 100644
--- 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 {
--
1.7.5.4


2012-02-19 19:17:43

by Hauke Mehrtens

[permalink] [raw]
Subject: Re: [PATCH 02/11] ssb: remove 5GHz antenna gain from sprom

On 02/19/2012 08:14 PM, Larry Finger wrote:
> On 02/19/2012 12:32 PM, Hauke Mehrtens wrote:
>> 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.
>>
>> Signed-off-by: Hauke Mehrtens<[email protected]>
>> ---
>> drivers/net/wireless/b43legacy/phy.c | 2 +-
>> drivers/ssb/pci.c | 40
>> ++++++++++++----------------------
>> drivers/ssb/pcmcia.c | 12 +++------
>> drivers/ssb/sdio.c | 12 +++------
>> include/linux/ssb/ssb.h | 7 +-----
>> 5 files changed, 24 insertions(+), 49 deletions(-)
>
> After this patch, I get the warning
>
> drivers/ssb/pci.c: In function ?sprom_extract_r123?:
> drivers/ssb/pci.c:334:5: warning: unused variable ?gain?
> [-Wunused-variable]
>
> I am still testing, but all other patches compile OK.

Thanks for the info, I haven't see it. I will fix it in the next round.

Hauke


2012-02-21 19:46:55

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 00/11] ssb/bcma/BCM47XX: sprom fixes and extensions

Has Ralf seen the arch/mips patches?

On Sun, Feb 19, 2012 at 07:32:14PM +0100, Hauke Mehrtens wrote:
> 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.
>
> Hauke Mehrtens (11):
> ssb: sprom fix some sizes / signedness
> ssb: remove 5GHz antenna gain from sprom
> ssb: fix per path sprom vars
> ssb: add ccode
> 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 | 618 ++++++++++++++++++++++++++
> 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 | 75 +++-
> drivers/net/wireless/b43legacy/phy.c | 2 +-
> drivers/ssb/pci.c | 40 +--
> 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, 844 insertions(+), 225 deletions(-)
> create mode 100644 arch/mips/bcm47xx/sprom.c
>
> --
> 1.7.5.4
>
>

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2012-02-19 18:33:31

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 05/11] 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 <[email protected]>
---
include/linux/ssb/ssb.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 75 insertions(+), 1 deletions(-)

diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 44e486e..992c47a 100644
--- 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; /* Board number number from SPROM. */
+ u16 board_type; /* Board type number from SPROM. */
u8 country_code; /* Country Code */
char ccode[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. */
--
1.7.5.4


2012-02-19 18:33:59

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 09/11] 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 <[email protected]>
---
arch/mips/include/asm/mach-bcm47xx/nvram.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h
index 184d5ec..69ef3ef 100644
--- 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],
--
1.7.5.4


2012-02-19 19:14:12

by Larry Finger

[permalink] [raw]
Subject: Re: [PATCH 02/11] ssb: remove 5GHz antenna gain from sprom

On 02/19/2012 12:32 PM, Hauke Mehrtens wrote:
> 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.
>
> Signed-off-by: Hauke Mehrtens<[email protected]>
> ---
> drivers/net/wireless/b43legacy/phy.c | 2 +-
> drivers/ssb/pci.c | 40 ++++++++++++----------------------
> drivers/ssb/pcmcia.c | 12 +++------
> drivers/ssb/sdio.c | 12 +++------
> include/linux/ssb/ssb.h | 7 +-----
> 5 files changed, 24 insertions(+), 49 deletions(-)

After this patch, I get the warning

drivers/ssb/pci.c: In function ?sprom_extract_r123?:
drivers/ssb/pci.c:334:5: warning: unused variable ?gain? [-Wunused-variable]

I am still testing, but all other patches compile OK.

Larry

2012-02-23 18:14:18

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 01/11] ssb: sprom fix some sizes / signedness

2012/2/19 Hauke Mehrtens <[email protected]>:
> @@ -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 */

Just a note in case you're going to develop ssb/bcma/b43/brcm code.
Please note we're trying to switch from properties you modified to
struct ssb_sprom_core_pwr_info.

The patch still looks fine.

--
Rafał

2012-02-19 18:49:53

by Michael Büsch

[permalink] [raw]
Subject: Re: [PATCH 04/11] ssb: add ccode

On Sun, 19 Feb 2012 19:32:18 +0100
Hauke Mehrtens <[email protected]> wrote:

> This member contains the country code encoded with two chars
>
> Signed-off-by: Hauke Mehrtens <[email protected]>
> ---
> include/linux/ssb/ssb.h | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
> index 4928419..44e486e 100644
> --- a/include/linux/ssb/ssb.h
> +++ b/include/linux/ssb/ssb.h
> @@ -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 ccode[2]; /* Country Code as two chars like EU or US */

This usually is referred to as "alpha2". So we should name it like that, too.

> 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) */



--
Greetings, Michael.

2012-02-21 19:52:40

by Hauke Mehrtens

[permalink] [raw]
Subject: Re: [PATCH 00/11] ssb/bcma/BCM47XX: sprom fixes and extensions

On 02/21/2012 08:37 PM, John W. Linville wrote:
> Has Ralf seen the arch/mips patches?
>
I just send it to the mips list, I will send v2 of the patches
explicitly to him and ask him.

> On Sun, Feb 19, 2012 at 07:32:14PM +0100, Hauke Mehrtens wrote:
>> 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.
>>
>> Hauke Mehrtens (11):
>> ssb: sprom fix some sizes / signedness
>> ssb: remove 5GHz antenna gain from sprom
>> ssb: fix per path sprom vars
>> ssb: add ccode
>> 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 | 618 ++++++++++++++++++++++++++
>> 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 | 75 +++-
>> drivers/net/wireless/b43legacy/phy.c | 2 +-
>> drivers/ssb/pci.c | 40 +--
>> 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, 844 insertions(+), 225 deletions(-)
>> create mode 100644 arch/mips/bcm47xx/sprom.c
>>
>> --
>> 1.7.5.4
>>
>>
>


2012-02-19 18:33:46

by Hauke Mehrtens

[permalink] [raw]
Subject: [PATCH 07/11] 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 <[email protected]>
---
drivers/bcma/sprom.c | 75 ++++++++++++++++++++++++++++++++++++++++-----
include/linux/bcma/bcma.h | 6 +++
2 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index ca77525..73c204d 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -14,6 +14,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 +285,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),
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 46bbd08..5af9a07 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -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;
--
1.7.5.4