kernel: ssb/bcma: update to version from wireless-testing tag master-2012-05-16-2
[openwrt.git] / target / linux / generic / patches-2.6.39 / 020-ssb_update.patch
1 --- a/drivers/ssb/b43_pci_bridge.c
2 +++ b/drivers/ssb/b43_pci_bridge.c
3 @@ -5,12 +5,13 @@
4   * because of its small size we include it in the SSB core
5   * instead of creating a standalone module.
6   *
7 - * Copyright 2007  Michael Buesch <mb@bu3sch.de>
8 + * Copyright 2007  Michael Buesch <m@bues.ch>
9   *
10   * Licensed under the GNU/GPL. See COPYING for details.
11   */
12  
13  #include <linux/pci.h>
14 +#include <linux/module.h>
15  #include <linux/ssb/ssb.h>
16  
17  #include "ssb_private.h"
18 @@ -28,6 +29,8 @@ static const struct pci_device_id b43_pc
19         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
20         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
21         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
22 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4322) },
23 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43222) },
24         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) },
25         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) },
26         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) },
27 --- a/drivers/ssb/driver_chipcommon.c
28 +++ b/drivers/ssb/driver_chipcommon.c
29 @@ -3,7 +3,7 @@
30   * Broadcom ChipCommon core driver
31   *
32   * Copyright 2005, Broadcom Corporation
33 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
34 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
35   *
36   * Licensed under the GNU/GPL. See COPYING for details.
37   */
38 @@ -46,40 +46,66 @@ void ssb_chipco_set_clockmode(struct ssb
39         if (!ccdev)
40                 return;
41         bus = ccdev->bus;
42 +
43 +       /* We support SLOW only on 6..9 */
44 +       if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)
45 +               mode = SSB_CLKMODE_DYNAMIC;
46 +
47 +       if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
48 +               return; /* PMU controls clockmode, separated function needed */
49 +       SSB_WARN_ON(ccdev->id.revision >= 20);
50 +
51         /* chipcommon cores prior to rev6 don't support dynamic clock control */
52         if (ccdev->id.revision < 6)
53                 return;
54 -       /* chipcommon cores rev10 are a whole new ball game */
55 +
56 +       /* ChipCommon cores rev10+ need testing */
57         if (ccdev->id.revision >= 10)
58                 return;
59 +
60         if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
61                 return;
62  
63         switch (mode) {
64 -       case SSB_CLKMODE_SLOW:
65 +       case SSB_CLKMODE_SLOW: /* For revs 6..9 only */
66                 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
67                 tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
68                 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
69                 break;
70         case SSB_CLKMODE_FAST:
71 -               ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
72 -               tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
73 -               tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
74 -               tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
75 -               chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
76 +               if (ccdev->id.revision < 10) {
77 +                       ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
78 +                       tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
79 +                       tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
80 +                       tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
81 +                       chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
82 +               } else {
83 +                       chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
84 +                               (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |
85 +                                SSB_CHIPCO_SYSCLKCTL_FORCEHT));
86 +                       /* udelay(150); TODO: not available in early init */
87 +               }
88                 break;
89         case SSB_CLKMODE_DYNAMIC:
90 -               tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
91 -               tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
92 -               tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
93 -               tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
94 -               if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
95 -                       tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
96 -               chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
97 -
98 -               /* for dynamic control, we have to release our xtal_pu "force on" */
99 -               if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
100 -                       ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
101 +               if (ccdev->id.revision < 10) {
102 +                       tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
103 +                       tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
104 +                       tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
105 +                       tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
106 +                       if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=
107 +                           SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
108 +                               tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
109 +                       chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
110 +
111 +                       /* For dynamic control, we have to release our xtal_pu
112 +                        * "force on" */
113 +                       if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
114 +                               ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
115 +               } else {
116 +                       chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
117 +                               (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
118 +                                ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));
119 +               }
120                 break;
121         default:
122                 SSB_WARN_ON(1);
123 @@ -260,6 +286,12 @@ void ssb_chipcommon_init(struct ssb_chip
124         if (cc->dev->id.revision >= 11)
125                 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
126         ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
127 +
128 +       if (cc->dev->id.revision >= 20) {
129 +               chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);
130 +               chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0);
131 +       }
132 +
133         ssb_pmu_init(cc);
134         chipco_powercontrol_init(cc);
135         ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
136 --- a/drivers/ssb/driver_chipcommon_pmu.c
137 +++ b/drivers/ssb/driver_chipcommon_pmu.c
138 @@ -2,7 +2,7 @@
139   * Sonics Silicon Backplane
140   * Broadcom ChipCommon Power Management Unit driver
141   *
142 - * Copyright 2009, Michael Buesch <mb@bu3sch.de>
143 + * Copyright 2009, Michael Buesch <m@bues.ch>
144   * Copyright 2007, Broadcom Corporation
145   *
146   * Licensed under the GNU/GPL. See COPYING for details.
147 @@ -12,6 +12,9 @@
148  #include <linux/ssb/ssb_regs.h>
149  #include <linux/ssb/ssb_driver_chipcommon.h>
150  #include <linux/delay.h>
151 +#ifdef CONFIG_BCM47XX
152 +#include <asm/mach-bcm47xx/nvram.h>
153 +#endif
154  
155  #include "ssb_private.h"
156  
157 @@ -91,10 +94,6 @@ static void ssb_pmu0_pllinit_r0(struct s
158         u32 pmuctl, tmp, pllctl;
159         unsigned int i;
160  
161 -       if ((bus->chip_id == 0x5354) && !crystalfreq) {
162 -               /* The 5354 crystal freq is 25MHz */
163 -               crystalfreq = 25000;
164 -       }
165         if (crystalfreq)
166                 e = pmu0_plltab_find_entry(crystalfreq);
167         if (!e)
168 @@ -320,7 +319,11 @@ static void ssb_pmu_pll_init(struct ssb_
169         u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */
170  
171         if (bus->bustype == SSB_BUSTYPE_SSB) {
172 -               /* TODO: The user may override the crystal frequency. */
173 +#ifdef CONFIG_BCM47XX
174 +               char buf[20];
175 +               if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
176 +                       crystalfreq = simple_strtoul(buf, NULL, 0);
177 +#endif
178         }
179  
180         switch (bus->chip_id) {
181 @@ -329,7 +332,11 @@ static void ssb_pmu_pll_init(struct ssb_
182                 ssb_pmu1_pllinit_r0(cc, crystalfreq);
183                 break;
184         case 0x4328:
185 +               ssb_pmu0_pllinit_r0(cc, crystalfreq);
186 +               break;
187         case 0x5354:
188 +               if (crystalfreq == 0)
189 +                       crystalfreq = 25000;
190                 ssb_pmu0_pllinit_r0(cc, crystalfreq);
191                 break;
192         case 0x4322:
193 @@ -417,12 +424,14 @@ static void ssb_pmu_resources_init(struc
194         u32 min_msk = 0, max_msk = 0;
195         unsigned int i;
196         const struct pmu_res_updown_tab_entry *updown_tab = NULL;
197 -       unsigned int updown_tab_size;
198 +       unsigned int updown_tab_size = 0;
199         const struct pmu_res_depend_tab_entry *depend_tab = NULL;
200 -       unsigned int depend_tab_size;
201 +       unsigned int depend_tab_size = 0;
202  
203         switch (bus->chip_id) {
204         case 0x4312:
205 +                min_msk = 0xCBB;
206 +                break;
207         case 0x4322:
208                 /* We keep the default settings:
209                  * min_msk = 0xCBB
210 @@ -604,3 +613,34 @@ void ssb_pmu_set_ldo_paref(struct ssb_ch
211  
212  EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
213  EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
214 +
215 +u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
216 +{
217 +       struct ssb_bus *bus = cc->dev->bus;
218 +
219 +       switch (bus->chip_id) {
220 +       case 0x5354:
221 +               /* 5354 chip uses a non programmable PLL of frequency 240MHz */
222 +               return 240000000;
223 +       default:
224 +               ssb_printk(KERN_ERR PFX
225 +                          "ERROR: PMU cpu clock unknown for device %04X\n",
226 +                          bus->chip_id);
227 +               return 0;
228 +       }
229 +}
230 +
231 +u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
232 +{
233 +       struct ssb_bus *bus = cc->dev->bus;
234 +
235 +       switch (bus->chip_id) {
236 +       case 0x5354:
237 +               return 120000000;
238 +       default:
239 +               ssb_printk(KERN_ERR PFX
240 +                          "ERROR: PMU controlclock unknown for device %04X\n",
241 +                          bus->chip_id);
242 +               return 0;
243 +       }
244 +}
245 --- a/drivers/ssb/driver_extif.c
246 +++ b/drivers/ssb/driver_extif.c
247 @@ -3,7 +3,7 @@
248   * Broadcom EXTIF core driver
249   *
250   * Copyright 2005, Broadcom Corporation
251 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
252 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
253   * Copyright 2006, 2007, Felix Fietkau <nbd@openwrt.org>
254   * Copyright 2007, Aurelien Jarno <aurelien@aurel32.net>
255   *
256 --- a/drivers/ssb/driver_gige.c
257 +++ b/drivers/ssb/driver_gige.c
258 @@ -3,7 +3,7 @@
259   * Broadcom Gigabit Ethernet core driver
260   *
261   * Copyright 2008, Broadcom Corporation
262 - * Copyright 2008, Michael Buesch <mb@bu3sch.de>
263 + * Copyright 2008, Michael Buesch <m@bues.ch>
264   *
265   * Licensed under the GNU/GPL. See COPYING for details.
266   */
267 @@ -106,8 +106,9 @@ void gige_pcicfg_write32(struct ssb_gige
268         gige_write32(dev, SSB_GIGE_PCICFG + offset, value);
269  }
270  
271 -static int ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn,
272 -                                   int reg, int size, u32 *val)
273 +static int __devinit ssb_gige_pci_read_config(struct pci_bus *bus,
274 +                                             unsigned int devfn, int reg,
275 +                                             int size, u32 *val)
276  {
277         struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
278         unsigned long flags;
279 @@ -136,8 +137,9 @@ static int ssb_gige_pci_read_config(stru
280         return PCIBIOS_SUCCESSFUL;
281  }
282  
283 -static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn,
284 -                                    int reg, int size, u32 val)
285 +static int __devinit ssb_gige_pci_write_config(struct pci_bus *bus,
286 +                                              unsigned int devfn, int reg,
287 +                                              int size, u32 val)
288  {
289         struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
290         unsigned long flags;
291 @@ -166,7 +168,8 @@ static int ssb_gige_pci_write_config(str
292         return PCIBIOS_SUCCESSFUL;
293  }
294  
295 -static int ssb_gige_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
296 +static int __devinit ssb_gige_probe(struct ssb_device *sdev,
297 +                                   const struct ssb_device_id *id)
298  {
299         struct ssb_gige *dev;
300         u32 base, tmslow, tmshigh;
301 --- a/drivers/ssb/driver_mipscore.c
302 +++ b/drivers/ssb/driver_mipscore.c
303 @@ -3,7 +3,7 @@
304   * Broadcom MIPS core driver
305   *
306   * Copyright 2005, Broadcom Corporation
307 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
308 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
309   *
310   * Licensed under the GNU/GPL. See COPYING for details.
311   */
312 @@ -208,6 +208,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *m
313         struct ssb_bus *bus = mcore->dev->bus;
314         u32 pll_type, n, m, rate = 0;
315  
316 +       if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
317 +               return ssb_pmu_get_cpu_clock(&bus->chipco);
318 +
319         if (bus->extif.dev) {
320                 ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
321         } else if (bus->chipco.dev) {
322 --- a/drivers/ssb/driver_pcicore.c
323 +++ b/drivers/ssb/driver_pcicore.c
324 @@ -3,7 +3,7 @@
325   * Broadcom PCI-core driver
326   *
327   * Copyright 2005, Broadcom Corporation
328 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
329 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
330   *
331   * Licensed under the GNU/GPL. See COPYING for details.
332   */
333 @@ -15,6 +15,11 @@
334  
335  #include "ssb_private.h"
336  
337 +static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address);
338 +static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data);
339 +static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
340 +static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
341 +                               u8 address, u16 data);
342  
343  static inline
344  u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
345 @@ -69,7 +74,7 @@ static u32 get_cfgspace_addr(struct ssb_
346         u32 tmp;
347  
348         /* We do only have one cardbus device behind the bridge. */
349 -       if (pc->cardbusmode && (dev >= 1))
350 +       if (pc->cardbusmode && (dev > 1))
351                 goto out;
352  
353         if (bus == 0) {
354 @@ -309,7 +314,7 @@ int ssb_pcicore_pcibios_map_irq(const st
355         return ssb_mips_irq(extpci_core->dev) + 2;
356  }
357  
358 -static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
359 +static void __devinit ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
360  {
361         u32 val;
362  
363 @@ -374,7 +379,7 @@ static void ssb_pcicore_init_hostmode(st
364         register_pci_controller(&ssb_pcicore_controller);
365  }
366  
367 -static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
368 +static int __devinit pcicore_is_in_hostmode(struct ssb_pcicore *pc)
369  {
370         struct ssb_bus *bus = pc->dev->bus;
371         u16 chipid_top;
372 @@ -403,25 +408,137 @@ static int pcicore_is_in_hostmode(struct
373  }
374  #endif /* CONFIG_SSB_PCICORE_HOSTMODE */
375  
376 +/**************************************************
377 + * Workarounds.
378 + **************************************************/
379 +
380 +static void __devinit ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
381 +{
382 +       u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
383 +       if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
384 +               tmp &= ~0xF000;
385 +               tmp |= (pc->dev->core_index << 12);
386 +               pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
387 +       }
388 +}
389 +
390 +static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
391 +{
392 +       return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
393 +}
394 +
395 +static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
396 +{
397 +       const u8 serdes_pll_device = 0x1D;
398 +       const u8 serdes_rx_device = 0x1F;
399 +       u16 tmp;
400 +
401 +       ssb_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
402 +                           ssb_pcicore_polarity_workaround(pc));
403 +       tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
404 +       if (tmp & 0x4000)
405 +               ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
406 +}
407 +
408 +static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
409 +{
410 +       struct ssb_device *pdev = pc->dev;
411 +       struct ssb_bus *bus = pdev->bus;
412 +       u32 tmp;
413 +
414 +       tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
415 +       tmp |= SSB_PCICORE_SBTOPCI_PREF;
416 +       tmp |= SSB_PCICORE_SBTOPCI_BURST;
417 +       pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
418 +
419 +       if (pdev->id.revision < 5) {
420 +               tmp = ssb_read32(pdev, SSB_IMCFGLO);
421 +               tmp &= ~SSB_IMCFGLO_SERTO;
422 +               tmp |= 2;
423 +               tmp &= ~SSB_IMCFGLO_REQTO;
424 +               tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
425 +               ssb_write32(pdev, SSB_IMCFGLO, tmp);
426 +               ssb_commit_settings(bus);
427 +       } else if (pdev->id.revision >= 11) {
428 +               tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
429 +               tmp |= SSB_PCICORE_SBTOPCI_MRM;
430 +               pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
431 +       }
432 +}
433 +
434 +static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
435 +{
436 +       u32 tmp;
437 +       u8 rev = pc->dev->id.revision;
438 +
439 +       if (rev == 0 || rev == 1) {
440 +               /* TLP Workaround register. */
441 +               tmp = ssb_pcie_read(pc, 0x4);
442 +               tmp |= 0x8;
443 +               ssb_pcie_write(pc, 0x4, tmp);
444 +       }
445 +       if (rev == 1) {
446 +               /* DLLP Link Control register. */
447 +               tmp = ssb_pcie_read(pc, 0x100);
448 +               tmp |= 0x40;
449 +               ssb_pcie_write(pc, 0x100, tmp);
450 +       }
451 +
452 +       if (rev == 0) {
453 +               const u8 serdes_rx_device = 0x1F;
454 +
455 +               ssb_pcie_mdio_write(pc, serdes_rx_device,
456 +                                       2 /* Timer */, 0x8128);
457 +               ssb_pcie_mdio_write(pc, serdes_rx_device,
458 +                                       6 /* CDR */, 0x0100);
459 +               ssb_pcie_mdio_write(pc, serdes_rx_device,
460 +                                       7 /* CDR BW */, 0x1466);
461 +       } else if (rev == 3 || rev == 4 || rev == 5) {
462 +               /* TODO: DLLP Power Management Threshold */
463 +               ssb_pcicore_serdes_workaround(pc);
464 +               /* TODO: ASPM */
465 +       } else if (rev == 7) {
466 +               /* TODO: No PLL down */
467 +       }
468 +
469 +       if (rev >= 6) {
470 +               /* Miscellaneous Configuration Fixup */
471 +               tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
472 +               if (!(tmp & 0x8000))
473 +                       pcicore_write16(pc, SSB_PCICORE_SPROM(5),
474 +                                       tmp | 0x8000);
475 +       }
476 +}
477  
478  /**************************************************
479   * Generic and Clientmode operation code.
480   **************************************************/
481  
482 -static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
483 +static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
484  {
485 +       struct ssb_device *pdev = pc->dev;
486 +       struct ssb_bus *bus = pdev->bus;
487 +
488 +       if (bus->bustype == SSB_BUSTYPE_PCI)
489 +               ssb_pcicore_fix_sprom_core_index(pc);
490 +
491         /* Disable PCI interrupts. */
492 -       ssb_write32(pc->dev, SSB_INTVEC, 0);
493 +       ssb_write32(pdev, SSB_INTVEC, 0);
494 +
495 +       /* Additional PCIe always once-executed workarounds */
496 +       if (pc->dev->id.coreid == SSB_DEV_PCIE) {
497 +               ssb_pcicore_serdes_workaround(pc);
498 +               /* TODO: ASPM */
499 +               /* TODO: Clock Request Update */
500 +       }
501  }
502  
503 -void ssb_pcicore_init(struct ssb_pcicore *pc)
504 +void __devinit ssb_pcicore_init(struct ssb_pcicore *pc)
505  {
506         struct ssb_device *dev = pc->dev;
507 -       struct ssb_bus *bus;
508  
509         if (!dev)
510                 return;
511 -       bus = dev->bus;
512         if (!ssb_device_is_enabled(dev))
513                 ssb_device_enable(dev, 0);
514  
515 @@ -446,11 +563,35 @@ static void ssb_pcie_write(struct ssb_pc
516         pcicore_write32(pc, 0x134, data);
517  }
518  
519 -static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
520 -                               u8 address, u16 data)
521 +static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy)
522 +{
523 +       const u16 mdio_control = 0x128;
524 +       const u16 mdio_data = 0x12C;
525 +       u32 v;
526 +       int i;
527 +
528 +       v = (1 << 30); /* Start of Transaction */
529 +       v |= (1 << 28); /* Write Transaction */
530 +       v |= (1 << 17); /* Turnaround */
531 +       v |= (0x1F << 18);
532 +       v |= (phy << 4);
533 +       pcicore_write32(pc, mdio_data, v);
534 +
535 +       udelay(10);
536 +       for (i = 0; i < 200; i++) {
537 +               v = pcicore_read32(pc, mdio_control);
538 +               if (v & 0x100 /* Trans complete */)
539 +                       break;
540 +               msleep(1);
541 +       }
542 +}
543 +
544 +static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
545  {
546         const u16 mdio_control = 0x128;
547         const u16 mdio_data = 0x12C;
548 +       int max_retries = 10;
549 +       u16 ret = 0;
550         u32 v;
551         int i;
552  
553 @@ -458,46 +599,68 @@ static void ssb_pcie_mdio_write(struct s
554         v |= 0x2; /* MDIO Clock Divisor */
555         pcicore_write32(pc, mdio_control, v);
556  
557 +       if (pc->dev->id.revision >= 10) {
558 +               max_retries = 200;
559 +               ssb_pcie_mdio_set_phy(pc, device);
560 +       }
561 +
562         v = (1 << 30); /* Start of Transaction */
563 -       v |= (1 << 28); /* Write Transaction */
564 +       v |= (1 << 29); /* Read Transaction */
565         v |= (1 << 17); /* Turnaround */
566 -       v |= (u32)device << 22;
567 +       if (pc->dev->id.revision < 10)
568 +               v |= (u32)device << 22;
569         v |= (u32)address << 18;
570 -       v |= data;
571         pcicore_write32(pc, mdio_data, v);
572         /* Wait for the device to complete the transaction */
573         udelay(10);
574 -       for (i = 0; i < 10; i++) {
575 +       for (i = 0; i < max_retries; i++) {
576                 v = pcicore_read32(pc, mdio_control);
577 -               if (v & 0x100 /* Trans complete */)
578 +               if (v & 0x100 /* Trans complete */) {
579 +                       udelay(10);
580 +                       ret = pcicore_read32(pc, mdio_data);
581                         break;
582 +               }
583                 msleep(1);
584         }
585         pcicore_write32(pc, mdio_control, 0);
586 +       return ret;
587  }
588  
589 -static void ssb_broadcast_value(struct ssb_device *dev,
590 -                               u32 address, u32 data)
591 +static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
592 +                               u8 address, u16 data)
593  {
594 -       /* This is used for both, PCI and ChipCommon core, so be careful. */
595 -       BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
596 -       BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
597 +       const u16 mdio_control = 0x128;
598 +       const u16 mdio_data = 0x12C;
599 +       int max_retries = 10;
600 +       u32 v;
601 +       int i;
602  
603 -       ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address);
604 -       ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
605 -       ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
606 -       ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
607 -}
608 +       v = 0x80; /* Enable Preamble Sequence */
609 +       v |= 0x2; /* MDIO Clock Divisor */
610 +       pcicore_write32(pc, mdio_control, v);
611  
612 -static void ssb_commit_settings(struct ssb_bus *bus)
613 -{
614 -       struct ssb_device *dev;
615 +       if (pc->dev->id.revision >= 10) {
616 +               max_retries = 200;
617 +               ssb_pcie_mdio_set_phy(pc, device);
618 +       }
619  
620 -       dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
621 -       if (WARN_ON(!dev))
622 -               return;
623 -       /* This forces an update of the cached registers. */
624 -       ssb_broadcast_value(dev, 0xFD8, 0);
625 +       v = (1 << 30); /* Start of Transaction */
626 +       v |= (1 << 28); /* Write Transaction */
627 +       v |= (1 << 17); /* Turnaround */
628 +       if (pc->dev->id.revision < 10)
629 +               v |= (u32)device << 22;
630 +       v |= (u32)address << 18;
631 +       v |= data;
632 +       pcicore_write32(pc, mdio_data, v);
633 +       /* Wait for the device to complete the transaction */
634 +       udelay(10);
635 +       for (i = 0; i < max_retries; i++) {
636 +               v = pcicore_read32(pc, mdio_control);
637 +               if (v & 0x100 /* Trans complete */)
638 +                       break;
639 +               msleep(1);
640 +       }
641 +       pcicore_write32(pc, mdio_control, 0);
642  }
643  
644  int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
645 @@ -550,48 +713,10 @@ int ssb_pcicore_dev_irqvecs_enable(struc
646         if (pc->setup_done)
647                 goto out;
648         if (pdev->id.coreid == SSB_DEV_PCI) {
649 -               tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
650 -               tmp |= SSB_PCICORE_SBTOPCI_PREF;
651 -               tmp |= SSB_PCICORE_SBTOPCI_BURST;
652 -               pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
653 -
654 -               if (pdev->id.revision < 5) {
655 -                       tmp = ssb_read32(pdev, SSB_IMCFGLO);
656 -                       tmp &= ~SSB_IMCFGLO_SERTO;
657 -                       tmp |= 2;
658 -                       tmp &= ~SSB_IMCFGLO_REQTO;
659 -                       tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
660 -                       ssb_write32(pdev, SSB_IMCFGLO, tmp);
661 -                       ssb_commit_settings(bus);
662 -               } else if (pdev->id.revision >= 11) {
663 -                       tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
664 -                       tmp |= SSB_PCICORE_SBTOPCI_MRM;
665 -                       pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
666 -               }
667 +               ssb_pcicore_pci_setup_workarounds(pc);
668         } else {
669                 WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
670 -               //TODO: Better make defines for all these magic PCIE values.
671 -               if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
672 -                       /* TLP Workaround register. */
673 -                       tmp = ssb_pcie_read(pc, 0x4);
674 -                       tmp |= 0x8;
675 -                       ssb_pcie_write(pc, 0x4, tmp);
676 -               }
677 -               if (pdev->id.revision == 0) {
678 -                       const u8 serdes_rx_device = 0x1F;
679 -
680 -                       ssb_pcie_mdio_write(pc, serdes_rx_device,
681 -                                           2 /* Timer */, 0x8128);
682 -                       ssb_pcie_mdio_write(pc, serdes_rx_device,
683 -                                           6 /* CDR */, 0x0100);
684 -                       ssb_pcie_mdio_write(pc, serdes_rx_device,
685 -                                           7 /* CDR BW */, 0x1466);
686 -               } else if (pdev->id.revision == 1) {
687 -                       /* DLLP Link Control register. */
688 -                       tmp = ssb_pcie_read(pc, 0x100);
689 -                       tmp |= 0x40;
690 -                       ssb_pcie_write(pc, 0x100, tmp);
691 -               }
692 +               ssb_pcicore_pcie_setup_workarounds(pc);
693         }
694         pc->setup_done = 1;
695  out:
696 --- a/drivers/ssb/embedded.c
697 +++ b/drivers/ssb/embedded.c
698 @@ -3,7 +3,7 @@
699   * Embedded systems support code
700   *
701   * Copyright 2005-2008, Broadcom Corporation
702 - * Copyright 2006-2008, Michael Buesch <mb@bu3sch.de>
703 + * Copyright 2006-2008, Michael Buesch <m@bues.ch>
704   *
705   * Licensed under the GNU/GPL. See COPYING for details.
706   */
707 --- a/drivers/ssb/main.c
708 +++ b/drivers/ssb/main.c
709 @@ -3,7 +3,7 @@
710   * Subsystem core
711   *
712   * Copyright 2005, Broadcom Corporation
713 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
714 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
715   *
716   * Licensed under the GNU/GPL. See COPYING for details.
717   */
718 @@ -12,6 +12,7 @@
719  
720  #include <linux/delay.h>
721  #include <linux/io.h>
722 +#include <linux/module.h>
723  #include <linux/ssb/ssb.h>
724  #include <linux/ssb/ssb_regs.h>
725  #include <linux/ssb/ssb_driver_gige.h>
726 @@ -139,19 +140,6 @@ static void ssb_device_put(struct ssb_de
727                 put_device(dev->dev);
728  }
729  
730 -static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv)
731 -{
732 -       if (drv)
733 -               get_driver(&drv->drv);
734 -       return drv;
735 -}
736 -
737 -static inline void ssb_driver_put(struct ssb_driver *drv)
738 -{
739 -       if (drv)
740 -               put_driver(&drv->drv);
741 -}
742 -
743  static int ssb_device_resume(struct device *dev)
744  {
745         struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
746 @@ -249,11 +237,9 @@ int ssb_devices_freeze(struct ssb_bus *b
747                         ssb_device_put(sdev);
748                         continue;
749                 }
750 -               sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver));
751 -               if (!sdrv || SSB_WARN_ON(!sdrv->remove)) {
752 -                       ssb_device_put(sdev);
753 +               sdrv = drv_to_ssb_drv(sdev->dev->driver);
754 +               if (SSB_WARN_ON(!sdrv->remove))
755                         continue;
756 -               }
757                 sdrv->remove(sdev);
758                 ctx->device_frozen[i] = 1;
759         }
760 @@ -292,7 +278,6 @@ int ssb_devices_thaw(struct ssb_freeze_c
761                                    dev_name(sdev->dev));
762                         result = err;
763                 }
764 -               ssb_driver_put(sdrv);
765                 ssb_device_put(sdev);
766         }
767  
768 @@ -557,7 +542,7 @@ error:
769  }
770  
771  /* Needs ssb_buses_lock() */
772 -static int ssb_attach_queued_buses(void)
773 +static int __devinit ssb_attach_queued_buses(void)
774  {
775         struct ssb_bus *bus, *n;
776         int err = 0;
777 @@ -768,9 +753,9 @@ out:
778         return err;
779  }
780  
781 -static int ssb_bus_register(struct ssb_bus *bus,
782 -                           ssb_invariants_func_t get_invariants,
783 -                           unsigned long baseaddr)
784 +static int __devinit ssb_bus_register(struct ssb_bus *bus,
785 +                                     ssb_invariants_func_t get_invariants,
786 +                                     unsigned long baseaddr)
787  {
788         int err;
789  
790 @@ -851,8 +836,8 @@ err_disable_xtal:
791  }
792  
793  #ifdef CONFIG_SSB_PCIHOST
794 -int ssb_bus_pcibus_register(struct ssb_bus *bus,
795 -                           struct pci_dev *host_pci)
796 +int __devinit ssb_bus_pcibus_register(struct ssb_bus *bus,
797 +                                     struct pci_dev *host_pci)
798  {
799         int err;
800  
801 @@ -875,9 +860,9 @@ EXPORT_SYMBOL(ssb_bus_pcibus_register);
802  #endif /* CONFIG_SSB_PCIHOST */
803  
804  #ifdef CONFIG_SSB_PCMCIAHOST
805 -int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
806 -                              struct pcmcia_device *pcmcia_dev,
807 -                              unsigned long baseaddr)
808 +int __devinit ssb_bus_pcmciabus_register(struct ssb_bus *bus,
809 +                                        struct pcmcia_device *pcmcia_dev,
810 +                                        unsigned long baseaddr)
811  {
812         int err;
813  
814 @@ -897,8 +882,9 @@ EXPORT_SYMBOL(ssb_bus_pcmciabus_register
815  #endif /* CONFIG_SSB_PCMCIAHOST */
816  
817  #ifdef CONFIG_SSB_SDIOHOST
818 -int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func,
819 -                            unsigned int quirks)
820 +int __devinit ssb_bus_sdiobus_register(struct ssb_bus *bus,
821 +                                      struct sdio_func *func,
822 +                                      unsigned int quirks)
823  {
824         int err;
825  
826 @@ -918,9 +904,9 @@ int ssb_bus_sdiobus_register(struct ssb_
827  EXPORT_SYMBOL(ssb_bus_sdiobus_register);
828  #endif /* CONFIG_SSB_PCMCIAHOST */
829  
830 -int ssb_bus_ssbbus_register(struct ssb_bus *bus,
831 -                           unsigned long baseaddr,
832 -                           ssb_invariants_func_t get_invariants)
833 +int __devinit ssb_bus_ssbbus_register(struct ssb_bus *bus,
834 +                                     unsigned long baseaddr,
835 +                                     ssb_invariants_func_t get_invariants)
836  {
837         int err;
838  
839 @@ -1001,8 +987,8 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
840         switch (plltype) {
841         case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
842                 if (m & SSB_CHIPCO_CLK_T6_MMASK)
843 -                       return SSB_CHIPCO_CLK_T6_M0;
844 -               return SSB_CHIPCO_CLK_T6_M1;
845 +                       return SSB_CHIPCO_CLK_T6_M1;
846 +               return SSB_CHIPCO_CLK_T6_M0;
847         case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
848         case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
849         case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
850 @@ -1092,6 +1078,9 @@ u32 ssb_clockspeed(struct ssb_bus *bus)
851         u32 plltype;
852         u32 clkctl_n, clkctl_m;
853  
854 +       if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
855 +               return ssb_pmu_get_controlclock(&bus->chipco);
856 +
857         if (ssb_extif_available(&bus->extif))
858                 ssb_extif_get_clockcontrol(&bus->extif, &plltype,
859                                            &clkctl_n, &clkctl_m);
860 @@ -1117,23 +1106,22 @@ static u32 ssb_tmslow_reject_bitmask(str
861  {
862         u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
863  
864 -       /* The REJECT bit changed position in TMSLOW between
865 -        * Backplane revisions. */
866 +       /* The REJECT bit seems to be different for Backplane rev 2.3 */
867         switch (rev) {
868         case SSB_IDLOW_SSBREV_22:
869 -               return SSB_TMSLOW_REJECT_22;
870 +       case SSB_IDLOW_SSBREV_24:
871 +       case SSB_IDLOW_SSBREV_26:
872 +               return SSB_TMSLOW_REJECT;
873         case SSB_IDLOW_SSBREV_23:
874                 return SSB_TMSLOW_REJECT_23;
875 -       case SSB_IDLOW_SSBREV_24:     /* TODO - find the proper REJECT bits */
876 -       case SSB_IDLOW_SSBREV_25:     /* same here */
877 -       case SSB_IDLOW_SSBREV_26:     /* same here */
878 +       case SSB_IDLOW_SSBREV_25:     /* TODO - find the proper REJECT bit */
879         case SSB_IDLOW_SSBREV_27:     /* same here */
880 -               return SSB_TMSLOW_REJECT_23;    /* this is a guess */
881 +               return SSB_TMSLOW_REJECT;       /* this is a guess */
882         default:
883                 printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
884                 WARN_ON(1);
885         }
886 -       return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
887 +       return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23);
888  }
889  
890  int ssb_device_is_enabled(struct ssb_device *dev)
891 @@ -1260,13 +1248,34 @@ void ssb_device_disable(struct ssb_devic
892  }
893  EXPORT_SYMBOL(ssb_device_disable);
894  
895 +/* Some chipsets need routing known for PCIe and 64-bit DMA */
896 +static bool ssb_dma_translation_special_bit(struct ssb_device *dev)
897 +{
898 +       u16 chip_id = dev->bus->chip_id;
899 +
900 +       if (dev->id.coreid == SSB_DEV_80211) {
901 +               return (chip_id == 0x4322 || chip_id == 43221 ||
902 +                       chip_id == 43231 || chip_id == 43222);
903 +       }
904 +
905 +       return 0;
906 +}
907 +
908  u32 ssb_dma_translation(struct ssb_device *dev)
909  {
910         switch (dev->bus->bustype) {
911         case SSB_BUSTYPE_SSB:
912                 return 0;
913         case SSB_BUSTYPE_PCI:
914 -               return SSB_PCI_DMA;
915 +               if (pci_is_pcie(dev->bus->host_pci) &&
916 +                   ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64) {
917 +                       return SSB_PCIE_DMA_H32;
918 +               } else {
919 +                       if (ssb_dma_translation_special_bit(dev))
920 +                               return SSB_PCIE_DMA_H32;
921 +                       else
922 +                               return SSB_PCI_DMA;
923 +               }
924         default:
925                 __ssb_dma_not_implemented(dev);
926         }
927 @@ -1309,20 +1318,20 @@ EXPORT_SYMBOL(ssb_bus_may_powerdown);
928  
929  int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
930  {
931 -       struct ssb_chipcommon *cc;
932         int err;
933         enum ssb_clkmode mode;
934  
935         err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
936         if (err)
937                 goto error;
938 -       cc = &bus->chipco;
939 -       mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
940 -       ssb_chipco_set_clockmode(cc, mode);
941  
942  #ifdef CONFIG_SSB_DEBUG
943         bus->powered_up = 1;
944  #endif
945 +
946 +       mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
947 +       ssb_chipco_set_clockmode(&bus->chipco, mode);
948 +
949         return 0;
950  error:
951         ssb_printk(KERN_ERR PFX "Bus powerup failed\n");
952 @@ -1330,6 +1339,37 @@ error:
953  }
954  EXPORT_SYMBOL(ssb_bus_powerup);
955  
956 +static void ssb_broadcast_value(struct ssb_device *dev,
957 +                               u32 address, u32 data)
958 +{
959 +#ifdef CONFIG_SSB_DRIVER_PCICORE
960 +       /* This is used for both, PCI and ChipCommon core, so be careful. */
961 +       BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
962 +       BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
963 +#endif
964 +
965 +       ssb_write32(dev, SSB_CHIPCO_BCAST_ADDR, address);
966 +       ssb_read32(dev, SSB_CHIPCO_BCAST_ADDR); /* flush */
967 +       ssb_write32(dev, SSB_CHIPCO_BCAST_DATA, data);
968 +       ssb_read32(dev, SSB_CHIPCO_BCAST_DATA); /* flush */
969 +}
970 +
971 +void ssb_commit_settings(struct ssb_bus *bus)
972 +{
973 +       struct ssb_device *dev;
974 +
975 +#ifdef CONFIG_SSB_DRIVER_PCICORE
976 +       dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
977 +#else
978 +       dev = bus->chipco.dev;
979 +#endif
980 +       if (WARN_ON(!dev))
981 +               return;
982 +       /* This forces an update of the cached registers. */
983 +       ssb_broadcast_value(dev, 0xFD8, 0);
984 +}
985 +EXPORT_SYMBOL(ssb_commit_settings);
986 +
987  u32 ssb_admatch_base(u32 adm)
988  {
989         u32 base = 0;
990 --- a/drivers/ssb/pci.c
991 +++ b/drivers/ssb/pci.c
992 @@ -1,7 +1,7 @@
993  /*
994   * Sonics Silicon Backplane PCI-Hostbus related functions.
995   *
996 - * Copyright (C) 2005-2006 Michael Buesch <mb@bu3sch.de>
997 + * Copyright (C) 2005-2006 Michael Buesch <m@bues.ch>
998   * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
999   * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
1000   * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
1001 @@ -178,6 +178,18 @@ err_pci:
1002  #define SPEX(_outvar, _offset, _mask, _shift) \
1003         SPEX16(_outvar, _offset, _mask, _shift)
1004  
1005 +#define SPEX_ARRAY8(_field, _offset, _mask, _shift)    \
1006 +       do {    \
1007 +               SPEX(_field[0], _offset +  0, _mask, _shift);   \
1008 +               SPEX(_field[1], _offset +  2, _mask, _shift);   \
1009 +               SPEX(_field[2], _offset +  4, _mask, _shift);   \
1010 +               SPEX(_field[3], _offset +  6, _mask, _shift);   \
1011 +               SPEX(_field[4], _offset +  8, _mask, _shift);   \
1012 +               SPEX(_field[5], _offset + 10, _mask, _shift);   \
1013 +               SPEX(_field[6], _offset + 12, _mask, _shift);   \
1014 +               SPEX(_field[7], _offset + 14, _mask, _shift);   \
1015 +       } while (0)
1016 +
1017  
1018  static inline u8 ssb_crc8(u8 crc, u8 data)
1019  {
1020 @@ -331,7 +343,6 @@ static void sprom_extract_r123(struct ss
1021  {
1022         int i;
1023         u16 v;
1024 -       s8 gain;
1025         u16 loc[3];
1026  
1027         if (out->revision == 3)                 /* rev 3 moved MAC */
1028 @@ -361,8 +372,9 @@ static void sprom_extract_r123(struct ss
1029         SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
1030         SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
1031         SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
1032 -       SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
1033 -            SSB_SPROM1_BINF_CCODE_SHIFT);
1034 +       if (out->revision == 1)
1035 +               SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
1036 +                    SSB_SPROM1_BINF_CCODE_SHIFT);
1037         SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
1038              SSB_SPROM1_BINF_ANTA_SHIFT);
1039         SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
1040 @@ -388,22 +400,16 @@ static void sprom_extract_r123(struct ss
1041         SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
1042         if (out->revision >= 2)
1043                 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
1044 +       SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
1045 +       SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
1046  
1047         /* Extract the antenna gain values. */
1048 -       gain = r123_extract_antgain(out->revision, in,
1049 -                                   SSB_SPROM1_AGAIN_BG,
1050 -                                   SSB_SPROM1_AGAIN_BG_SHIFT);
1051 -       out->antenna_gain.ghz24.a0 = gain;
1052 -       out->antenna_gain.ghz24.a1 = gain;
1053 -       out->antenna_gain.ghz24.a2 = gain;
1054 -       out->antenna_gain.ghz24.a3 = gain;
1055 -       gain = r123_extract_antgain(out->revision, in,
1056 -                                   SSB_SPROM1_AGAIN_A,
1057 -                                   SSB_SPROM1_AGAIN_A_SHIFT);
1058 -       out->antenna_gain.ghz5.a0 = gain;
1059 -       out->antenna_gain.ghz5.a1 = gain;
1060 -       out->antenna_gain.ghz5.a2 = gain;
1061 -       out->antenna_gain.ghz5.a3 = gain;
1062 +       out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
1063 +                                                   SSB_SPROM1_AGAIN_BG,
1064 +                                                   SSB_SPROM1_AGAIN_BG_SHIFT);
1065 +       out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
1066 +                                                   SSB_SPROM1_AGAIN_A,
1067 +                                                   SSB_SPROM1_AGAIN_A_SHIFT);
1068  }
1069  
1070  /* Revs 4 5 and 8 have partially shared layout */
1071 @@ -464,14 +470,17 @@ static void sprom_extract_r45(struct ssb
1072         SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
1073         SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
1074              SSB_SPROM4_ETHPHY_ET1A_SHIFT);
1075 +       SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
1076         if (out->revision == 4) {
1077 -               SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
1078 +               SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
1079 +               SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
1080                 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
1081                 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
1082                 SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
1083                 SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
1084         } else {
1085 -               SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
1086 +               SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8);
1087 +               SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0);
1088                 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
1089                 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
1090                 SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
1091 @@ -504,16 +513,14 @@ static void sprom_extract_r45(struct ssb
1092         }
1093  
1094         /* Extract the antenna gain values. */
1095 -       SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
1096 +       SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
1097              SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
1098 -       SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
1099 +       SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
1100              SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
1101 -       SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
1102 +       SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
1103              SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
1104 -       SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
1105 +       SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
1106              SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
1107 -       memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
1108 -              sizeof(out->antenna_gain.ghz5));
1109  
1110         sprom_extract_r458(out, in);
1111  
1112 @@ -523,14 +530,22 @@ static void sprom_extract_r45(struct ssb
1113  static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
1114  {
1115         int i;
1116 -       u16 v;
1117 +       u16 v, o;
1118 +       u16 pwr_info_offset[] = {
1119 +               SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
1120 +               SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
1121 +       };
1122 +       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
1123 +                       ARRAY_SIZE(out->core_pwr_info));
1124  
1125         /* extract the MAC address */
1126         for (i = 0; i < 3; i++) {
1127                 v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
1128                 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
1129         }
1130 -       SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
1131 +       SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
1132 +       SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
1133 +       SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
1134         SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
1135         SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
1136         SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
1137 @@ -596,17 +611,127 @@ static void sprom_extract_r8(struct ssb_
1138         SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
1139  
1140         /* Extract the antenna gain values. */
1141 -       SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
1142 +       SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
1143              SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
1144 -       SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
1145 +       SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
1146              SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
1147 -       SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
1148 +       SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
1149              SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
1150 -       SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
1151 +       SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
1152              SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
1153 -       memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
1154 -              sizeof(out->antenna_gain.ghz5));
1155  
1156 +       /* Extract cores power info info */
1157 +       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
1158 +               o = pwr_info_offset[i];
1159 +               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1160 +                       SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
1161 +               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1162 +                       SSB_SPROM8_2G_MAXP, 0);
1163 +
1164 +               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
1165 +               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
1166 +               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
1167 +
1168 +               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1169 +                       SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
1170 +               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1171 +                       SSB_SPROM8_5G_MAXP, 0);
1172 +               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
1173 +                       SSB_SPROM8_5GH_MAXP, 0);
1174 +               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
1175 +                       SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
1176 +
1177 +               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
1178 +               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
1179 +               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
1180 +               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
1181 +               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
1182 +               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
1183 +               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
1184 +               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
1185 +               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
1186 +       }
1187 +
1188 +       /* Extract FEM info */
1189 +       SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
1190 +               SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
1191 +       SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G,
1192 +               SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
1193 +       SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G,
1194 +               SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
1195 +       SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G,
1196 +               SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
1197 +       SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G,
1198 +               SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
1199 +
1200 +       SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G,
1201 +               SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
1202 +       SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G,
1203 +               SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
1204 +       SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G,
1205 +               SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
1206 +       SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G,
1207 +               SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
1208 +       SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G,
1209 +               SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
1210 +
1211 +       SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
1212 +            SSB_SPROM8_LEDDC_ON_SHIFT);
1213 +       SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
1214 +            SSB_SPROM8_LEDDC_OFF_SHIFT);
1215 +
1216 +       SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
1217 +            SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
1218 +       SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
1219 +            SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
1220 +       SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
1221 +            SSB_SPROM8_TXRXC_SWITCH_SHIFT);
1222 +
1223 +       SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
1224 +
1225 +       SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
1226 +       SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
1227 +       SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
1228 +       SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
1229 +
1230 +       SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
1231 +            SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
1232 +       SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
1233 +            SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
1234 +       SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
1235 +            SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
1236 +            SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
1237 +       SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
1238 +            SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
1239 +       SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
1240 +            SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
1241 +            SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
1242 +       SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
1243 +            SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
1244 +            SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
1245 +       SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
1246 +            SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
1247 +            SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
1248 +       SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
1249 +            SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
1250 +
1251 +       SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
1252 +       SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
1253 +       SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
1254 +       SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
1255 +
1256 +       SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
1257 +            SSB_SPROM8_THERMAL_TRESH_SHIFT);
1258 +       SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
1259 +            SSB_SPROM8_THERMAL_OFFSET_SHIFT);
1260 +       SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
1261 +            SSB_SPROM8_TEMPDELTA_PHYCAL,
1262 +            SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
1263 +       SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
1264 +            SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
1265 +       SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
1266 +            SSB_SPROM8_TEMPDELTA_HYSTERESIS,
1267 +            SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
1268         sprom_extract_r458(out, in);
1269  
1270         /* TODO - get remaining rev 8 stuff needed */
1271 @@ -662,7 +787,6 @@ static int sprom_extract(struct ssb_bus
1272  static int ssb_pci_sprom_get(struct ssb_bus *bus,
1273                              struct ssb_sprom *sprom)
1274  {
1275 -       const struct ssb_sprom *fallback;
1276         int err;
1277         u16 *buf;
1278  
1279 @@ -707,10 +831,17 @@ static int ssb_pci_sprom_get(struct ssb_
1280                 if (err) {
1281                         /* All CRC attempts failed.
1282                          * Maybe there is no SPROM on the device?
1283 -                        * If we have a fallback, use that. */
1284 -                       fallback = ssb_get_fallback_sprom();
1285 -                       if (fallback) {
1286 -                               memcpy(sprom, fallback, sizeof(*sprom));
1287 +                        * Now we ask the arch code if there is some sprom
1288 +                        * available for this device in some other storage */
1289 +                       err = ssb_fill_sprom_with_fallback(bus, sprom);
1290 +                       if (err) {
1291 +                               ssb_printk(KERN_WARNING PFX "WARNING: Using"
1292 +                                          " fallback SPROM failed (err %d)\n",
1293 +                                          err);
1294 +                       } else {
1295 +                               ssb_dprintk(KERN_DEBUG PFX "Using SPROM"
1296 +                                           " revision %d provided by"
1297 +                                           " platform.\n", sprom->revision);
1298                                 err = 0;
1299                                 goto out_free;
1300                         }
1301 @@ -728,12 +859,8 @@ out_free:
1302  static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
1303                                   struct ssb_boardinfo *bi)
1304  {
1305 -       pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
1306 -                            &bi->vendor);
1307 -       pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
1308 -                            &bi->type);
1309 -       pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
1310 -                            &bi->rev);
1311 +       bi->vendor = bus->host_pci->subsystem_vendor;
1312 +       bi->type = bus->host_pci->subsystem_device;
1313  }
1314  
1315  int ssb_pci_get_invariants(struct ssb_bus *bus,
1316 --- a/drivers/ssb/pcihost_wrapper.c
1317 +++ b/drivers/ssb/pcihost_wrapper.c
1318 @@ -6,7 +6,7 @@
1319   * Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
1320   * Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
1321   * Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
1322 - * Copyright (c) 2005-2007 Michael Buesch <mbuesch@freenet.de>
1323 + * Copyright (c) 2005-2007 Michael Buesch <m@bues.ch>
1324   *
1325   * Licensed under the GNU/GPL. See COPYING for details.
1326   */
1327 @@ -53,8 +53,8 @@ static int ssb_pcihost_resume(struct pci
1328  # define ssb_pcihost_resume    NULL
1329  #endif /* CONFIG_PM */
1330  
1331 -static int ssb_pcihost_probe(struct pci_dev *dev,
1332 -                            const struct pci_device_id *id)
1333 +static int __devinit ssb_pcihost_probe(struct pci_dev *dev,
1334 +                                      const struct pci_device_id *id)
1335  {
1336         struct ssb_bus *ssb;
1337         int err = -ENOMEM;
1338 @@ -110,7 +110,7 @@ static void ssb_pcihost_remove(struct pc
1339         pci_set_drvdata(dev, NULL);
1340  }
1341  
1342 -int ssb_pcihost_register(struct pci_driver *driver)
1343 +int __devinit ssb_pcihost_register(struct pci_driver *driver)
1344  {
1345         driver->probe = ssb_pcihost_probe;
1346         driver->remove = ssb_pcihost_remove;
1347 --- a/drivers/ssb/pcmcia.c
1348 +++ b/drivers/ssb/pcmcia.c
1349 @@ -3,7 +3,7 @@
1350   * PCMCIA-Hostbus related functions
1351   *
1352   * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
1353 - * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
1354 + * Copyright 2007-2008 Michael Buesch <m@bues.ch>
1355   *
1356   * Licensed under the GNU/GPL. See COPYING for details.
1357   */
1358 @@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(
1359         case SSB_PCMCIA_CIS_ANTGAIN:
1360                 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1361                         "antg tpl size");
1362 -               sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
1363 -               sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
1364 -               sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
1365 -               sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
1366 -               sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
1367 -               sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
1368 -               sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
1369 -               sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
1370 +               sprom->antenna_gain.a0 = tuple->TupleData[1];
1371 +               sprom->antenna_gain.a1 = tuple->TupleData[1];
1372 +               sprom->antenna_gain.a2 = tuple->TupleData[1];
1373 +               sprom->antenna_gain.a3 = tuple->TupleData[1];
1374                 break;
1375         case SSB_PCMCIA_CIS_BFLAGS:
1376                 GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
1377 --- a/drivers/ssb/scan.c
1378 +++ b/drivers/ssb/scan.c
1379 @@ -2,7 +2,7 @@
1380   * Sonics Silicon Backplane
1381   * Bus scanning
1382   *
1383 - * Copyright (C) 2005-2007 Michael Buesch <mb@bu3sch.de>
1384 + * Copyright (C) 2005-2007 Michael Buesch <m@bues.ch>
1385   * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
1386   * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
1387   * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
1388 @@ -258,7 +258,10 @@ static int we_support_multiple_80211_cor
1389  #ifdef CONFIG_SSB_PCIHOST
1390         if (bus->bustype == SSB_BUSTYPE_PCI) {
1391                 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
1392 -                   bus->host_pci->device == 0x4324)
1393 +                   ((bus->host_pci->device == 0x4313) ||
1394 +                    (bus->host_pci->device == 0x431A) ||
1395 +                    (bus->host_pci->device == 0x4321) ||
1396 +                    (bus->host_pci->device == 0x4324)))
1397                         return 1;
1398         }
1399  #endif /* CONFIG_SSB_PCIHOST */
1400 @@ -307,8 +310,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
1401         } else {
1402                 if (bus->bustype == SSB_BUSTYPE_PCI) {
1403                         bus->chip_id = pcidev_to_chipid(bus->host_pci);
1404 -                       pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
1405 -                                            &bus->chip_rev);
1406 +                       bus->chip_rev = bus->host_pci->revision;
1407                         bus->chip_package = 0;
1408                 } else {
1409                         bus->chip_id = 0x4710;
1410 @@ -316,6 +318,9 @@ int ssb_bus_scan(struct ssb_bus *bus,
1411                         bus->chip_package = 0;
1412                 }
1413         }
1414 +       ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and "
1415 +                  "package 0x%02X\n", bus->chip_id, bus->chip_rev,
1416 +                  bus->chip_package);
1417         if (!bus->nr_devices)
1418                 bus->nr_devices = chipid_to_nrcores(bus->chip_id);
1419         if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
1420 --- a/drivers/ssb/sdio.c
1421 +++ b/drivers/ssb/sdio.c
1422 @@ -6,7 +6,7 @@
1423   *
1424   * Based on drivers/ssb/pcmcia.c
1425   * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
1426 - * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
1427 + * Copyright 2007-2008 Michael Buesch <m@bues.ch>
1428   *
1429   * Licensed under the GNU/GPL. See COPYING for details.
1430   *
1431 @@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_b
1432                         case SSB_SDIO_CIS_ANTGAIN:
1433                                 GOTO_ERROR_ON(tuple->size != 2,
1434                                               "antg tpl size");
1435 -                               sprom->antenna_gain.ghz24.a0 = tuple->data[1];
1436 -                               sprom->antenna_gain.ghz24.a1 = tuple->data[1];
1437 -                               sprom->antenna_gain.ghz24.a2 = tuple->data[1];
1438 -                               sprom->antenna_gain.ghz24.a3 = tuple->data[1];
1439 -                               sprom->antenna_gain.ghz5.a0 = tuple->data[1];
1440 -                               sprom->antenna_gain.ghz5.a1 = tuple->data[1];
1441 -                               sprom->antenna_gain.ghz5.a2 = tuple->data[1];
1442 -                               sprom->antenna_gain.ghz5.a3 = tuple->data[1];
1443 +                               sprom->antenna_gain.a0 = tuple->data[1];
1444 +                               sprom->antenna_gain.a1 = tuple->data[1];
1445 +                               sprom->antenna_gain.a2 = tuple->data[1];
1446 +                               sprom->antenna_gain.a3 = tuple->data[1];
1447                                 break;
1448                         case SSB_SDIO_CIS_BFLAGS:
1449                                 GOTO_ERROR_ON((tuple->size != 3) &&
1450 --- a/drivers/ssb/sprom.c
1451 +++ b/drivers/ssb/sprom.c
1452 @@ -2,7 +2,7 @@
1453   * Sonics Silicon Backplane
1454   * Common SPROM support routines
1455   *
1456 - * Copyright (C) 2005-2008 Michael Buesch <mb@bu3sch.de>
1457 + * Copyright (C) 2005-2008 Michael Buesch <m@bues.ch>
1458   * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
1459   * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
1460   * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
1461 @@ -17,7 +17,7 @@
1462  #include <linux/slab.h>
1463  
1464  
1465 -static const struct ssb_sprom *fallback_sprom;
1466 +static int(*get_fallback_sprom)(struct ssb_bus *dev, struct ssb_sprom *out);
1467  
1468  
1469  static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
1470 @@ -145,36 +145,43 @@ out:
1471  }
1472  
1473  /**
1474 - * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found.
1475 + * ssb_arch_register_fallback_sprom - Registers a method providing a
1476 + * fallback SPROM if no SPROM is found.
1477   *
1478 - * @sprom: The SPROM data structure to register.
1479 + * @sprom_callback: The callback function.
1480   *
1481 - * With this function the architecture implementation may register a fallback
1482 - * SPROM data structure. The fallback is only used for PCI based SSB devices,
1483 - * where no valid SPROM can be found in the shadow registers.
1484 + * With this function the architecture implementation may register a
1485 + * callback handler which fills the SPROM data structure. The fallback is
1486 + * only used for PCI based SSB devices, where no valid SPROM can be found
1487 + * in the shadow registers.
1488 + *
1489 + * This function is useful for weird architectures that have a half-assed
1490 + * SSB device hardwired to their PCI bus.
1491 + *
1492 + * Note that it does only work with PCI attached SSB devices. PCMCIA
1493 + * devices currently don't use this fallback.
1494 + * Architectures must provide the SPROM for native SSB devices anyway, so
1495 + * the fallback also isn't used for native devices.
1496   *
1497 - * This function is useful for weird architectures that have a half-assed SSB device
1498 - * hardwired to their PCI bus.
1499 - *
1500 - * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently
1501 - * don't use this fallback.
1502 - * Architectures must provide the SPROM for native SSB devices anyway,
1503 - * so the fallback also isn't used for native devices.
1504 - *
1505 - * This function is available for architecture code, only. So it is not exported.
1506 + * This function is available for architecture code, only. So it is not
1507 + * exported.
1508   */
1509 -int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom)
1510 +int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus,
1511 +                                    struct ssb_sprom *out))
1512  {
1513 -       if (fallback_sprom)
1514 +       if (get_fallback_sprom)
1515                 return -EEXIST;
1516 -       fallback_sprom = sprom;
1517 +       get_fallback_sprom = sprom_callback;
1518  
1519         return 0;
1520  }
1521  
1522 -const struct ssb_sprom *ssb_get_fallback_sprom(void)
1523 +int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out)
1524  {
1525 -       return fallback_sprom;
1526 +       if (!get_fallback_sprom)
1527 +               return -ENOENT;
1528 +
1529 +       return get_fallback_sprom(bus, out);
1530  }
1531  
1532  /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
1533 --- a/drivers/ssb/ssb_private.h
1534 +++ b/drivers/ssb/ssb_private.h
1535 @@ -171,7 +171,8 @@ ssize_t ssb_attr_sprom_store(struct ssb_
1536                              const char *buf, size_t count,
1537                              int (*sprom_check_crc)(const u16 *sprom, size_t size),
1538                              int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
1539 -extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
1540 +extern int ssb_fill_sprom_with_fallback(struct ssb_bus *bus,
1541 +                                       struct ssb_sprom *out);
1542  
1543  
1544  /* core.c */
1545 @@ -206,4 +207,8 @@ static inline void b43_pci_ssb_bridge_ex
1546  }
1547  #endif /* CONFIG_SSB_B43_PCI_BRIDGE */
1548  
1549 +/* driver_chipcommon_pmu.c */
1550 +extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
1551 +extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
1552 +
1553  #endif /* LINUX_SSB_PRIVATE_H_ */
1554 --- a/include/linux/ssb/ssb.h
1555 +++ b/include/linux/ssb/ssb.h
1556 @@ -16,6 +16,12 @@ struct pcmcia_device;
1557  struct ssb_bus;
1558  struct ssb_driver;
1559  
1560 +struct ssb_sprom_core_pwr_info {
1561 +       u8 itssi_2g, itssi_5g;
1562 +       u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh;
1563 +       u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4];
1564 +};
1565 +
1566  struct ssb_sprom {
1567         u8 revision;
1568         u8 il0mac[6];           /* MAC address for 802.11b/g */
1569 @@ -25,8 +31,13 @@ struct ssb_sprom {
1570         u8 et1phyaddr;          /* MII address for enet1 */
1571         u8 et0mdcport;          /* MDIO for enet0 */
1572         u8 et1mdcport;          /* MDIO for enet1 */
1573 -       u8 board_rev;           /* Board revision number from SPROM. */
1574 +       u16 board_rev;          /* Board revision number from SPROM. */
1575 +       u16 board_num;          /* Board number from SPROM. */
1576 +       u16 board_type;         /* Board type from SPROM. */
1577         u8 country_code;        /* Country Code */
1578 +       char alpha2[2];         /* Country Code as two chars like EU or US */
1579 +       u8 leddc_on_time;       /* LED Powersave Duty Cycle On Count */
1580 +       u8 leddc_off_time;      /* LED Powersave Duty Cycle Off Count */
1581         u8 ant_available_a;     /* 2GHz antenna available bits (up to 4) */
1582         u8 ant_available_bg;    /* 5GHz antenna available bits (up to 4) */
1583         u16 pa0b0;
1584 @@ -45,10 +56,10 @@ struct ssb_sprom {
1585         u8 gpio1;               /* GPIO pin 1 */
1586         u8 gpio2;               /* GPIO pin 2 */
1587         u8 gpio3;               /* GPIO pin 3 */
1588 -       u16 maxpwr_bg;          /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
1589 -       u16 maxpwr_al;          /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
1590 -       u16 maxpwr_a;           /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
1591 -       u16 maxpwr_ah;          /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
1592 +       u8 maxpwr_bg;           /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
1593 +       u8 maxpwr_al;           /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
1594 +       u8 maxpwr_a;            /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
1595 +       u8 maxpwr_ah;           /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
1596         u8 itssi_a;             /* Idle TSSI Target for A-PHY */
1597         u8 itssi_bg;            /* Idle TSSI Target for B/G-PHY */
1598         u8 tri2g;               /* 2.4GHz TX isolation */
1599 @@ -59,8 +70,8 @@ struct ssb_sprom {
1600         u8 txpid5gl[4];         /* 4.9 - 5.1GHz TX power index */
1601         u8 txpid5g[4];          /* 5.1 - 5.5GHz TX power index */
1602         u8 txpid5gh[4];         /* 5.5 - ...GHz TX power index */
1603 -       u8 rxpo2g;              /* 2GHz RX power offset */
1604 -       u8 rxpo5g;              /* 5GHz RX power offset */
1605 +       s8 rxpo2g;              /* 2GHz RX power offset */
1606 +       s8 rxpo5g;              /* 5GHz RX power offset */
1607         u8 rssisav2g;           /* 2GHz RSSI params */
1608         u8 rssismc2g;
1609         u8 rssismf2g;
1610 @@ -80,26 +91,103 @@ struct ssb_sprom {
1611         u16 boardflags2_hi;     /* Board flags (bits 48-63) */
1612         /* TODO store board flags in a single u64 */
1613  
1614 +       struct ssb_sprom_core_pwr_info core_pwr_info[4];
1615 +
1616         /* Antenna gain values for up to 4 antennas
1617          * on each band. Values in dBm/4 (Q5.2). Negative gain means the
1618          * loss in the connectors is bigger than the gain. */
1619         struct {
1620 -               struct {
1621 -                       s8 a0, a1, a2, a3;
1622 -               } ghz24;        /* 2.4GHz band */
1623 -               struct {
1624 -                       s8 a0, a1, a2, a3;
1625 -               } ghz5;         /* 5GHz band */
1626 +               s8 a0, a1, a2, a3;
1627         } antenna_gain;
1628  
1629 -       /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
1630 +       struct {
1631 +               struct {
1632 +                       u8 tssipos, extpa_gain, pdet_range, tr_iso, antswlut;
1633 +               } ghz2;
1634 +               struct {
1635 +                       u8 tssipos, extpa_gain, pdet_range, tr_iso, antswlut;
1636 +               } ghz5;
1637 +       } fem;
1638 +
1639 +       u16 mcs2gpo[8];
1640 +       u16 mcs5gpo[8];
1641 +       u16 mcs5glpo[8];
1642 +       u16 mcs5ghpo[8];
1643 +       u8 opo;
1644 +
1645 +       u8 rxgainerr2ga[3];
1646 +       u8 rxgainerr5gla[3];
1647 +       u8 rxgainerr5gma[3];
1648 +       u8 rxgainerr5gha[3];
1649 +       u8 rxgainerr5gua[3];
1650 +
1651 +       u8 noiselvl2ga[3];
1652 +       u8 noiselvl5gla[3];
1653 +       u8 noiselvl5gma[3];
1654 +       u8 noiselvl5gha[3];
1655 +       u8 noiselvl5gua[3];
1656 +
1657 +       u8 regrev;
1658 +       u8 txchain;
1659 +       u8 rxchain;
1660 +       u8 antswitch;
1661 +       u16 cddpo;
1662 +       u16 stbcpo;
1663 +       u16 bw40po;
1664 +       u16 bwduppo;
1665 +
1666 +       u8 tempthresh;
1667 +       u8 tempoffset;
1668 +       u16 rawtempsense;
1669 +       u8 measpower;
1670 +       u8 tempsense_slope;
1671 +       u8 tempcorrx;
1672 +       u8 tempsense_option;
1673 +       u8 freqoffset_corr;
1674 +       u8 iqcal_swp_dis;
1675 +       u8 hw_iqcal_en;
1676 +       u8 elna2g;
1677 +       u8 elna5g;
1678 +       u8 phycal_tempdelta;
1679 +       u8 temps_period;
1680 +       u8 temps_hysteresis;
1681 +       u8 measpower1;
1682 +       u8 measpower2;
1683 +       u8 pcieingress_war;
1684 +
1685 +       /* power per rate from sromrev 9 */
1686 +       u16 cckbw202gpo;
1687 +       u16 cckbw20ul2gpo;
1688 +       u32 legofdmbw202gpo;
1689 +       u32 legofdmbw20ul2gpo;
1690 +       u32 legofdmbw205glpo;
1691 +       u32 legofdmbw20ul5glpo;
1692 +       u32 legofdmbw205gmpo;
1693 +       u32 legofdmbw20ul5gmpo;
1694 +       u32 legofdmbw205ghpo;
1695 +       u32 legofdmbw20ul5ghpo;
1696 +       u32 mcsbw202gpo;
1697 +       u32 mcsbw20ul2gpo;
1698 +       u32 mcsbw402gpo;
1699 +       u32 mcsbw205glpo;
1700 +       u32 mcsbw20ul5glpo;
1701 +       u32 mcsbw405glpo;
1702 +       u32 mcsbw205gmpo;
1703 +       u32 mcsbw20ul5gmpo;
1704 +       u32 mcsbw405gmpo;
1705 +       u32 mcsbw205ghpo;
1706 +       u32 mcsbw20ul5ghpo;
1707 +       u32 mcsbw405ghpo;
1708 +       u16 mcs32po;
1709 +       u16 legofdm40duppo;
1710 +       u8 sar2g;
1711 +       u8 sar5g;
1712  };
1713  
1714  /* Information about the PCB the circuitry is soldered on. */
1715  struct ssb_boardinfo {
1716         u16 vendor;
1717         u16 type;
1718 -       u16 rev;
1719  };
1720  
1721  
1722 @@ -229,10 +317,9 @@ struct ssb_driver {
1723  #define drv_to_ssb_drv(_drv) container_of(_drv, struct ssb_driver, drv)
1724  
1725  extern int __ssb_driver_register(struct ssb_driver *drv, struct module *owner);
1726 -static inline int ssb_driver_register(struct ssb_driver *drv)
1727 -{
1728 -       return __ssb_driver_register(drv, THIS_MODULE);
1729 -}
1730 +#define ssb_driver_register(drv) \
1731 +       __ssb_driver_register(drv, THIS_MODULE)
1732 +
1733  extern void ssb_driver_unregister(struct ssb_driver *drv);
1734  
1735  
1736 @@ -308,7 +395,7 @@ struct ssb_bus {
1737  
1738         /* ID information about the Chip. */
1739         u16 chip_id;
1740 -       u16 chip_rev;
1741 +       u8 chip_rev;
1742         u16 sprom_offset;
1743         u16 sprom_size;         /* number of words in sprom */
1744         u8 chip_package;
1745 @@ -404,7 +491,9 @@ extern bool ssb_is_sprom_available(struc
1746  
1747  /* Set a fallback SPROM.
1748   * See kdoc at the function definition for complete documentation. */
1749 -extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
1750 +extern int ssb_arch_register_fallback_sprom(
1751 +               int (*sprom_callback)(struct ssb_bus *bus,
1752 +               struct ssb_sprom *out));
1753  
1754  /* Suspend a SSB bus.
1755   * Call this from the parent bus suspend routine. */
1756 @@ -518,6 +607,7 @@ extern int ssb_bus_may_powerdown(struct
1757   * Otherwise static always-on powercontrol will be used. */
1758  extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
1759  
1760 +extern void ssb_commit_settings(struct ssb_bus *bus);
1761  
1762  /* Various helper functions */
1763  extern u32 ssb_admatch_base(u32 adm);
1764 --- a/include/linux/ssb/ssb_driver_chipcommon.h
1765 +++ b/include/linux/ssb/ssb_driver_chipcommon.h
1766 @@ -8,7 +8,7 @@
1767   * gpio interface, extbus, and support for serial and parallel flashes.
1768   *
1769   * Copyright 2005, Broadcom Corporation
1770 - * Copyright 2006, Michael Buesch <mb@bu3sch.de>
1771 + * Copyright 2006, Michael Buesch <m@bues.ch>
1772   *
1773   * Licensed under the GPL version 2. See COPYING for details.
1774   */
1775 @@ -123,6 +123,8 @@
1776  #define SSB_CHIPCO_FLASHDATA           0x0048
1777  #define SSB_CHIPCO_BCAST_ADDR          0x0050
1778  #define SSB_CHIPCO_BCAST_DATA          0x0054
1779 +#define SSB_CHIPCO_GPIOPULLUP          0x0058          /* Rev >= 20 only */
1780 +#define SSB_CHIPCO_GPIOPULLDOWN                0x005C          /* Rev >= 20 only */
1781  #define SSB_CHIPCO_GPIOIN              0x0060
1782  #define SSB_CHIPCO_GPIOOUT             0x0064
1783  #define SSB_CHIPCO_GPIOOUTEN           0x0068
1784 @@ -131,6 +133,9 @@
1785  #define SSB_CHIPCO_GPIOIRQ             0x0074
1786  #define SSB_CHIPCO_WATCHDOG            0x0080
1787  #define SSB_CHIPCO_GPIOTIMER           0x0088          /* LED powersave (corerev >= 16) */
1788 +#define  SSB_CHIPCO_GPIOTIMER_OFFTIME  0x0000FFFF
1789 +#define  SSB_CHIPCO_GPIOTIMER_OFFTIME_SHIFT    0
1790 +#define  SSB_CHIPCO_GPIOTIMER_ONTIME   0xFFFF0000
1791  #define  SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT     16
1792  #define SSB_CHIPCO_GPIOTOUTM           0x008C          /* LED powersave (corerev >= 16) */
1793  #define SSB_CHIPCO_CLOCK_N             0x0090
1794 @@ -189,8 +194,10 @@
1795  #define  SSB_CHIPCO_CLKCTLST_HAVEALPREQ        0x00000008 /* ALP available request */
1796  #define  SSB_CHIPCO_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
1797  #define  SSB_CHIPCO_CLKCTLST_HWCROFF   0x00000020 /* Force HW clock request off */
1798 -#define  SSB_CHIPCO_CLKCTLST_HAVEHT    0x00010000 /* HT available */
1799 -#define  SSB_CHIPCO_CLKCTLST_HAVEALP   0x00020000 /* APL available */
1800 +#define  SSB_CHIPCO_CLKCTLST_HAVEALP   0x00010000 /* ALP available */
1801 +#define  SSB_CHIPCO_CLKCTLST_HAVEHT    0x00020000 /* HT available */
1802 +#define  SSB_CHIPCO_CLKCTLST_4328A0_HAVEHT     0x00010000 /* 4328a0 has reversed bits */
1803 +#define  SSB_CHIPCO_CLKCTLST_4328A0_HAVEALP    0x00020000 /* 4328a0 has reversed bits */
1804  #define SSB_CHIPCO_HW_WORKAROUND       0x01E4 /* Hardware workaround (rev >= 20) */
1805  #define SSB_CHIPCO_UART0_DATA          0x0300
1806  #define SSB_CHIPCO_UART0_IMR           0x0304
1807 --- a/include/linux/ssb/ssb_driver_gige.h
1808 +++ b/include/linux/ssb/ssb_driver_gige.h
1809 @@ -2,6 +2,7 @@
1810  #define LINUX_SSB_DRIVER_GIGE_H_
1811  
1812  #include <linux/ssb/ssb.h>
1813 +#include <linux/bug.h>
1814  #include <linux/pci.h>
1815  #include <linux/spinlock.h>
1816  
1817 --- a/include/linux/ssb/ssb_regs.h
1818 +++ b/include/linux/ssb/ssb_regs.h
1819 @@ -97,7 +97,7 @@
1820  #define  SSB_INTVEC_ENET1      0x00000040 /* Enable interrupts for enet 1 */
1821  #define SSB_TMSLOW             0x0F98     /* SB Target State Low */
1822  #define  SSB_TMSLOW_RESET      0x00000001 /* Reset */
1823 -#define  SSB_TMSLOW_REJECT_22  0x00000002 /* Reject (Backplane rev 2.2) */
1824 +#define  SSB_TMSLOW_REJECT     0x00000002 /* Reject (Standard Backplane) */
1825  #define  SSB_TMSLOW_REJECT_23  0x00000004 /* Reject (Backplane rev 2.3) */
1826  #define  SSB_TMSLOW_CLOCK      0x00010000 /* Clock Enable */
1827  #define  SSB_TMSLOW_FGC                0x00020000 /* Force Gated Clocks On */
1828 @@ -228,6 +228,7 @@
1829  #define  SSB_SPROM1_AGAIN_BG_SHIFT     0
1830  #define  SSB_SPROM1_AGAIN_A            0xFF00  /* A-PHY */
1831  #define  SSB_SPROM1_AGAIN_A_SHIFT      8
1832 +#define SSB_SPROM1_CCODE               0x0076
1833  
1834  /* SPROM Revision 2 (inherits from rev 1) */
1835  #define SSB_SPROM2_BFLHI               0x0038  /* Boardflags (high 16 bits) */
1836 @@ -267,6 +268,7 @@
1837  #define  SSB_SPROM3_OFDMGPO            0x107A  /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
1838  
1839  /* SPROM Revision 4 */
1840 +#define SSB_SPROM4_BOARDREV            0x0042  /* Board revision */
1841  #define SSB_SPROM4_BFLLO               0x0044  /* Boardflags (low 16 bits) */
1842  #define SSB_SPROM4_BFLHI               0x0046  /* Board Flags Hi */
1843  #define SSB_SPROM4_BFL2LO              0x0048  /* Board flags 2 (low 16 bits) */
1844 @@ -389,6 +391,11 @@
1845  #define  SSB_SPROM8_GPIOB_P2           0x00FF  /* Pin 2 */
1846  #define  SSB_SPROM8_GPIOB_P3           0xFF00  /* Pin 3 */
1847  #define  SSB_SPROM8_GPIOB_P3_SHIFT     8
1848 +#define SSB_SPROM8_LEDDC               0x009A
1849 +#define  SSB_SPROM8_LEDDC_ON           0xFF00  /* oncount */
1850 +#define  SSB_SPROM8_LEDDC_ON_SHIFT     8
1851 +#define  SSB_SPROM8_LEDDC_OFF          0x00FF  /* offcount */
1852 +#define  SSB_SPROM8_LEDDC_OFF_SHIFT    0
1853  #define SSB_SPROM8_ANTAVAIL            0x009C  /* Antenna available bitfields*/
1854  #define  SSB_SPROM8_ANTAVAIL_A         0xFF00  /* A-PHY bitfield */
1855  #define  SSB_SPROM8_ANTAVAIL_A_SHIFT   8
1856 @@ -404,6 +411,13 @@
1857  #define  SSB_SPROM8_AGAIN2_SHIFT       0
1858  #define  SSB_SPROM8_AGAIN3             0xFF00  /* Antenna 3 */
1859  #define  SSB_SPROM8_AGAIN3_SHIFT       8
1860 +#define SSB_SPROM8_TXRXC               0x00A2
1861 +#define  SSB_SPROM8_TXRXC_TXCHAIN      0x000f
1862 +#define  SSB_SPROM8_TXRXC_TXCHAIN_SHIFT        0
1863 +#define  SSB_SPROM8_TXRXC_RXCHAIN      0x00f0
1864 +#define  SSB_SPROM8_TXRXC_RXCHAIN_SHIFT        4
1865 +#define  SSB_SPROM8_TXRXC_SWITCH       0xff00
1866 +#define  SSB_SPROM8_TXRXC_SWITCH_SHIFT 8
1867  #define SSB_SPROM8_RSSIPARM2G          0x00A4  /* RSSI params for 2GHz */
1868  #define  SSB_SPROM8_RSSISMF2G          0x000F
1869  #define  SSB_SPROM8_RSSISMC2G          0x00F0
1870 @@ -430,8 +444,87 @@
1871  #define  SSB_SPROM8_TRI5GH_SHIFT       8
1872  #define SSB_SPROM8_RXPO                        0x00AC  /* RX power offsets */
1873  #define  SSB_SPROM8_RXPO2G             0x00FF  /* 2GHz RX power offset */
1874 +#define  SSB_SPROM8_RXPO2G_SHIFT       0
1875  #define  SSB_SPROM8_RXPO5G             0xFF00  /* 5GHz RX power offset */
1876  #define  SSB_SPROM8_RXPO5G_SHIFT       8
1877 +#define SSB_SPROM8_FEM2G               0x00AE
1878 +#define SSB_SPROM8_FEM5G               0x00B0
1879 +#define  SSB_SROM8_FEM_TSSIPOS         0x0001
1880 +#define  SSB_SROM8_FEM_TSSIPOS_SHIFT   0
1881 +#define  SSB_SROM8_FEM_EXTPA_GAIN      0x0006
1882 +#define  SSB_SROM8_FEM_EXTPA_GAIN_SHIFT        1
1883 +#define  SSB_SROM8_FEM_PDET_RANGE      0x00F8
1884 +#define  SSB_SROM8_FEM_PDET_RANGE_SHIFT        3
1885 +#define  SSB_SROM8_FEM_TR_ISO          0x0700
1886 +#define  SSB_SROM8_FEM_TR_ISO_SHIFT    8
1887 +#define  SSB_SROM8_FEM_ANTSWLUT                0xF800
1888 +#define  SSB_SROM8_FEM_ANTSWLUT_SHIFT  11
1889 +#define SSB_SPROM8_THERMAL             0x00B2
1890 +#define  SSB_SPROM8_THERMAL_OFFSET     0x00ff
1891 +#define  SSB_SPROM8_THERMAL_OFFSET_SHIFT       0
1892 +#define  SSB_SPROM8_THERMAL_TRESH      0xff00
1893 +#define  SSB_SPROM8_THERMAL_TRESH_SHIFT        8
1894 +/* Temp sense related entries */
1895 +#define SSB_SPROM8_RAWTS               0x00B4
1896 +#define  SSB_SPROM8_RAWTS_RAWTEMP      0x01ff
1897 +#define  SSB_SPROM8_RAWTS_RAWTEMP_SHIFT        0
1898 +#define  SSB_SPROM8_RAWTS_MEASPOWER    0xfe00
1899 +#define  SSB_SPROM8_RAWTS_MEASPOWER_SHIFT      9
1900 +#define SSB_SPROM8_OPT_CORRX           0x00B6
1901 +#define  SSB_SPROM8_OPT_CORRX_TEMP_SLOPE       0x00ff
1902 +#define  SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT 0
1903 +#define  SSB_SPROM8_OPT_CORRX_TEMPCORRX        0xfc00
1904 +#define  SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT  10
1905 +#define  SSB_SPROM8_OPT_CORRX_TEMP_OPTION      0x0300
1906 +#define  SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT        8
1907 +/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */
1908 +#define SSB_SPROM8_HWIQ_IQSWP          0x00B8
1909 +#define  SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR       0x000f
1910 +#define  SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT 0
1911 +#define  SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP       0x0010
1912 +#define  SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT 4
1913 +#define  SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL        0x0020
1914 +#define  SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT  5
1915 +#define SSB_SPROM8_TEMPDELTA           0x00BA
1916 +#define  SSB_SPROM8_TEMPDELTA_PHYCAL   0x00ff
1917 +#define  SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT     0
1918 +#define  SSB_SPROM8_TEMPDELTA_PERIOD   0x0f00
1919 +#define  SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT     8
1920 +#define  SSB_SPROM8_TEMPDELTA_HYSTERESIS       0xf000
1921 +#define  SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT 12
1922 +
1923 +/* There are 4 blocks with power info sharing the same layout */
1924 +#define SSB_SROM8_PWR_INFO_CORE0       0x00C0
1925 +#define SSB_SROM8_PWR_INFO_CORE1       0x00E0
1926 +#define SSB_SROM8_PWR_INFO_CORE2       0x0100
1927 +#define SSB_SROM8_PWR_INFO_CORE3       0x0120
1928 +
1929 +#define SSB_SROM8_2G_MAXP_ITSSI                0x00
1930 +#define  SSB_SPROM8_2G_MAXP            0x00FF
1931 +#define  SSB_SPROM8_2G_ITSSI           0xFF00
1932 +#define  SSB_SPROM8_2G_ITSSI_SHIFT     8
1933 +#define SSB_SROM8_2G_PA_0              0x02    /* 2GHz power amp settings */
1934 +#define SSB_SROM8_2G_PA_1              0x04
1935 +#define SSB_SROM8_2G_PA_2              0x06
1936 +#define SSB_SROM8_5G_MAXP_ITSSI                0x08    /* 5GHz ITSSI and 5.3GHz Max Power */
1937 +#define  SSB_SPROM8_5G_MAXP            0x00FF
1938 +#define  SSB_SPROM8_5G_ITSSI           0xFF00
1939 +#define  SSB_SPROM8_5G_ITSSI_SHIFT     8
1940 +#define SSB_SPROM8_5GHL_MAXP           0x0A    /* 5.2GHz and 5.8GHz Max Power */
1941 +#define  SSB_SPROM8_5GH_MAXP           0x00FF
1942 +#define  SSB_SPROM8_5GL_MAXP           0xFF00
1943 +#define  SSB_SPROM8_5GL_MAXP_SHIFT     8
1944 +#define SSB_SROM8_5G_PA_0              0x0C    /* 5.3GHz power amp settings */
1945 +#define SSB_SROM8_5G_PA_1              0x0E
1946 +#define SSB_SROM8_5G_PA_2              0x10
1947 +#define SSB_SROM8_5GL_PA_0             0x12    /* 5.2GHz power amp settings */
1948 +#define SSB_SROM8_5GL_PA_1             0x14
1949 +#define SSB_SROM8_5GL_PA_2             0x16
1950 +#define SSB_SROM8_5GH_PA_0             0x18    /* 5.8GHz power amp settings */
1951 +#define SSB_SROM8_5GH_PA_1             0x1A
1952 +#define SSB_SROM8_5GH_PA_2             0x1C
1953 +
1954 +/* TODO: Make it deprecated */
1955  #define SSB_SPROM8_MAXP_BG             0x00C0  /* Max Power 2GHz in path 1 */
1956  #define  SSB_SPROM8_MAXP_BG_MASK       0x00FF  /* Mask for Max Power 2GHz */
1957  #define  SSB_SPROM8_ITSSI_BG           0xFF00  /* Mask for path 1 itssi_bg */
1958 @@ -456,12 +549,63 @@
1959  #define SSB_SPROM8_PA1HIB0             0x00D8  /* 5.8GHz power amp settings */
1960  #define SSB_SPROM8_PA1HIB1             0x00DA
1961  #define SSB_SPROM8_PA1HIB2             0x00DC
1962 +
1963  #define SSB_SPROM8_CCK2GPO             0x0140  /* CCK power offset */
1964  #define SSB_SPROM8_OFDM2GPO            0x0142  /* 2.4GHz OFDM power offset */
1965  #define SSB_SPROM8_OFDM5GPO            0x0146  /* 5.3GHz OFDM power offset */
1966  #define SSB_SPROM8_OFDM5GLPO           0x014A  /* 5.2GHz OFDM power offset */
1967  #define SSB_SPROM8_OFDM5GHPO           0x014E  /* 5.8GHz OFDM power offset */
1968  
1969 +#define SSB_SPROM8_2G_MCSPO            0x0152
1970 +#define SSB_SPROM8_5G_MCSPO            0x0162
1971 +#define SSB_SPROM8_5GL_MCSPO           0x0172
1972 +#define SSB_SPROM8_5GH_MCSPO           0x0182
1973 +
1974 +#define SSB_SPROM8_CDDPO               0x0192
1975 +#define SSB_SPROM8_STBCPO              0x0194
1976 +#define SSB_SPROM8_BW40PO              0x0196
1977 +#define SSB_SPROM8_BWDUPPO             0x0198
1978 +
1979 +/* Values for boardflags_lo read from SPROM */
1980 +#define SSB_BFL_BTCOEXIST              0x0001  /* implements Bluetooth coexistance */
1981 +#define SSB_BFL_PACTRL                 0x0002  /* GPIO 9 controlling the PA */
1982 +#define SSB_BFL_AIRLINEMODE            0x0004  /* implements GPIO 13 radio disable indication */
1983 +#define SSB_BFL_RSSI                   0x0008  /* software calculates nrssi slope. */
1984 +#define SSB_BFL_ENETSPI                        0x0010  /* has ephy roboswitch spi */
1985 +#define SSB_BFL_XTAL_NOSLOW            0x0020  /* no slow clock available */
1986 +#define SSB_BFL_CCKHIPWR               0x0040  /* can do high power CCK transmission */
1987 +#define SSB_BFL_ENETADM                        0x0080  /* has ADMtek switch */
1988 +#define SSB_BFL_ENETVLAN               0x0100  /* can do vlan */
1989 +#define SSB_BFL_AFTERBURNER            0x0200  /* supports Afterburner mode */
1990 +#define SSB_BFL_NOPCI                  0x0400  /* board leaves PCI floating */
1991 +#define SSB_BFL_FEM                    0x0800  /* supports the Front End Module */
1992 +#define SSB_BFL_EXTLNA                 0x1000  /* has an external LNA */
1993 +#define SSB_BFL_HGPA                   0x2000  /* had high gain PA */
1994 +#define SSB_BFL_BTCMOD                 0x4000  /* BFL_BTCOEXIST is given in alternate GPIOs */
1995 +#define SSB_BFL_ALTIQ                  0x8000  /* alternate I/Q settings */
1996 +
1997 +/* Values for boardflags_hi read from SPROM */
1998 +#define SSB_BFH_NOPA                   0x0001  /* has no PA */
1999 +#define SSB_BFH_RSSIINV                        0x0002  /* RSSI uses positive slope (not TSSI) */
2000 +#define SSB_BFH_PAREF                  0x0004  /* uses the PARef LDO */
2001 +#define SSB_BFH_3TSWITCH               0x0008  /* uses a triple throw switch shared with bluetooth */
2002 +#define SSB_BFH_PHASESHIFT             0x0010  /* can support phase shifter */
2003 +#define SSB_BFH_BUCKBOOST              0x0020  /* has buck/booster */
2004 +#define SSB_BFH_FEM_BT                 0x0040  /* has FEM and switch to share antenna with bluetooth */
2005 +
2006 +/* Values for boardflags2_lo read from SPROM */
2007 +#define SSB_BFL2_RXBB_INT_REG_DIS      0x0001  /* external RX BB regulator present */
2008 +#define SSB_BFL2_APLL_WAR              0x0002  /* alternative A-band PLL settings implemented */
2009 +#define SSB_BFL2_TXPWRCTRL_EN          0x0004  /* permits enabling TX Power Control */
2010 +#define SSB_BFL2_2X4_DIV               0x0008  /* 2x4 diversity switch */
2011 +#define SSB_BFL2_5G_PWRGAIN            0x0010  /* supports 5G band power gain */
2012 +#define SSB_BFL2_PCIEWAR_OVR           0x0020  /* overrides ASPM and Clkreq settings */
2013 +#define SSB_BFL2_CAESERS_BRD           0x0040  /* is Caesers board (unused) */
2014 +#define SSB_BFL2_BTC3WIRE              0x0080  /* used 3-wire bluetooth coexist */
2015 +#define SSB_BFL2_SKWRKFEM_BRD          0x0100  /* 4321mcm93 uses Skyworks FEM */
2016 +#define SSB_BFL2_SPUR_WAR              0x0200  /* has a workaround for clock-harmonic spurs */
2017 +#define SSB_BFL2_GPLL_WAR              0x0400  /* altenative G-band PLL settings implemented */
2018 +
2019  /* Values for SSB_SPROM1_BINF_CCODE */
2020  enum {
2021         SSB_SPROM1CCODE_WORLD = 0,