From 095f695cbb07281682462da0618fffabb499d0be Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 19 Aug 2008 12:50:31 -0500 Subject: ssb: Update for Rev. 5 SPROM Although a revision 5 SPROM has not been seen in the wild, the open-source portion of the MIPS driver 4.150.10.5 describes its layout, which is mostly inherited from revision 4. This patch implements the differences. Signed-off-by: Larry Finger Acked-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) (limited to 'drivers/ssb/pci.c') diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index f883dcfffe0..0de4b5e0450 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -399,14 +399,19 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) out->antenna_gain.ghz5.a3 = gain; } -static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) +static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) { int i; u16 v; + u16 il0mac_offset; + if (out->revision == 4) + il0mac_offset = SSB_SPROM4_IL0MAC; + else + il0mac_offset = SSB_SPROM5_IL0MAC; /* extract the equivalent of the r1 variables */ for (i = 0; i < 3; i++) { - v = in[SPOFF(SSB_SPROM4_IL0MAC) + i]; + v = in[SPOFF(il0mac_offset) + i]; *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); } for (i = 0; i < 3; i++) { @@ -420,9 +425,15 @@ static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, SSB_SPROM4_ETHPHY_ET1A_SHIFT); - SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); - SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); - SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); + if (out->revision == 4) { + SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); + SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); + SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); + } else { + SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0); + SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); + SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); + } SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, SSB_SPROM4_ANTAVAIL_A_SHIFT); SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG, @@ -433,12 +444,21 @@ static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0); SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A, SSB_SPROM4_ITSSI_A_SHIFT); - SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0); - SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1, - SSB_SPROM4_GPIOA_P1_SHIFT); - SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); - SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, - SSB_SPROM4_GPIOB_P3_SHIFT); + if (out->revision == 4) { + SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0); + SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1, + SSB_SPROM4_GPIOA_P1_SHIFT); + SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); + SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, + SSB_SPROM4_GPIOB_P3_SHIFT); + } else { + SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0); + SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1, + SSB_SPROM5_GPIOA_P1_SHIFT); + SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0); + SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3, + SSB_SPROM5_GPIOB_P3_SHIFT); + } /* Extract the antenna gain values. */ SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, @@ -471,16 +491,16 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, } else if (bus->chip_id == 0x4321) { /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */ out->revision = 4; - sprom_extract_r4(out, in); + sprom_extract_r45(out, in); } else { if (out->revision == 0) goto unsupported; if (out->revision >= 1 && out->revision <= 3) { sprom_extract_r123(out, in); } - if (out->revision == 4) - sprom_extract_r4(out, in); - if (out->revision >= 5) + if (out->revision == 4 || out->revision == 5) + sprom_extract_r45(out, in); + if (out->revision > 5) goto unsupported; } -- cgit v1.2.3 From 31ce12fb3ebf88b054deb99ad729e84888bf6125 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 20 Aug 2008 17:45:06 -0500 Subject: ssb: Clean up extraction of MAC addresses from SPROM Only rev 1 and 2 ssb SPROMs have fields named et0mac and et1mac; however, all of the extraction routines extract pseudo data for these fields from regions that are all 1's resulting in a hardware address of FF:FF:FF:FF:FF:FF. This patch forces such a fill at the beginning of the data extraction process, and only does the formal extraction if the SPROM rev is 1 or 2. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'drivers/ssb/pci.c') diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 0de4b5e0450..d5cde051806 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -327,11 +327,9 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) s8 gain; u16 loc[3]; - if (out->revision == 3) { /* rev 3 moved MAC */ + if (out->revision == 3) /* rev 3 moved MAC */ loc[0] = SSB_SPROM3_IL0MAC; - loc[1] = SSB_SPROM3_ET0MAC; - loc[2] = SSB_SPROM3_ET1MAC; - } else { + else { loc[0] = SSB_SPROM1_IL0MAC; loc[1] = SSB_SPROM1_ET0MAC; loc[2] = SSB_SPROM1_ET1MAC; @@ -340,13 +338,15 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) v = in[SPOFF(loc[0]) + i]; *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); } - for (i = 0; i < 3; i++) { - v = in[SPOFF(loc[1]) + i]; - *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); - } - for (i = 0; i < 3; i++) { - v = in[SPOFF(loc[2]) + i]; - *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); + if (out->revision < 3) { /* only rev 1-2 have et0, et1 */ + for (i = 0; i < 3; i++) { + v = in[SPOFF(loc[1]) + i]; + *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); + } + for (i = 0; i < 3; i++) { + v = in[SPOFF(loc[2]) + i]; + *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); + } } SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, @@ -409,19 +409,11 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) il0mac_offset = SSB_SPROM4_IL0MAC; else il0mac_offset = SSB_SPROM5_IL0MAC; - /* extract the equivalent of the r1 variables */ + /* extract the MAC address */ for (i = 0; i < 3; i++) { v = in[SPOFF(il0mac_offset) + i]; *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); } - for (i = 0; i < 3; i++) { - v = in[SPOFF(SSB_SPROM4_ET0MAC) + i]; - *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); - } - for (i = 0; i < 3; i++) { - v = in[SPOFF(SSB_SPROM4_ET1MAC) + i]; - *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); - } SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, SSB_SPROM4_ETHPHY_ET1A_SHIFT); @@ -482,6 +474,8 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, out->revision = in[size - 1] & 0x00FF; ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); + memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ + memset(out->et1mac, 0xFF, 6); if ((bus->chip_id & 0xFF00) == 0x4400) { /* Workaround: The BCM44XX chip has a stupid revision * number stored in the SPROM. -- cgit v1.2.3