Root/target/linux/generic/patches-2.6.31/941-ssb_update.patch

1--- a/drivers/ssb/Kconfig
2+++ b/drivers/ssb/Kconfig
3@@ -66,6 +66,20 @@ config SSB_PCMCIAHOST
4 
5       If unsure, say N
6 
7+config SSB_SDIOHOST_POSSIBLE
8+ bool
9+ depends on SSB && (MMC = y || MMC = SSB)
10+ default y
11+
12+config SSB_SDIOHOST
13+ bool "Support for SSB on SDIO-bus host"
14+ depends on SSB_SDIOHOST_POSSIBLE
15+ help
16+ Support for a Sonics Silicon Backplane on top
17+ of a SDIO device.
18+
19+ If unsure, say N
20+
21 config SSB_SILENT
22     bool "No SSB kernel messages"
23     depends on SSB && EMBEDDED
24--- a/drivers/ssb/Makefile
25+++ b/drivers/ssb/Makefile
26@@ -6,6 +6,7 @@ ssb-$(CONFIG_SSB_SPROM) += sprom.o
27 # host support
28 ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o
29 ssb-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o
30+ssb-$(CONFIG_SSB_SDIOHOST) += sdio.o
31 
32 # built-in drivers
33 ssb-y += driver_chipcommon.o
34--- a/drivers/ssb/b43_pci_bridge.c
35+++ b/drivers/ssb/b43_pci_bridge.c
36@@ -24,6 +24,7 @@ static const struct pci_device_id b43_pc
37     { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
38     { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) },
39     { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) },
40+ { PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC, 0x4318) },
41     { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
42     { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
43     { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
44--- a/drivers/ssb/driver_chipcommon.c
45+++ b/drivers/ssb/driver_chipcommon.c
46@@ -46,40 +46,66 @@ void ssb_chipco_set_clockmode(struct ssb
47     if (!ccdev)
48         return;
49     bus = ccdev->bus;
50+
51+ /* We support SLOW only on 6..9 */
52+ if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)
53+ mode = SSB_CLKMODE_DYNAMIC;
54+
55+ if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
56+ return; /* PMU controls clockmode, separated function needed */
57+ SSB_WARN_ON(ccdev->id.revision >= 20);
58+
59     /* chipcommon cores prior to rev6 don't support dynamic clock control */
60     if (ccdev->id.revision < 6)
61         return;
62- /* chipcommon cores rev10 are a whole new ball game */
63+
64+ /* ChipCommon cores rev10+ need testing */
65     if (ccdev->id.revision >= 10)
66         return;
67+
68     if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
69         return;
70 
71     switch (mode) {
72- case SSB_CLKMODE_SLOW:
73+ case SSB_CLKMODE_SLOW: /* For revs 6..9 only */
74         tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
75         tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
76         chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
77         break;
78     case SSB_CLKMODE_FAST:
79- ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
80- tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
81- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
82- tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
83- chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
84+ if (ccdev->id.revision < 10) {
85+ ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
86+ tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
87+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
88+ tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
89+ chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
90+ } else {
91+ chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
92+ (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |
93+ SSB_CHIPCO_SYSCLKCTL_FORCEHT));
94+ /* udelay(150); TODO: not available in early init */
95+ }
96         break;
97     case SSB_CLKMODE_DYNAMIC:
98- tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
99- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
100- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
101- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
102- if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
103- tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
104- chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
105-
106- /* for dynamic control, we have to release our xtal_pu "force on" */
107- if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
108- ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
109+ if (ccdev->id.revision < 10) {
110+ tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
111+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
112+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
113+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
114+ if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=
115+ SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
116+ tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
117+ chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
118+
119+ /* For dynamic control, we have to release our xtal_pu
120+ * "force on" */
121+ if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
122+ ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
123+ } else {
124+ chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
125+ (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
126+ ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));
127+ }
128         break;
129     default:
130         SSB_WARN_ON(1);
131@@ -209,6 +235,24 @@ static void chipco_powercontrol_init(str
132     }
133 }
134 
135+/* http://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */
136+static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc)
137+{
138+ struct ssb_bus *bus = cc->dev->bus;
139+
140+ switch (bus->chip_id) {
141+ case 0x4312:
142+ case 0x4322:
143+ case 0x4328:
144+ return 7000;
145+ case 0x4325:
146+ /* TODO: */
147+ default:
148+ return 15000;
149+ }
150+}
151+
152+/* http://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */
153 static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)
154 {
155     struct ssb_bus *bus = cc->dev->bus;
156@@ -218,6 +262,12 @@ static void calc_fast_powerup_delay(stru
157 
158     if (bus->bustype != SSB_BUSTYPE_PCI)
159         return;
160+
161+ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
162+ cc->fast_pwrup_delay = pmu_fast_powerup_delay(cc);
163+ return;
164+ }
165+
166     if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
167         return;
168 
169@@ -233,6 +283,15 @@ void ssb_chipcommon_init(struct ssb_chip
170 {
171     if (!cc->dev)
172         return; /* We don't have a ChipCommon */
173+ if (cc->dev->id.revision >= 11)
174+ cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
175+ ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
176+
177+ if (cc->dev->id.revision >= 20) {
178+ chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);
179+ chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0);
180+ }
181+
182     ssb_pmu_init(cc);
183     chipco_powercontrol_init(cc);
184     ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
185@@ -370,6 +429,7 @@ u32 ssb_chipco_gpio_control(struct ssb_c
186 {
187     return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
188 }
189+EXPORT_SYMBOL(ssb_chipco_gpio_control);
190 
191 u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
192 {
193--- a/drivers/ssb/driver_chipcommon_pmu.c
194+++ b/drivers/ssb/driver_chipcommon_pmu.c
195@@ -28,6 +28,21 @@ static void ssb_chipco_pll_write(struct
196     chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value);
197 }
198 
199+static void ssb_chipco_regctl_maskset(struct ssb_chipcommon *cc,
200+ u32 offset, u32 mask, u32 set)
201+{
202+ u32 value;
203+
204+ chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
205+ chipco_write32(cc, SSB_CHIPCO_REGCTL_ADDR, offset);
206+ chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
207+ value = chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
208+ value &= mask;
209+ value |= set;
210+ chipco_write32(cc, SSB_CHIPCO_REGCTL_DATA, value);
211+ chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
212+}
213+
214 struct pmu0_plltab_entry {
215     u16 freq; /* Crystal frequency in kHz.*/
216     u8 xf; /* Crystal frequency value for PMU control */
217@@ -317,6 +332,12 @@ static void ssb_pmu_pll_init(struct ssb_
218     case 0x5354:
219         ssb_pmu0_pllinit_r0(cc, crystalfreq);
220         break;
221+ case 0x4322:
222+ if (cc->pmu.rev == 2) {
223+ chipco_write32(cc, SSB_CHIPCO_PLLCTL_ADDR, 0x0000000A);
224+ chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0);
225+ }
226+ break;
227     default:
228         ssb_printk(KERN_ERR PFX
229                "ERROR: PLL init unknown for device %04X\n",
230@@ -396,12 +417,15 @@ static void ssb_pmu_resources_init(struc
231     u32 min_msk = 0, max_msk = 0;
232     unsigned int i;
233     const struct pmu_res_updown_tab_entry *updown_tab = NULL;
234- unsigned int updown_tab_size;
235+ unsigned int updown_tab_size = 0;
236     const struct pmu_res_depend_tab_entry *depend_tab = NULL;
237- unsigned int depend_tab_size;
238+ unsigned int depend_tab_size = 0;
239 
240     switch (bus->chip_id) {
241     case 0x4312:
242+ min_msk = 0xCBB;
243+ break;
244+ case 0x4322:
245         /* We keep the default settings:
246          * min_msk = 0xCBB
247          * max_msk = 0x7FFFF
248@@ -480,9 +504,9 @@ static void ssb_pmu_resources_init(struc
249         chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk);
250 }
251 
252+/* http://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */
253 void ssb_pmu_init(struct ssb_chipcommon *cc)
254 {
255- struct ssb_bus *bus = cc->dev->bus;
256     u32 pmucap;
257 
258     if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU))
259@@ -494,15 +518,91 @@ void ssb_pmu_init(struct ssb_chipcommon
260     ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n",
261             cc->pmu.rev, pmucap);
262 
263- if (cc->pmu.rev >= 1) {
264- if ((bus->chip_id == 0x4325) && (bus->chip_rev < 2)) {
265- chipco_mask32(cc, SSB_CHIPCO_PMU_CTL,
266- ~SSB_CHIPCO_PMU_CTL_NOILPONW);
267- } else {
268- chipco_set32(cc, SSB_CHIPCO_PMU_CTL,
269- SSB_CHIPCO_PMU_CTL_NOILPONW);
270- }
271- }
272+ if (cc->pmu.rev == 1)
273+ chipco_mask32(cc, SSB_CHIPCO_PMU_CTL,
274+ ~SSB_CHIPCO_PMU_CTL_NOILPONW);
275+ else
276+ chipco_set32(cc, SSB_CHIPCO_PMU_CTL,
277+ SSB_CHIPCO_PMU_CTL_NOILPONW);
278     ssb_pmu_pll_init(cc);
279     ssb_pmu_resources_init(cc);
280 }
281+
282+void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
283+ enum ssb_pmu_ldo_volt_id id, u32 voltage)
284+{
285+ struct ssb_bus *bus = cc->dev->bus;
286+ u32 addr, shift, mask;
287+
288+ switch (bus->chip_id) {
289+ case 0x4328:
290+ case 0x5354:
291+ switch (id) {
292+ case LDO_VOLT1:
293+ addr = 2;
294+ shift = 25;
295+ mask = 0xF;
296+ break;
297+ case LDO_VOLT2:
298+ addr = 3;
299+ shift = 1;
300+ mask = 0xF;
301+ break;
302+ case LDO_VOLT3:
303+ addr = 3;
304+ shift = 9;
305+ mask = 0xF;
306+ break;
307+ case LDO_PAREF:
308+ addr = 3;
309+ shift = 17;
310+ mask = 0x3F;
311+ break;
312+ default:
313+ SSB_WARN_ON(1);
314+ return;
315+ }
316+ break;
317+ case 0x4312:
318+ if (SSB_WARN_ON(id != LDO_PAREF))
319+ return;
320+ addr = 0;
321+ shift = 21;
322+ mask = 0x3F;
323+ break;
324+ default:
325+ return;
326+ }
327+
328+ ssb_chipco_regctl_maskset(cc, addr, ~(mask << shift),
329+ (voltage & mask) << shift);
330+}
331+
332+void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
333+{
334+ struct ssb_bus *bus = cc->dev->bus;
335+ int ldo;
336+
337+ switch (bus->chip_id) {
338+ case 0x4312:
339+ ldo = SSB_PMURES_4312_PA_REF_LDO;
340+ break;
341+ case 0x4328:
342+ ldo = SSB_PMURES_4328_PA_REF_LDO;
343+ break;
344+ case 0x5354:
345+ ldo = SSB_PMURES_5354_PA_REF_LDO;
346+ break;
347+ default:
348+ return;
349+ }
350+
351+ if (on)
352+ chipco_set32(cc, SSB_CHIPCO_PMU_MINRES_MSK, 1 << ldo);
353+ else
354+ chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK, ~(1 << ldo));
355+ chipco_read32(cc, SSB_CHIPCO_PMU_MINRES_MSK); //SPEC FIXME found via mmiotrace - dummy read?
356+}
357+
358+EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
359+EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
360--- a/drivers/ssb/driver_gige.c
361+++ b/drivers/ssb/driver_gige.c
362@@ -12,6 +12,7 @@
363 #include <linux/ssb/ssb_driver_gige.h>
364 #include <linux/pci.h>
365 #include <linux/pci_regs.h>
366+#include <linux/slab.h>
367 
368 
369 /*
370@@ -105,8 +106,9 @@ void gige_pcicfg_write32(struct ssb_gige
371     gige_write32(dev, SSB_GIGE_PCICFG + offset, value);
372 }
373 
374-static int ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn,
375- int reg, int size, u32 *val)
376+static int __devinit ssb_gige_pci_read_config(struct pci_bus *bus,
377+ unsigned int devfn, int reg,
378+ int size, u32 *val)
379 {
380     struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
381     unsigned long flags;
382@@ -135,8 +137,9 @@ static int ssb_gige_pci_read_config(stru
383     return PCIBIOS_SUCCESSFUL;
384 }
385 
386-static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn,
387- int reg, int size, u32 val)
388+static int __devinit ssb_gige_pci_write_config(struct pci_bus *bus,
389+ unsigned int devfn, int reg,
390+ int size, u32 val)
391 {
392     struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
393     unsigned long flags;
394@@ -165,7 +168,8 @@ static int ssb_gige_pci_write_config(str
395     return PCIBIOS_SUCCESSFUL;
396 }
397 
398-static int ssb_gige_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
399+static int __devinit ssb_gige_probe(struct ssb_device *sdev,
400+ const struct ssb_device_id *id)
401 {
402     struct ssb_gige *dev;
403     u32 base, tmslow, tmshigh;
404--- a/drivers/ssb/driver_mipscore.c
405+++ b/drivers/ssb/driver_mipscore.c
406@@ -270,7 +270,6 @@ void ssb_mipscore_init(struct ssb_mipsco
407                 set_irq(dev, irq++);
408             }
409             break;
410- /* fallthrough */
411         case SSB_DEV_PCI:
412         case SSB_DEV_ETHERNET:
413         case SSB_DEV_ETHERNET_GBIT:
414@@ -281,6 +280,10 @@ void ssb_mipscore_init(struct ssb_mipsco
415                 set_irq(dev, irq++);
416                 break;
417             }
418+ /* fallthrough */
419+ case SSB_DEV_EXTIF:
420+ set_irq(dev, 0);
421+ break;
422         }
423     }
424     ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n");
425--- a/drivers/ssb/driver_pcicore.c
426+++ b/drivers/ssb/driver_pcicore.c
427@@ -15,6 +15,11 @@
428 
429 #include "ssb_private.h"
430 
431+static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address);
432+static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data);
433+static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
434+static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
435+ u8 address, u16 data);
436 
437 static inline
438 u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
439@@ -246,20 +251,12 @@ static struct pci_controller ssb_pcicore
440     .pci_ops = &ssb_pcicore_pciops,
441     .io_resource = &ssb_pcicore_io_resource,
442     .mem_resource = &ssb_pcicore_mem_resource,
443- .mem_offset = 0x24000000,
444 };
445 
446-static u32 ssb_pcicore_pcibus_iobase = 0x100;
447-static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
448-
449 /* This function is called when doing a pci_enable_device().
450  * We must first check if the device is a device on the PCI-core bridge. */
451 int ssb_pcicore_plat_dev_init(struct pci_dev *d)
452 {
453- struct resource *res;
454- int pos, size;
455- u32 *base;
456-
457     if (d->bus->ops != &ssb_pcicore_pciops) {
458         /* This is not a device on the PCI-core bridge. */
459         return -ENODEV;
460@@ -268,27 +265,6 @@ int ssb_pcicore_plat_dev_init(struct pci
461     ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
462            pci_name(d));
463 
464- /* Fix up resource bases */
465- for (pos = 0; pos < 6; pos++) {
466- res = &d->resource[pos];
467- if (res->flags & IORESOURCE_IO)
468- base = &ssb_pcicore_pcibus_iobase;
469- else
470- base = &ssb_pcicore_pcibus_membase;
471- res->flags |= IORESOURCE_PCI_FIXED;
472- if (res->end) {
473- size = res->end - res->start + 1;
474- if (*base & (size - 1))
475- *base = (*base + size) & ~(size - 1);
476- res->start = *base;
477- res->end = res->start + size - 1;
478- *base += size;
479- pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
480- }
481- /* Fix up PCI bridge BAR0 only */
482- if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
483- break;
484- }
485     /* Fix up interrupt lines */
486     d->irq = ssb_mips_irq(extpci_core->dev) + 2;
487     pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
488@@ -338,7 +314,7 @@ int ssb_pcicore_pcibios_map_irq(const st
489     return ssb_mips_irq(extpci_core->dev) + 2;
490 }
491 
492-static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
493+static void __devinit ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
494 {
495     u32 val;
496 
497@@ -403,7 +379,7 @@ static void ssb_pcicore_init_hostmode(st
498     register_pci_controller(&ssb_pcicore_controller);
499 }
500 
501-static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
502+static int __devinit pcicore_is_in_hostmode(struct ssb_pcicore *pc)
503 {
504     struct ssb_bus *bus = pc->dev->bus;
505     u16 chipid_top;
506@@ -432,25 +408,133 @@ static int pcicore_is_in_hostmode(struct
507 }
508 #endif /* CONFIG_SSB_PCICORE_HOSTMODE */
509 
510+/**************************************************
511+ * Workarounds.
512+ **************************************************/
513+
514+static void __devinit ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
515+{
516+ u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
517+ if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
518+ tmp &= ~0xF000;
519+ tmp |= (pc->dev->core_index << 12);
520+ pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
521+ }
522+}
523+
524+static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
525+{
526+ return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
527+}
528+
529+static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
530+{
531+ const u8 serdes_pll_device = 0x1D;
532+ const u8 serdes_rx_device = 0x1F;
533+ u16 tmp;
534+
535+ ssb_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
536+ ssb_pcicore_polarity_workaround(pc));
537+ tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
538+ if (tmp & 0x4000)
539+ ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
540+}
541+
542+static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
543+{
544+ struct ssb_device *pdev = pc->dev;
545+ struct ssb_bus *bus = pdev->bus;
546+ u32 tmp;
547+
548+ tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
549+ tmp |= SSB_PCICORE_SBTOPCI_PREF;
550+ tmp |= SSB_PCICORE_SBTOPCI_BURST;
551+ pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
552+
553+ if (pdev->id.revision < 5) {
554+ tmp = ssb_read32(pdev, SSB_IMCFGLO);
555+ tmp &= ~SSB_IMCFGLO_SERTO;
556+ tmp |= 2;
557+ tmp &= ~SSB_IMCFGLO_REQTO;
558+ tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
559+ ssb_write32(pdev, SSB_IMCFGLO, tmp);
560+ ssb_commit_settings(bus);
561+ } else if (pdev->id.revision >= 11) {
562+ tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
563+ tmp |= SSB_PCICORE_SBTOPCI_MRM;
564+ pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
565+ }
566+}
567+
568+static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
569+{
570+ u32 tmp;
571+ u8 rev = pc->dev->id.revision;
572+
573+ if (rev == 0 || rev == 1) {
574+ /* TLP Workaround register. */
575+ tmp = ssb_pcie_read(pc, 0x4);
576+ tmp |= 0x8;
577+ ssb_pcie_write(pc, 0x4, tmp);
578+ }
579+ if (rev == 1) {
580+ /* DLLP Link Control register. */
581+ tmp = ssb_pcie_read(pc, 0x100);
582+ tmp |= 0x40;
583+ ssb_pcie_write(pc, 0x100, tmp);
584+ }
585+
586+ if (rev == 0) {
587+ const u8 serdes_rx_device = 0x1F;
588+
589+ ssb_pcie_mdio_write(pc, serdes_rx_device,
590+ 2 /* Timer */, 0x8128);
591+ ssb_pcie_mdio_write(pc, serdes_rx_device,
592+ 6 /* CDR */, 0x0100);
593+ ssb_pcie_mdio_write(pc, serdes_rx_device,
594+ 7 /* CDR BW */, 0x1466);
595+ } else if (rev == 3 || rev == 4 || rev == 5) {
596+ /* TODO: DLLP Power Management Threshold */
597+ ssb_pcicore_serdes_workaround(pc);
598+ /* TODO: ASPM */
599+ } else if (rev == 7) {
600+ /* TODO: No PLL down */
601+ }
602+
603+ if (rev >= 6) {
604+ /* Miscellaneous Configuration Fixup */
605+ tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
606+ if (!(tmp & 0x8000))
607+ pcicore_write16(pc, SSB_PCICORE_SPROM(5),
608+ tmp | 0x8000);
609+ }
610+}
611 
612 /**************************************************
613  * Generic and Clientmode operation code.
614  **************************************************/
615 
616-static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
617+static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
618 {
619+ ssb_pcicore_fix_sprom_core_index(pc);
620+
621     /* Disable PCI interrupts. */
622     ssb_write32(pc->dev, SSB_INTVEC, 0);
623+
624+ /* Additional PCIe always once-executed workarounds */
625+ if (pc->dev->id.coreid == SSB_DEV_PCIE) {
626+ ssb_pcicore_serdes_workaround(pc);
627+ /* TODO: ASPM */
628+ /* TODO: Clock Request Update */
629+ }
630 }
631 
632-void ssb_pcicore_init(struct ssb_pcicore *pc)
633+void __devinit ssb_pcicore_init(struct ssb_pcicore *pc)
634 {
635     struct ssb_device *dev = pc->dev;
636- struct ssb_bus *bus;
637 
638     if (!dev)
639         return;
640- bus = dev->bus;
641     if (!ssb_device_is_enabled(dev))
642         ssb_device_enable(dev, 0);
643 
644@@ -475,58 +559,104 @@ static void ssb_pcie_write(struct ssb_pc
645     pcicore_write32(pc, 0x134, data);
646 }
647 
648-static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
649- u8 address, u16 data)
650+static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy)
651 {
652     const u16 mdio_control = 0x128;
653     const u16 mdio_data = 0x12C;
654     u32 v;
655     int i;
656 
657+ v = (1 << 30); /* Start of Transaction */
658+ v |= (1 << 28); /* Write Transaction */
659+ v |= (1 << 17); /* Turnaround */
660+ v |= (0x1F << 18);
661+ v |= (phy << 4);
662+ pcicore_write32(pc, mdio_data, v);
663+
664+ udelay(10);
665+ for (i = 0; i < 200; i++) {
666+ v = pcicore_read32(pc, mdio_control);
667+ if (v & 0x100 /* Trans complete */)
668+ break;
669+ msleep(1);
670+ }
671+}
672+
673+static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
674+{
675+ const u16 mdio_control = 0x128;
676+ const u16 mdio_data = 0x12C;
677+ int max_retries = 10;
678+ u16 ret = 0;
679+ u32 v;
680+ int i;
681+
682     v = 0x80; /* Enable Preamble Sequence */
683     v |= 0x2; /* MDIO Clock Divisor */
684     pcicore_write32(pc, mdio_control, v);
685 
686+ if (pc->dev->id.revision >= 10) {
687+ max_retries = 200;
688+ ssb_pcie_mdio_set_phy(pc, device);
689+ }
690+
691     v = (1 << 30); /* Start of Transaction */
692- v |= (1 << 28); /* Write Transaction */
693+ v |= (1 << 29); /* Read Transaction */
694     v |= (1 << 17); /* Turnaround */
695- v |= (u32)device << 22;
696+ if (pc->dev->id.revision < 10)
697+ v |= (u32)device << 22;
698     v |= (u32)address << 18;
699- v |= data;
700     pcicore_write32(pc, mdio_data, v);
701     /* Wait for the device to complete the transaction */
702     udelay(10);
703- for (i = 0; i < 10; i++) {
704+ for (i = 0; i < max_retries; i++) {
705         v = pcicore_read32(pc, mdio_control);
706- if (v & 0x100 /* Trans complete */)
707+ if (v & 0x100 /* Trans complete */) {
708+ udelay(10);
709+ ret = pcicore_read32(pc, mdio_data);
710             break;
711+ }
712         msleep(1);
713     }
714     pcicore_write32(pc, mdio_control, 0);
715+ return ret;
716 }
717 
718-static void ssb_broadcast_value(struct ssb_device *dev,
719- u32 address, u32 data)
720+static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
721+ u8 address, u16 data)
722 {
723- /* This is used for both, PCI and ChipCommon core, so be careful. */
724- BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
725- BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
726+ const u16 mdio_control = 0x128;
727+ const u16 mdio_data = 0x12C;
728+ int max_retries = 10;
729+ u32 v;
730+ int i;
731 
732- ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address);
733- ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
734- ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
735- ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
736-}
737+ v = 0x80; /* Enable Preamble Sequence */
738+ v |= 0x2; /* MDIO Clock Divisor */
739+ pcicore_write32(pc, mdio_control, v);
740 
741-static void ssb_commit_settings(struct ssb_bus *bus)
742-{
743- struct ssb_device *dev;
744+ if (pc->dev->id.revision >= 10) {
745+ max_retries = 200;
746+ ssb_pcie_mdio_set_phy(pc, device);
747+ }
748 
749- dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
750- if (WARN_ON(!dev))
751- return;
752- /* This forces an update of the cached registers. */
753- ssb_broadcast_value(dev, 0xFD8, 0);
754+ v = (1 << 30); /* Start of Transaction */
755+ v |= (1 << 28); /* Write Transaction */
756+ v |= (1 << 17); /* Turnaround */
757+ if (pc->dev->id.revision < 10)
758+ v |= (u32)device << 22;
759+ v |= (u32)address << 18;
760+ v |= data;
761+ pcicore_write32(pc, mdio_data, v);
762+ /* Wait for the device to complete the transaction */
763+ udelay(10);
764+ for (i = 0; i < max_retries; i++) {
765+ v = pcicore_read32(pc, mdio_control);
766+ if (v & 0x100 /* Trans complete */)
767+ break;
768+ msleep(1);
769+ }
770+ pcicore_write32(pc, mdio_control, 0);
771 }
772 
773 int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
774@@ -551,13 +681,13 @@ int ssb_pcicore_dev_irqvecs_enable(struc
775     might_sleep_if(pdev->id.coreid != SSB_DEV_PCI);
776 
777     /* Enable interrupts for this device. */
778- if (bus->host_pci &&
779- ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE))) {
780+ if ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE)) {
781         u32 coremask;
782 
783         /* Calculate the "coremask" for the device. */
784         coremask = (1 << dev->core_index);
785 
786+ SSB_WARN_ON(bus->bustype != SSB_BUSTYPE_PCI);
787         err = pci_read_config_dword(bus->host_pci, SSB_PCI_IRQMASK, &tmp);
788         if (err)
789             goto out;
790@@ -579,48 +709,10 @@ int ssb_pcicore_dev_irqvecs_enable(struc
791     if (pc->setup_done)
792         goto out;
793     if (pdev->id.coreid == SSB_DEV_PCI) {
794- tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
795- tmp |= SSB_PCICORE_SBTOPCI_PREF;
796- tmp |= SSB_PCICORE_SBTOPCI_BURST;
797- pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
798-
799- if (pdev->id.revision < 5) {
800- tmp = ssb_read32(pdev, SSB_IMCFGLO);
801- tmp &= ~SSB_IMCFGLO_SERTO;
802- tmp |= 2;
803- tmp &= ~SSB_IMCFGLO_REQTO;
804- tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
805- ssb_write32(pdev, SSB_IMCFGLO, tmp);
806- ssb_commit_settings(bus);
807- } else if (pdev->id.revision >= 11) {
808- tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
809- tmp |= SSB_PCICORE_SBTOPCI_MRM;
810- pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
811- }
812+ ssb_pcicore_pci_setup_workarounds(pc);
813     } else {
814         WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
815- //TODO: Better make defines for all these magic PCIE values.
816- if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
817- /* TLP Workaround register. */
818- tmp = ssb_pcie_read(pc, 0x4);
819- tmp |= 0x8;
820- ssb_pcie_write(pc, 0x4, tmp);
821- }
822- if (pdev->id.revision == 0) {
823- const u8 serdes_rx_device = 0x1F;
824-
825- ssb_pcie_mdio_write(pc, serdes_rx_device,
826- 2 /* Timer */, 0x8128);
827- ssb_pcie_mdio_write(pc, serdes_rx_device,
828- 6 /* CDR */, 0x0100);
829- ssb_pcie_mdio_write(pc, serdes_rx_device,
830- 7 /* CDR BW */, 0x1466);
831- } else if (pdev->id.revision == 1) {
832- /* DLLP Link Control register. */
833- tmp = ssb_pcie_read(pc, 0x100);
834- tmp |= 0x40;
835- ssb_pcie_write(pc, 0x100, tmp);
836- }
837+ ssb_pcicore_pcie_setup_workarounds(pc);
838     }
839     pc->setup_done = 1;
840 out:
841--- a/drivers/ssb/main.c
842+++ b/drivers/ssb/main.c
843@@ -17,6 +17,8 @@
844 #include <linux/ssb/ssb_driver_gige.h>
845 #include <linux/dma-mapping.h>
846 #include <linux/pci.h>
847+#include <linux/mmc/sdio_func.h>
848+#include <linux/slab.h>
849 
850 #include <pcmcia/cs_types.h>
851 #include <pcmcia/cs.h>
852@@ -88,6 +90,25 @@ found:
853 }
854 #endif /* CONFIG_SSB_PCMCIAHOST */
855 
856+#ifdef CONFIG_SSB_SDIOHOST
857+struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func)
858+{
859+ struct ssb_bus *bus;
860+
861+ ssb_buses_lock();
862+ list_for_each_entry(bus, &buses, list) {
863+ if (bus->bustype == SSB_BUSTYPE_SDIO &&
864+ bus->host_sdio == func)
865+ goto found;
866+ }
867+ bus = NULL;
868+found:
869+ ssb_buses_unlock();
870+
871+ return bus;
872+}
873+#endif /* CONFIG_SSB_SDIOHOST */
874+
875 int ssb_for_each_bus_call(unsigned long data,
876               int (*func)(struct ssb_bus *bus, unsigned long data))
877 {
878@@ -120,6 +141,19 @@ static void ssb_device_put(struct ssb_de
879         put_device(dev->dev);
880 }
881 
882+static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv)
883+{
884+ if (drv)
885+ get_driver(&drv->drv);
886+ return drv;
887+}
888+
889+static inline void ssb_driver_put(struct ssb_driver *drv)
890+{
891+ if (drv)
892+ put_driver(&drv->drv);
893+}
894+
895 static int ssb_device_resume(struct device *dev)
896 {
897     struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
898@@ -190,90 +224,81 @@ int ssb_bus_suspend(struct ssb_bus *bus)
899 EXPORT_SYMBOL(ssb_bus_suspend);
900 
901 #ifdef CONFIG_SSB_SPROM
902-int ssb_devices_freeze(struct ssb_bus *bus)
903+/** ssb_devices_freeze - Freeze all devices on the bus.
904+ *
905+ * After freezing no device driver will be handling a device
906+ * on this bus anymore. ssb_devices_thaw() must be called after
907+ * a successful freeze to reactivate the devices.
908+ *
909+ * @bus: The bus.
910+ * @ctx: Context structure. Pass this to ssb_devices_thaw().
911+ */
912+int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx)
913 {
914- struct ssb_device *dev;
915- struct ssb_driver *drv;
916- int err = 0;
917- int i;
918- pm_message_t state = PMSG_FREEZE;
919+ struct ssb_device *sdev;
920+ struct ssb_driver *sdrv;
921+ unsigned int i;
922+
923+ memset(ctx, 0, sizeof(*ctx));
924+ ctx->bus = bus;
925+ SSB_WARN_ON(bus->nr_devices > ARRAY_SIZE(ctx->device_frozen));
926 
927- /* First check that we are capable to freeze all devices. */
928     for (i = 0; i < bus->nr_devices; i++) {
929- dev = &(bus->devices[i]);
930- if (!dev->dev ||
931- !dev->dev->driver ||
932- !device_is_registered(dev->dev))
933- continue;
934- drv = drv_to_ssb_drv(dev->dev->driver);
935- if (!drv)
936+ sdev = ssb_device_get(&bus->devices[i]);
937+
938+ if (!sdev->dev || !sdev->dev->driver ||
939+ !device_is_registered(sdev->dev)) {
940+ ssb_device_put(sdev);
941             continue;
942- if (!drv->suspend) {
943- /* Nope, can't suspend this one. */
944- return -EOPNOTSUPP;
945         }
946- }
947- /* Now suspend all devices */
948- for (i = 0; i < bus->nr_devices; i++) {
949- dev = &(bus->devices[i]);
950- if (!dev->dev ||
951- !dev->dev->driver ||
952- !device_is_registered(dev->dev))
953- continue;
954- drv = drv_to_ssb_drv(dev->dev->driver);
955- if (!drv)
956+ sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver));
957+ if (!sdrv || SSB_WARN_ON(!sdrv->remove)) {
958+ ssb_device_put(sdev);
959             continue;
960- err = drv->suspend(dev, state);
961- if (err) {
962- ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n",
963- dev_name(dev->dev));
964- goto err_unwind;
965         }
966+ sdrv->remove(sdev);
967+ ctx->device_frozen[i] = 1;
968     }
969 
970     return 0;
971-err_unwind:
972- for (i--; i >= 0; i--) {
973- dev = &(bus->devices[i]);
974- if (!dev->dev ||
975- !dev->dev->driver ||
976- !device_is_registered(dev->dev))
977- continue;
978- drv = drv_to_ssb_drv(dev->dev->driver);
979- if (!drv)
980- continue;
981- if (drv->resume)
982- drv->resume(dev);
983- }
984- return err;
985 }
986 
987-int ssb_devices_thaw(struct ssb_bus *bus)
988+/** ssb_devices_thaw - Unfreeze all devices on the bus.
989+ *
990+ * This will re-attach the device drivers and re-init the devices.
991+ *
992+ * @ctx: The context structure from ssb_devices_freeze()
993+ */
994+int ssb_devices_thaw(struct ssb_freeze_context *ctx)
995 {
996- struct ssb_device *dev;
997- struct ssb_driver *drv;
998- int err;
999- int i;
1000+ struct ssb_bus *bus = ctx->bus;
1001+ struct ssb_device *sdev;
1002+ struct ssb_driver *sdrv;
1003+ unsigned int i;
1004+ int err, result = 0;
1005 
1006     for (i = 0; i < bus->nr_devices; i++) {
1007- dev = &(bus->devices[i]);
1008- if (!dev->dev ||
1009- !dev->dev->driver ||
1010- !device_is_registered(dev->dev))
1011+ if (!ctx->device_frozen[i])
1012             continue;
1013- drv = drv_to_ssb_drv(dev->dev->driver);
1014- if (!drv)
1015+ sdev = &bus->devices[i];
1016+
1017+ if (SSB_WARN_ON(!sdev->dev || !sdev->dev->driver))
1018             continue;
1019- if (SSB_WARN_ON(!drv->resume))
1020+ sdrv = drv_to_ssb_drv(sdev->dev->driver);
1021+ if (SSB_WARN_ON(!sdrv || !sdrv->probe))
1022             continue;
1023- err = drv->resume(dev);
1024+
1025+ err = sdrv->probe(sdev, &sdev->id);
1026         if (err) {
1027             ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n",
1028- dev_name(dev->dev));
1029+ dev_name(sdev->dev));
1030+ result = err;
1031         }
1032+ ssb_driver_put(sdrv);
1033+ ssb_device_put(sdev);
1034     }
1035 
1036- return 0;
1037+ return result;
1038 }
1039 #endif /* CONFIG_SSB_SPROM */
1040 
1041@@ -360,6 +385,35 @@ static int ssb_device_uevent(struct devi
1042                  ssb_dev->id.revision);
1043 }
1044 
1045+#define ssb_config_attr(attrib, field, format_string) \
1046+static ssize_t \
1047+attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \
1048+{ \
1049+ return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \
1050+}
1051+
1052+ssb_config_attr(core_num, core_index, "%u\n")
1053+ssb_config_attr(coreid, id.coreid, "0x%04x\n")
1054+ssb_config_attr(vendor, id.vendor, "0x%04x\n")
1055+ssb_config_attr(revision, id.revision, "%u\n")
1056+ssb_config_attr(irq, irq, "%u\n")
1057+static ssize_t
1058+name_show(struct device *dev, struct device_attribute *attr, char *buf)
1059+{
1060+ return sprintf(buf, "%s\n",
1061+ ssb_core_name(dev_to_ssb_dev(dev)->id.coreid));
1062+}
1063+
1064+static struct device_attribute ssb_device_attrs[] = {
1065+ __ATTR_RO(name),
1066+ __ATTR_RO(core_num),
1067+ __ATTR_RO(coreid),
1068+ __ATTR_RO(vendor),
1069+ __ATTR_RO(revision),
1070+ __ATTR_RO(irq),
1071+ __ATTR_NULL,
1072+};
1073+
1074 static struct bus_type ssb_bustype = {
1075     .name = "ssb",
1076     .match = ssb_bus_match,
1077@@ -369,6 +423,7 @@ static struct bus_type ssb_bustype = {
1078     .suspend = ssb_device_suspend,
1079     .resume = ssb_device_resume,
1080     .uevent = ssb_device_uevent,
1081+ .dev_attrs = ssb_device_attrs,
1082 };
1083 
1084 static void ssb_buses_lock(void)
1085@@ -461,6 +516,7 @@ static int ssb_devices_register(struct s
1086 #ifdef CONFIG_SSB_PCIHOST
1087             sdev->irq = bus->host_pci->irq;
1088             dev->parent = &bus->host_pci->dev;
1089+ sdev->dma_dev = dev->parent;
1090 #endif
1091             break;
1092         case SSB_BUSTYPE_PCMCIA:
1093@@ -469,8 +525,14 @@ static int ssb_devices_register(struct s
1094             dev->parent = &bus->host_pcmcia->dev;
1095 #endif
1096             break;
1097+ case SSB_BUSTYPE_SDIO:
1098+#ifdef CONFIG_SSB_SDIOHOST
1099+ dev->parent = &bus->host_sdio->dev;
1100+#endif
1101+ break;
1102         case SSB_BUSTYPE_SSB:
1103             dev->dma_mask = &dev->coherent_dma_mask;
1104+ sdev->dma_dev = dev;
1105             break;
1106         }
1107 
1108@@ -497,7 +559,7 @@ error:
1109 }
1110 
1111 /* Needs ssb_buses_lock() */
1112-static int ssb_attach_queued_buses(void)
1113+static int __devinit ssb_attach_queued_buses(void)
1114 {
1115     struct ssb_bus *bus, *n;
1116     int err = 0;
1117@@ -708,9 +770,9 @@ out:
1118     return err;
1119 }
1120 
1121-static int ssb_bus_register(struct ssb_bus *bus,
1122- ssb_invariants_func_t get_invariants,
1123- unsigned long baseaddr)
1124+static int __devinit ssb_bus_register(struct ssb_bus *bus,
1125+ ssb_invariants_func_t get_invariants,
1126+ unsigned long baseaddr)
1127 {
1128     int err;
1129 
1130@@ -724,12 +786,18 @@ static int ssb_bus_register(struct ssb_b
1131     err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
1132     if (err)
1133         goto out;
1134+
1135+ /* Init SDIO-host device (if any), before the scan */
1136+ err = ssb_sdio_init(bus);
1137+ if (err)
1138+ goto err_disable_xtal;
1139+
1140     ssb_buses_lock();
1141     bus->busnumber = next_busnumber;
1142     /* Scan for devices (cores) */
1143     err = ssb_bus_scan(bus, baseaddr);
1144     if (err)
1145- goto err_disable_xtal;
1146+ goto err_sdio_exit;
1147 
1148     /* Init PCI-host device (if any) */
1149     err = ssb_pci_init(bus);
1150@@ -776,6 +844,8 @@ err_pci_exit:
1151     ssb_pci_exit(bus);
1152 err_unmap:
1153     ssb_iounmap(bus);
1154+err_sdio_exit:
1155+ ssb_sdio_exit(bus);
1156 err_disable_xtal:
1157     ssb_buses_unlock();
1158     ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
1159@@ -783,8 +853,8 @@ err_disable_xtal:
1160 }
1161 
1162 #ifdef CONFIG_SSB_PCIHOST
1163-int ssb_bus_pcibus_register(struct ssb_bus *bus,
1164- struct pci_dev *host_pci)
1165+int __devinit ssb_bus_pcibus_register(struct ssb_bus *bus,
1166+ struct pci_dev *host_pci)
1167 {
1168     int err;
1169 
1170@@ -796,6 +866,9 @@ int ssb_bus_pcibus_register(struct ssb_b
1171     if (!err) {
1172         ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
1173                "PCI device %s\n", dev_name(&host_pci->dev));
1174+ } else {
1175+ ssb_printk(KERN_ERR PFX "Failed to register PCI version"
1176+ " of SSB with error %d\n", err);
1177     }
1178 
1179     return err;
1180@@ -804,9 +877,9 @@ EXPORT_SYMBOL(ssb_bus_pcibus_register);
1181 #endif /* CONFIG_SSB_PCIHOST */
1182 
1183 #ifdef CONFIG_SSB_PCMCIAHOST
1184-int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
1185- struct pcmcia_device *pcmcia_dev,
1186- unsigned long baseaddr)
1187+int __devinit ssb_bus_pcmciabus_register(struct ssb_bus *bus,
1188+ struct pcmcia_device *pcmcia_dev,
1189+ unsigned long baseaddr)
1190 {
1191     int err;
1192 
1193@@ -825,9 +898,32 @@ int ssb_bus_pcmciabus_register(struct ss
1194 EXPORT_SYMBOL(ssb_bus_pcmciabus_register);
1195 #endif /* CONFIG_SSB_PCMCIAHOST */
1196 
1197-int ssb_bus_ssbbus_register(struct ssb_bus *bus,
1198- unsigned long baseaddr,
1199- ssb_invariants_func_t get_invariants)
1200+#ifdef CONFIG_SSB_SDIOHOST
1201+int __devinit ssb_bus_sdiobus_register(struct ssb_bus *bus,
1202+ struct sdio_func *func,
1203+ unsigned int quirks)
1204+{
1205+ int err;
1206+
1207+ bus->bustype = SSB_BUSTYPE_SDIO;
1208+ bus->host_sdio = func;
1209+ bus->ops = &ssb_sdio_ops;
1210+ bus->quirks = quirks;
1211+
1212+ err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0);
1213+ if (!err) {
1214+ ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
1215+ "SDIO device %s\n", sdio_func_id(func));
1216+ }
1217+
1218+ return err;
1219+}
1220+EXPORT_SYMBOL(ssb_bus_sdiobus_register);
1221+#endif /* CONFIG_SSB_PCMCIAHOST */
1222+
1223+int __devinit ssb_bus_ssbbus_register(struct ssb_bus *bus,
1224+ unsigned long baseaddr,
1225+ ssb_invariants_func_t get_invariants)
1226 {
1227     int err;
1228 
1229@@ -908,8 +1004,8 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
1230     switch (plltype) {
1231     case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
1232         if (m & SSB_CHIPCO_CLK_T6_MMASK)
1233- return SSB_CHIPCO_CLK_T6_M0;
1234- return SSB_CHIPCO_CLK_T6_M1;
1235+ return SSB_CHIPCO_CLK_T6_M1;
1236+ return SSB_CHIPCO_CLK_T6_M0;
1237     case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
1238     case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
1239     case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
1240@@ -1024,23 +1120,22 @@ static u32 ssb_tmslow_reject_bitmask(str
1241 {
1242     u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
1243 
1244- /* The REJECT bit changed position in TMSLOW between
1245- * Backplane revisions. */
1246+ /* The REJECT bit seems to be different for Backplane rev 2.3 */
1247     switch (rev) {
1248     case SSB_IDLOW_SSBREV_22:
1249- return SSB_TMSLOW_REJECT_22;
1250+ case SSB_IDLOW_SSBREV_24:
1251+ case SSB_IDLOW_SSBREV_26:
1252+ return SSB_TMSLOW_REJECT;
1253     case SSB_IDLOW_SSBREV_23:
1254         return SSB_TMSLOW_REJECT_23;
1255- case SSB_IDLOW_SSBREV_24: /* TODO - find the proper REJECT bits */
1256- case SSB_IDLOW_SSBREV_25: /* same here */
1257- case SSB_IDLOW_SSBREV_26: /* same here */
1258+ case SSB_IDLOW_SSBREV_25: /* TODO - find the proper REJECT bit */
1259     case SSB_IDLOW_SSBREV_27: /* same here */
1260- return SSB_TMSLOW_REJECT_23; /* this is a guess */
1261+ return SSB_TMSLOW_REJECT; /* this is a guess */
1262     default:
1263         printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
1264         WARN_ON(1);
1265     }
1266- return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
1267+ return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23);
1268 }
1269 
1270 int ssb_device_is_enabled(struct ssb_device *dev)
1271@@ -1099,10 +1194,10 @@ void ssb_device_enable(struct ssb_device
1272 }
1273 EXPORT_SYMBOL(ssb_device_enable);
1274 
1275-/* Wait for a bit in a register to get set or unset.
1276+/* Wait for bitmask in a register to get set or cleared.
1277  * timeout is in units of ten-microseconds */
1278-static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
1279- int timeout, int set)
1280+static int ssb_wait_bits(struct ssb_device *dev, u16 reg, u32 bitmask,
1281+ int timeout, int set)
1282 {
1283     int i;
1284     u32 val;
1285@@ -1110,7 +1205,7 @@ static int ssb_wait_bit(struct ssb_devic
1286     for (i = 0; i < timeout; i++) {
1287         val = ssb_read32(dev, reg);
1288         if (set) {
1289- if (val & bitmask)
1290+ if ((val & bitmask) == bitmask)
1291                 return 0;
1292         } else {
1293             if (!(val & bitmask))
1294@@ -1127,20 +1222,38 @@ static int ssb_wait_bit(struct ssb_devic
1295 
1296 void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
1297 {
1298- u32 reject;
1299+ u32 reject, val;
1300 
1301     if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
1302         return;
1303 
1304     reject = ssb_tmslow_reject_bitmask(dev);
1305- ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
1306- ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1);
1307- ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
1308- ssb_write32(dev, SSB_TMSLOW,
1309- SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
1310- reject | SSB_TMSLOW_RESET |
1311- core_specific_flags);
1312- ssb_flush_tmslow(dev);
1313+
1314+ if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_CLOCK) {
1315+ ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
1316+ ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1);
1317+ ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
1318+
1319+ if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
1320+ val = ssb_read32(dev, SSB_IMSTATE);
1321+ val |= SSB_IMSTATE_REJECT;
1322+ ssb_write32(dev, SSB_IMSTATE, val);
1323+ ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000,
1324+ 0);
1325+ }
1326+
1327+ ssb_write32(dev, SSB_TMSLOW,
1328+ SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
1329+ reject | SSB_TMSLOW_RESET |
1330+ core_specific_flags);
1331+ ssb_flush_tmslow(dev);
1332+
1333+ if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
1334+ val = ssb_read32(dev, SSB_IMSTATE);
1335+ val &= ~SSB_IMSTATE_REJECT;
1336+ ssb_write32(dev, SSB_IMSTATE, val);
1337+ }
1338+ }
1339 
1340     ssb_write32(dev, SSB_TMSLOW,
1341             reject | SSB_TMSLOW_RESET |
1342@@ -1155,7 +1268,10 @@ u32 ssb_dma_translation(struct ssb_devic
1343     case SSB_BUSTYPE_SSB:
1344         return 0;
1345     case SSB_BUSTYPE_PCI:
1346- return SSB_PCI_DMA;
1347+ if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64)
1348+ return SSB_PCIE_DMA_H32;
1349+ else
1350+ return SSB_PCI_DMA;
1351     default:
1352         __ssb_dma_not_implemented(dev);
1353     }
1354@@ -1272,20 +1388,20 @@ EXPORT_SYMBOL(ssb_bus_may_powerdown);
1355 
1356 int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
1357 {
1358- struct ssb_chipcommon *cc;
1359     int err;
1360     enum ssb_clkmode mode;
1361 
1362     err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
1363     if (err)
1364         goto error;
1365- cc = &bus->chipco;
1366- mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
1367- ssb_chipco_set_clockmode(cc, mode);
1368 
1369 #ifdef CONFIG_SSB_DEBUG
1370     bus->powered_up = 1;
1371 #endif
1372+
1373+ mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
1374+ ssb_chipco_set_clockmode(&bus->chipco, mode);
1375+
1376     return 0;
1377 error:
1378     ssb_printk(KERN_ERR PFX "Bus powerup failed\n");
1379@@ -1293,6 +1409,37 @@ error:
1380 }
1381 EXPORT_SYMBOL(ssb_bus_powerup);
1382 
1383+static void ssb_broadcast_value(struct ssb_device *dev,
1384+ u32 address, u32 data)
1385+{
1386+#ifdef CONFIG_SSB_DRIVER_PCICORE
1387+ /* This is used for both, PCI and ChipCommon core, so be careful. */
1388+ BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
1389+ BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
1390+#endif
1391+
1392+ ssb_write32(dev, SSB_CHIPCO_BCAST_ADDR, address);
1393+ ssb_read32(dev, SSB_CHIPCO_BCAST_ADDR); /* flush */
1394+ ssb_write32(dev, SSB_CHIPCO_BCAST_DATA, data);
1395+ ssb_read32(dev, SSB_CHIPCO_BCAST_DATA); /* flush */
1396+}
1397+
1398+void ssb_commit_settings(struct ssb_bus *bus)
1399+{
1400+ struct ssb_device *dev;
1401+
1402+#ifdef CONFIG_SSB_DRIVER_PCICORE
1403+ dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
1404+#else
1405+ dev = bus->chipco.dev;
1406+#endif
1407+ if (WARN_ON(!dev))
1408+ return;
1409+ /* This forces an update of the cached registers. */
1410+ ssb_broadcast_value(dev, 0xFD8, 0);
1411+}
1412+EXPORT_SYMBOL(ssb_commit_settings);
1413+
1414 u32 ssb_admatch_base(u32 adm)
1415 {
1416     u32 base = 0;
1417@@ -1358,8 +1505,10 @@ static int __init ssb_modinit(void)
1418     ssb_buses_lock();
1419     err = ssb_attach_queued_buses();
1420     ssb_buses_unlock();
1421- if (err)
1422+ if (err) {
1423         bus_unregister(&ssb_bustype);
1424+ goto out;
1425+ }
1426 
1427     err = b43_pci_ssb_bridge_init();
1428     if (err) {
1429@@ -1375,7 +1524,7 @@ static int __init ssb_modinit(void)
1430         /* don't fail SSB init because of this */
1431         err = 0;
1432     }
1433-
1434+out:
1435     return err;
1436 }
1437 /* ssb must be initialized after PCI but before the ssb drivers.
1438--- a/drivers/ssb/pci.c
1439+++ b/drivers/ssb/pci.c
1440@@ -17,6 +17,7 @@
1441 
1442 #include <linux/ssb/ssb.h>
1443 #include <linux/ssb/ssb_regs.h>
1444+#include <linux/slab.h>
1445 #include <linux/pci.h>
1446 #include <linux/delay.h>
1447 
1448@@ -167,10 +168,16 @@ err_pci:
1449 }
1450 
1451 /* Get the word-offset for a SSB_SPROM_XXX define. */
1452-#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16))
1453+#define SPOFF(offset) ((offset) / sizeof(u16))
1454 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
1455-#define SPEX(_outvar, _offset, _mask, _shift) \
1456+#define SPEX16(_outvar, _offset, _mask, _shift) \
1457     out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
1458+#define SPEX32(_outvar, _offset, _mask, _shift) \
1459+ out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
1460+ in[SPOFF(_offset)]) & (_mask)) >> (_shift))
1461+#define SPEX(_outvar, _offset, _mask, _shift) \
1462+ SPEX16(_outvar, _offset, _mask, _shift)
1463+
1464 
1465 static inline u8 ssb_crc8(u8 crc, u8 data)
1466 {
1467@@ -247,7 +254,7 @@ static int sprom_do_read(struct ssb_bus
1468     int i;
1469 
1470     for (i = 0; i < bus->sprom_size; i++)
1471- sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
1472+ sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2));
1473 
1474     return 0;
1475 }
1476@@ -278,7 +285,7 @@ static int sprom_do_write(struct ssb_bus
1477             ssb_printk("75%%");
1478         else if (i % 2)
1479             ssb_printk(".");
1480- writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
1481+ writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
1482         mmiowb();
1483         msleep(20);
1484     }
1485@@ -399,6 +406,46 @@ static void sprom_extract_r123(struct ss
1486     out->antenna_gain.ghz5.a3 = gain;
1487 }
1488 
1489+/* Revs 4 5 and 8 have partially shared layout */
1490+static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
1491+{
1492+ SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
1493+ SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
1494+ SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
1495+ SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
1496+ SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
1497+ SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
1498+ SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
1499+ SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
1500+
1501+ SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
1502+ SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
1503+ SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
1504+ SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
1505+ SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
1506+ SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
1507+ SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
1508+ SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
1509+
1510+ SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
1511+ SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
1512+ SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
1513+ SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
1514+ SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
1515+ SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
1516+ SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
1517+ SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
1518+
1519+ SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
1520+ SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
1521+ SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
1522+ SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
1523+ SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
1524+ SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
1525+ SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
1526+ SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
1527+}
1528+
1529 static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
1530 {
1531     int i;
1532@@ -421,10 +468,14 @@ static void sprom_extract_r45(struct ssb
1533         SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
1534         SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
1535         SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
1536+ SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
1537+ SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
1538     } else {
1539         SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
1540         SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
1541         SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
1542+ SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
1543+ SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0);
1544     }
1545     SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
1546          SSB_SPROM4_ANTAVAIL_A_SHIFT);
1547@@ -464,6 +515,8 @@ static void sprom_extract_r45(struct ssb
1548     memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
1549            sizeof(out->antenna_gain.ghz5));
1550 
1551+ sprom_extract_r458(out, in);
1552+
1553     /* TODO - get remaining rev 4 stuff needed */
1554 }
1555 
1556@@ -474,12 +527,14 @@ static void sprom_extract_r8(struct ssb_
1557 
1558     /* extract the MAC address */
1559     for (i = 0; i < 3; i++) {
1560- v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
1561+ v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
1562         *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
1563     }
1564     SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
1565     SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
1566     SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
1567+ SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
1568+ SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
1569     SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
1570          SSB_SPROM8_ANTAVAIL_A_SHIFT);
1571     SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
1572@@ -490,12 +545,55 @@ static void sprom_extract_r8(struct ssb_
1573     SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
1574     SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
1575          SSB_SPROM8_ITSSI_A_SHIFT);
1576+ SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
1577+ SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
1578+ SSB_SPROM8_MAXP_AL_SHIFT);
1579     SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
1580     SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
1581          SSB_SPROM8_GPIOA_P1_SHIFT);
1582     SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
1583     SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
1584          SSB_SPROM8_GPIOB_P3_SHIFT);
1585+ SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
1586+ SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
1587+ SSB_SPROM8_TRI5G_SHIFT);
1588+ SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
1589+ SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
1590+ SSB_SPROM8_TRI5GH_SHIFT);
1591+ SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0);
1592+ SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
1593+ SSB_SPROM8_RXPO5G_SHIFT);
1594+ SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
1595+ SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
1596+ SSB_SPROM8_RSSISMC2G_SHIFT);
1597+ SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
1598+ SSB_SPROM8_RSSISAV2G_SHIFT);
1599+ SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
1600+ SSB_SPROM8_BXA2G_SHIFT);
1601+ SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
1602+ SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
1603+ SSB_SPROM8_RSSISMC5G_SHIFT);
1604+ SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
1605+ SSB_SPROM8_RSSISAV5G_SHIFT);
1606+ SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
1607+ SSB_SPROM8_BXA5G_SHIFT);
1608+ SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
1609+ SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
1610+ SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
1611+ SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
1612+ SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
1613+ SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
1614+ SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
1615+ SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
1616+ SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
1617+ SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
1618+ SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
1619+ SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
1620+ SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
1621+ SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
1622+ SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
1623+ SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
1624+ SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
1625 
1626     /* Extract the antenna gain values. */
1627     SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
1628@@ -509,6 +607,8 @@ static void sprom_extract_r8(struct ssb_
1629     memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
1630            sizeof(out->antenna_gain.ghz5));
1631 
1632+ sprom_extract_r458(out, in);
1633+
1634     /* TODO - get remaining rev 8 stuff needed */
1635 }
1636 
1637@@ -521,36 +621,34 @@ static int sprom_extract(struct ssb_bus
1638     ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
1639     memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
1640     memset(out->et1mac, 0xFF, 6);
1641+
1642     if ((bus->chip_id & 0xFF00) == 0x4400) {
1643         /* Workaround: The BCM44XX chip has a stupid revision
1644          * number stored in the SPROM.
1645          * Always extract r1. */
1646         out->revision = 1;
1647+ ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision);
1648+ }
1649+
1650+ switch (out->revision) {
1651+ case 1:
1652+ case 2:
1653+ case 3:
1654         sprom_extract_r123(out, in);
1655- } else if (bus->chip_id == 0x4321) {
1656- /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */
1657- out->revision = 4;
1658+ break;
1659+ case 4:
1660+ case 5:
1661         sprom_extract_r45(out, in);
1662- } else {
1663- switch (out->revision) {
1664- case 1:
1665- case 2:
1666- case 3:
1667- sprom_extract_r123(out, in);
1668- break;
1669- case 4:
1670- case 5:
1671- sprom_extract_r45(out, in);
1672- break;
1673- case 8:
1674- sprom_extract_r8(out, in);
1675- break;
1676- default:
1677- ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
1678- " revision %d detected. Will extract"
1679- " v1\n", out->revision);
1680- sprom_extract_r123(out, in);
1681- }
1682+ break;
1683+ case 8:
1684+ sprom_extract_r8(out, in);
1685+ break;
1686+ default:
1687+ ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
1688+ " revision %d detected. Will extract"
1689+ " v1\n", out->revision);
1690+ out->revision = 1;
1691+ sprom_extract_r123(out, in);
1692     }
1693 
1694     if (out->boardflags_lo == 0xFFFF)
1695@@ -564,13 +662,34 @@ static int sprom_extract(struct ssb_bus
1696 static int ssb_pci_sprom_get(struct ssb_bus *bus,
1697                  struct ssb_sprom *sprom)
1698 {
1699- const struct ssb_sprom *fallback;
1700- int err = -ENOMEM;
1701+ int err;
1702     u16 *buf;
1703 
1704+ if (!ssb_is_sprom_available(bus)) {
1705+ ssb_printk(KERN_ERR PFX "No SPROM available!\n");
1706+ return -ENODEV;
1707+ }
1708+ if (bus->chipco.dev) { /* can be unavailable! */
1709+ /*
1710+ * get SPROM offset: SSB_SPROM_BASE1 except for
1711+ * chipcommon rev >= 31 or chip ID is 0x4312 and
1712+ * chipcommon status & 3 == 2
1713+ */
1714+ if (bus->chipco.dev->id.revision >= 31)
1715+ bus->sprom_offset = SSB_SPROM_BASE31;
1716+ else if (bus->chip_id == 0x4312 &&
1717+ (bus->chipco.status & 0x03) == 2)
1718+ bus->sprom_offset = SSB_SPROM_BASE31;
1719+ else
1720+ bus->sprom_offset = SSB_SPROM_BASE1;
1721+ } else {
1722+ bus->sprom_offset = SSB_SPROM_BASE1;
1723+ }
1724+ ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
1725+
1726     buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
1727     if (!buf)
1728- goto out;
1729+ return -ENOMEM;
1730     bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
1731     sprom_do_read(bus, buf);
1732     err = sprom_check_crc(buf, bus->sprom_size);
1733@@ -580,17 +699,24 @@ static int ssb_pci_sprom_get(struct ssb_
1734         buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
1735                   GFP_KERNEL);
1736         if (!buf)
1737- goto out;
1738+ return -ENOMEM;
1739         bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
1740         sprom_do_read(bus, buf);
1741         err = sprom_check_crc(buf, bus->sprom_size);
1742         if (err) {
1743             /* All CRC attempts failed.
1744              * Maybe there is no SPROM on the device?
1745- * If we have a fallback, use that. */
1746- fallback = ssb_get_fallback_sprom();
1747- if (fallback) {
1748- memcpy(sprom, fallback, sizeof(*sprom));
1749+ * Now we ask the arch code if there is some sprom
1750+ * available for this device in some other storage */
1751+ err = ssb_fill_sprom_with_fallback(bus, sprom);
1752+ if (err) {
1753+ ssb_printk(KERN_WARNING PFX "WARNING: Using"
1754+ " fallback SPROM failed (err %d)\n",
1755+ err);
1756+ } else {
1757+ ssb_dprintk(KERN_DEBUG PFX "Using SPROM"
1758+ " revision %d provided by"
1759+ " platform.\n", sprom->revision);
1760                 err = 0;
1761                 goto out_free;
1762             }
1763@@ -602,19 +728,15 @@ static int ssb_pci_sprom_get(struct ssb_
1764 
1765 out_free:
1766     kfree(buf);
1767-out:
1768     return err;
1769 }
1770 
1771 static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
1772                   struct ssb_boardinfo *bi)
1773 {
1774- pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
1775- &bi->vendor);
1776- pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
1777- &bi->type);
1778- pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
1779- &bi->rev);
1780+ bi->vendor = bus->host_pci->subsystem_vendor;
1781+ bi->type = bus->host_pci->subsystem_device;
1782+ bi->rev = bus->host_pci->revision;
1783 }
1784 
1785 int ssb_pci_get_invariants(struct ssb_bus *bus,
1786--- a/drivers/ssb/pcihost_wrapper.c
1787+++ b/drivers/ssb/pcihost_wrapper.c
1788@@ -12,6 +12,7 @@
1789  */
1790 
1791 #include <linux/pci.h>
1792+#include <linux/slab.h>
1793 #include <linux/ssb/ssb.h>
1794 
1795 
1796@@ -52,12 +53,13 @@ static int ssb_pcihost_resume(struct pci
1797 # define ssb_pcihost_resume NULL
1798 #endif /* CONFIG_PM */
1799 
1800-static int ssb_pcihost_probe(struct pci_dev *dev,
1801- const struct pci_device_id *id)
1802+static int __devinit ssb_pcihost_probe(struct pci_dev *dev,
1803+ const struct pci_device_id *id)
1804 {
1805     struct ssb_bus *ssb;
1806     int err = -ENOMEM;
1807     const char *name;
1808+ u32 val;
1809 
1810     ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
1811     if (!ssb)
1812@@ -73,6 +75,12 @@ static int ssb_pcihost_probe(struct pci_
1813         goto err_pci_disable;
1814     pci_set_master(dev);
1815 
1816+ /* Disable the RETRY_TIMEOUT register (0x41) to keep
1817+ * PCI Tx retries from interfering with C3 CPU state */
1818+ pci_read_config_dword(dev, 0x40, &val);
1819+ if ((val & 0x0000ff00) != 0)
1820+ pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
1821+
1822     err = ssb_bus_pcibus_register(ssb, dev);
1823     if (err)
1824         goto err_pci_release_regions;
1825@@ -102,7 +110,7 @@ static void ssb_pcihost_remove(struct pc
1826     pci_set_drvdata(dev, NULL);
1827 }
1828 
1829-int ssb_pcihost_register(struct pci_driver *driver)
1830+int __devinit ssb_pcihost_register(struct pci_driver *driver)
1831 {
1832     driver->probe = ssb_pcihost_probe;
1833     driver->remove = ssb_pcihost_remove;
1834--- a/drivers/ssb/pcmcia.c
1835+++ b/drivers/ssb/pcmcia.c
1836@@ -617,136 +617,140 @@ static int ssb_pcmcia_sprom_check_crc(co
1837     } \
1838   } while (0)
1839 
1840-int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
1841- struct ssb_init_invariants *iv)
1842+static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
1843+ tuple_t *tuple,
1844+ void *priv)
1845 {
1846- tuple_t tuple;
1847- int res;
1848- unsigned char buf[32];
1849+ struct ssb_sprom *sprom = priv;
1850+
1851+ if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
1852+ return -EINVAL;
1853+ if (tuple->TupleDataLen != ETH_ALEN + 2)
1854+ return -EINVAL;
1855+ if (tuple->TupleData[1] != ETH_ALEN)
1856+ return -EINVAL;
1857+ memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
1858+ return 0;
1859+};
1860+
1861+static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
1862+ tuple_t *tuple,
1863+ void *priv)
1864+{
1865+ struct ssb_init_invariants *iv = priv;
1866     struct ssb_sprom *sprom = &iv->sprom;
1867     struct ssb_boardinfo *bi = &iv->boardinfo;
1868     const char *error_description;
1869 
1870+ GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
1871+ switch (tuple->TupleData[0]) {
1872+ case SSB_PCMCIA_CIS_ID:
1873+ GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
1874+ (tuple->TupleDataLen != 7),
1875+ "id tpl size");
1876+ bi->vendor = tuple->TupleData[1] |
1877+ ((u16)tuple->TupleData[2] << 8);
1878+ break;
1879+ case SSB_PCMCIA_CIS_BOARDREV:
1880+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1881+ "boardrev tpl size");
1882+ sprom->board_rev = tuple->TupleData[1];
1883+ break;
1884+ case SSB_PCMCIA_CIS_PA:
1885+ GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
1886+ (tuple->TupleDataLen != 10),
1887+ "pa tpl size");
1888+ sprom->pa0b0 = tuple->TupleData[1] |
1889+ ((u16)tuple->TupleData[2] << 8);
1890+ sprom->pa0b1 = tuple->TupleData[3] |
1891+ ((u16)tuple->TupleData[4] << 8);
1892+ sprom->pa0b2 = tuple->TupleData[5] |
1893+ ((u16)tuple->TupleData[6] << 8);
1894+ sprom->itssi_a = tuple->TupleData[7];
1895+ sprom->itssi_bg = tuple->TupleData[7];
1896+ sprom->maxpwr_a = tuple->TupleData[8];
1897+ sprom->maxpwr_bg = tuple->TupleData[8];
1898+ break;
1899+ case SSB_PCMCIA_CIS_OEMNAME:
1900+ /* We ignore this. */
1901+ break;
1902+ case SSB_PCMCIA_CIS_CCODE:
1903+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1904+ "ccode tpl size");
1905+ sprom->country_code = tuple->TupleData[1];
1906+ break;
1907+ case SSB_PCMCIA_CIS_ANTENNA:
1908+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1909+ "ant tpl size");
1910+ sprom->ant_available_a = tuple->TupleData[1];
1911+ sprom->ant_available_bg = tuple->TupleData[1];
1912+ break;
1913+ case SSB_PCMCIA_CIS_ANTGAIN:
1914+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1915+ "antg tpl size");
1916+ sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
1917+ sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
1918+ sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
1919+ sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
1920+ sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
1921+ sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
1922+ sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
1923+ sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
1924+ break;
1925+ case SSB_PCMCIA_CIS_BFLAGS:
1926+ GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
1927+ (tuple->TupleDataLen != 5),
1928+ "bfl tpl size");
1929+ sprom->boardflags_lo = tuple->TupleData[1] |
1930+ ((u16)tuple->TupleData[2] << 8);
1931+ break;
1932+ case SSB_PCMCIA_CIS_LEDS:
1933+ GOTO_ERROR_ON(tuple->TupleDataLen != 5,
1934+ "leds tpl size");
1935+ sprom->gpio0 = tuple->TupleData[1];
1936+ sprom->gpio1 = tuple->TupleData[2];
1937+ sprom->gpio2 = tuple->TupleData[3];
1938+ sprom->gpio3 = tuple->TupleData[4];
1939+ break;
1940+ }
1941+ return -ENOSPC; /* continue with next entry */
1942+
1943+error:
1944+ ssb_printk(KERN_ERR PFX
1945+ "PCMCIA: Failed to fetch device invariants: %s\n",
1946+ error_description);
1947+ return -ENODEV;
1948+}
1949+
1950+
1951+int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
1952+ struct ssb_init_invariants *iv)
1953+{
1954+ struct ssb_sprom *sprom = &iv->sprom;
1955+ int res;
1956+
1957     memset(sprom, 0xFF, sizeof(*sprom));
1958     sprom->revision = 1;
1959     sprom->boardflags_lo = 0;
1960     sprom->boardflags_hi = 0;
1961 
1962     /* First fetch the MAC address. */
1963- memset(&tuple, 0, sizeof(tuple));
1964- tuple.DesiredTuple = CISTPL_FUNCE;
1965- tuple.TupleData = buf;
1966- tuple.TupleDataMax = sizeof(buf);
1967- res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
1968- GOTO_ERROR_ON(res != 0, "MAC first tpl");
1969- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
1970- GOTO_ERROR_ON(res != 0, "MAC first tpl data");
1971- while (1) {
1972- GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
1973- if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
1974- break;
1975- res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
1976- GOTO_ERROR_ON(res != 0, "MAC next tpl");
1977- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
1978- GOTO_ERROR_ON(res != 0, "MAC next tpl data");
1979+ res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
1980+ ssb_pcmcia_get_mac, sprom);
1981+ if (res != 0) {
1982+ ssb_printk(KERN_ERR PFX
1983+ "PCMCIA: Failed to fetch MAC address\n");
1984+ return -ENODEV;
1985     }
1986- GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
1987- memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
1988 
1989     /* Fetch the vendor specific tuples. */
1990- memset(&tuple, 0, sizeof(tuple));
1991- tuple.DesiredTuple = SSB_PCMCIA_CIS;
1992- tuple.TupleData = buf;
1993- tuple.TupleDataMax = sizeof(buf);
1994- res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
1995- GOTO_ERROR_ON(res != 0, "VEN first tpl");
1996- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
1997- GOTO_ERROR_ON(res != 0, "VEN first tpl data");
1998- while (1) {
1999- GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
2000- switch (tuple.TupleData[0]) {
2001- case SSB_PCMCIA_CIS_ID:
2002- GOTO_ERROR_ON((tuple.TupleDataLen != 5) &&
2003- (tuple.TupleDataLen != 7),
2004- "id tpl size");
2005- bi->vendor = tuple.TupleData[1] |
2006- ((u16)tuple.TupleData[2] << 8);
2007- break;
2008- case SSB_PCMCIA_CIS_BOARDREV:
2009- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
2010- "boardrev tpl size");
2011- sprom->board_rev = tuple.TupleData[1];
2012- break;
2013- case SSB_PCMCIA_CIS_PA:
2014- GOTO_ERROR_ON((tuple.TupleDataLen != 9) &&
2015- (tuple.TupleDataLen != 10),
2016- "pa tpl size");
2017- sprom->pa0b0 = tuple.TupleData[1] |
2018- ((u16)tuple.TupleData[2] << 8);
2019- sprom->pa0b1 = tuple.TupleData[3] |
2020- ((u16)tuple.TupleData[4] << 8);
2021- sprom->pa0b2 = tuple.TupleData[5] |
2022- ((u16)tuple.TupleData[6] << 8);
2023- sprom->itssi_a = tuple.TupleData[7];
2024- sprom->itssi_bg = tuple.TupleData[7];
2025- sprom->maxpwr_a = tuple.TupleData[8];
2026- sprom->maxpwr_bg = tuple.TupleData[8];
2027- break;
2028- case SSB_PCMCIA_CIS_OEMNAME:
2029- /* We ignore this. */
2030- break;
2031- case SSB_PCMCIA_CIS_CCODE:
2032- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
2033- "ccode tpl size");
2034- sprom->country_code = tuple.TupleData[1];
2035- break;
2036- case SSB_PCMCIA_CIS_ANTENNA:
2037- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
2038- "ant tpl size");
2039- sprom->ant_available_a = tuple.TupleData[1];
2040- sprom->ant_available_bg = tuple.TupleData[1];
2041- break;
2042- case SSB_PCMCIA_CIS_ANTGAIN:
2043- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
2044- "antg tpl size");
2045- sprom->antenna_gain.ghz24.a0 = tuple.TupleData[1];
2046- sprom->antenna_gain.ghz24.a1 = tuple.TupleData[1];
2047- sprom->antenna_gain.ghz24.a2 = tuple.TupleData[1];
2048- sprom->antenna_gain.ghz24.a3 = tuple.TupleData[1];
2049- sprom->antenna_gain.ghz5.a0 = tuple.TupleData[1];
2050- sprom->antenna_gain.ghz5.a1 = tuple.TupleData[1];
2051- sprom->antenna_gain.ghz5.a2 = tuple.TupleData[1];
2052- sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
2053- break;
2054- case SSB_PCMCIA_CIS_BFLAGS:
2055- GOTO_ERROR_ON((tuple.TupleDataLen != 3) &&
2056- (tuple.TupleDataLen != 5),
2057- "bfl tpl size");
2058- sprom->boardflags_lo = tuple.TupleData[1] |
2059- ((u16)tuple.TupleData[2] << 8);
2060- break;
2061- case SSB_PCMCIA_CIS_LEDS:
2062- GOTO_ERROR_ON(tuple.TupleDataLen != 5,
2063- "leds tpl size");
2064- sprom->gpio0 = tuple.TupleData[1];
2065- sprom->gpio1 = tuple.TupleData[2];
2066- sprom->gpio2 = tuple.TupleData[3];
2067- sprom->gpio3 = tuple.TupleData[4];
2068- break;
2069- }
2070- res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
2071- if (res == -ENOSPC)
2072- break;
2073- GOTO_ERROR_ON(res != 0, "VEN next tpl");
2074- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
2075- GOTO_ERROR_ON(res != 0, "VEN next tpl data");
2076- }
2077+ res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
2078+ ssb_pcmcia_do_get_invariants, iv);
2079+ if ((res == 0) || (res == -ENOSPC))
2080+ return 0;
2081 
2082- return 0;
2083-error:
2084     ssb_printk(KERN_ERR PFX
2085- "PCMCIA: Failed to fetch device invariants: %s\n",
2086- error_description);
2087+ "PCMCIA: Failed to fetch device invariants\n");
2088     return -ENODEV;
2089 }
2090 
2091--- a/drivers/ssb/scan.c
2092+++ b/drivers/ssb/scan.c
2093@@ -162,6 +162,8 @@ static u8 chipid_to_nrcores(u16 chipid)
2094 static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
2095                u16 offset)
2096 {
2097+ u32 lo, hi;
2098+
2099     switch (bus->bustype) {
2100     case SSB_BUSTYPE_SSB:
2101         offset += current_coreidx * SSB_CORE_SIZE;
2102@@ -174,7 +176,12 @@ static u32 scan_read32(struct ssb_bus *b
2103             offset -= 0x800;
2104         } else
2105             ssb_pcmcia_switch_segment(bus, 0);
2106- break;
2107+ lo = readw(bus->mmio + offset);
2108+ hi = readw(bus->mmio + offset + 2);
2109+ return lo | (hi << 16);
2110+ case SSB_BUSTYPE_SDIO:
2111+ offset += current_coreidx * SSB_CORE_SIZE;
2112+ return ssb_sdio_scan_read32(bus, offset);
2113     }
2114     return readl(bus->mmio + offset);
2115 }
2116@@ -188,6 +195,8 @@ static int scan_switchcore(struct ssb_bu
2117         return ssb_pci_switch_coreidx(bus, coreidx);
2118     case SSB_BUSTYPE_PCMCIA:
2119         return ssb_pcmcia_switch_coreidx(bus, coreidx);
2120+ case SSB_BUSTYPE_SDIO:
2121+ return ssb_sdio_scan_switch_coreidx(bus, coreidx);
2122     }
2123     return 0;
2124 }
2125@@ -206,6 +215,8 @@ void ssb_iounmap(struct ssb_bus *bus)
2126         SSB_BUG_ON(1); /* Can't reach this code. */
2127 #endif
2128         break;
2129+ case SSB_BUSTYPE_SDIO:
2130+ break;
2131     }
2132     bus->mmio = NULL;
2133     bus->mapped_device = NULL;
2134@@ -230,6 +241,10 @@ static void __iomem *ssb_ioremap(struct
2135         SSB_BUG_ON(1); /* Can't reach this code. */
2136 #endif
2137         break;
2138+ case SSB_BUSTYPE_SDIO:
2139+ /* Nothing to ioremap in the SDIO case, just fake it */
2140+ mmio = (void __iomem *)baseaddr;
2141+ break;
2142     }
2143 
2144     return mmio;
2145@@ -245,7 +260,10 @@ static int we_support_multiple_80211_cor
2146 #ifdef CONFIG_SSB_PCIHOST
2147     if (bus->bustype == SSB_BUSTYPE_PCI) {
2148         if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
2149- bus->host_pci->device == 0x4324)
2150+ ((bus->host_pci->device == 0x4313) ||
2151+ (bus->host_pci->device == 0x431A) ||
2152+ (bus->host_pci->device == 0x4321) ||
2153+ (bus->host_pci->device == 0x4324)))
2154             return 1;
2155     }
2156 #endif /* CONFIG_SSB_PCIHOST */
2157@@ -294,8 +312,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
2158     } else {
2159         if (bus->bustype == SSB_BUSTYPE_PCI) {
2160             bus->chip_id = pcidev_to_chipid(bus->host_pci);
2161- pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
2162- &bus->chip_rev);
2163+ bus->chip_rev = bus->host_pci->revision;
2164             bus->chip_package = 0;
2165         } else {
2166             bus->chip_id = 0x4710;
2167@@ -339,7 +356,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
2168         dev->bus = bus;
2169         dev->ops = bus->ops;
2170 
2171- ssb_dprintk(KERN_INFO PFX
2172+ printk(KERN_DEBUG PFX
2173                 "Core %d found: %s "
2174                 "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
2175                 i, ssb_core_name(dev->id.coreid),
2176@@ -407,6 +424,16 @@ int ssb_bus_scan(struct ssb_bus *bus,
2177             bus->pcicore.dev = dev;
2178 #endif /* CONFIG_SSB_DRIVER_PCICORE */
2179             break;
2180+ case SSB_DEV_ETHERNET:
2181+ if (bus->bustype == SSB_BUSTYPE_PCI) {
2182+ if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
2183+ (bus->host_pci->device & 0xFF00) == 0x4300) {
2184+ /* This is a dangling ethernet core on a
2185+ * wireless device. Ignore it. */
2186+ continue;
2187+ }
2188+ }
2189+ break;
2190         default:
2191             break;
2192         }
2193--- /dev/null
2194+++ b/drivers/ssb/sdio.c
2195@@ -0,0 +1,610 @@
2196+/*
2197+ * Sonics Silicon Backplane
2198+ * SDIO-Hostbus related functions
2199+ *
2200+ * Copyright 2009 Albert Herranz <albert_herranz@yahoo.es>
2201+ *
2202+ * Based on drivers/ssb/pcmcia.c
2203+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
2204+ * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
2205+ *
2206+ * Licensed under the GNU/GPL. See COPYING for details.
2207+ *
2208+ */
2209+
2210+#include <linux/ssb/ssb.h>
2211+#include <linux/delay.h>
2212+#include <linux/io.h>
2213+#include <linux/etherdevice.h>
2214+#include <linux/mmc/sdio_func.h>
2215+
2216+#include "ssb_private.h"
2217+
2218+/* Define the following to 1 to enable a printk on each coreswitch. */
2219+#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG 0
2220+
2221+
2222+/* Hardware invariants CIS tuples */
2223+#define SSB_SDIO_CIS 0x80
2224+#define SSB_SDIO_CIS_SROMREV 0x00
2225+#define SSB_SDIO_CIS_ID 0x01
2226+#define SSB_SDIO_CIS_BOARDREV 0x02
2227+#define SSB_SDIO_CIS_PA 0x03
2228+#define SSB_SDIO_CIS_PA_PA0B0_LO 0
2229+#define SSB_SDIO_CIS_PA_PA0B0_HI 1
2230+#define SSB_SDIO_CIS_PA_PA0B1_LO 2
2231+#define SSB_SDIO_CIS_PA_PA0B1_HI 3
2232+#define SSB_SDIO_CIS_PA_PA0B2_LO 4
2233+#define SSB_SDIO_CIS_PA_PA0B2_HI 5
2234+#define SSB_SDIO_CIS_PA_ITSSI 6
2235+#define SSB_SDIO_CIS_PA_MAXPOW 7
2236+#define SSB_SDIO_CIS_OEMNAME 0x04
2237+#define SSB_SDIO_CIS_CCODE 0x05
2238+#define SSB_SDIO_CIS_ANTENNA 0x06
2239+#define SSB_SDIO_CIS_ANTGAIN 0x07
2240+#define SSB_SDIO_CIS_BFLAGS 0x08
2241+#define SSB_SDIO_CIS_LEDS 0x09
2242+
2243+#define CISTPL_FUNCE_LAN_NODE_ID 0x04 /* same as in PCMCIA */
2244+
2245+
2246+/*
2247+ * Function 1 miscellaneous registers.
2248+ *
2249+ * Definitions match src/include/sbsdio.h from the
2250+ * Android Open Source Project
2251+ * http://android.git.kernel.org/?p=platform/system/wlan/broadcom.git
2252+ *
2253+ */
2254+#define SBSDIO_FUNC1_SBADDRLOW 0x1000a /* SB Address window Low (b15) */
2255+#define SBSDIO_FUNC1_SBADDRMID 0x1000b /* SB Address window Mid (b23-b16) */
2256+#define SBSDIO_FUNC1_SBADDRHIGH 0x1000c /* SB Address window High (b24-b31) */
2257+
2258+/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
2259+#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid address bits in SBADDRLOW */
2260+#define SBSDIO_SBADDRMID_MASK 0xff /* Valid address bits in SBADDRMID */
2261+#define SBSDIO_SBADDRHIGH_MASK 0xff /* Valid address bits in SBADDRHIGH */
2262+
2263+#define SBSDIO_SB_OFT_ADDR_MASK 0x7FFF /* sb offset addr is <= 15 bits, 32k */
2264+
2265+/* REVISIT: this flag doesn't seem to matter */
2266+#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x8000 /* forces 32-bit SB access */
2267+
2268+
2269+/*
2270+ * Address map within the SDIO function address space (128K).
2271+ *
2272+ * Start End Description
2273+ * ------- ------- ------------------------------------------
2274+ * 0x00000 0x0ffff selected backplane address window (64K)
2275+ * 0x10000 0x1ffff backplane control registers (max 64K)
2276+ *
2277+ * The current address window is configured by writing to registers
2278+ * SBADDRLOW, SBADDRMID and SBADDRHIGH.
2279+ *
2280+ * In order to access the contents of a 32-bit Silicon Backplane address
2281+ * the backplane address window must be first loaded with the highest
2282+ * 16 bits of the target address. Then, an access must be done to the
2283+ * SDIO function address space using the lower 15 bits of the address.
2284+ * Bit 15 of the address must be set when doing 32 bit accesses.
2285+ *
2286+ * 10987654321098765432109876543210
2287+ * WWWWWWWWWWWWWWWWW SB Address Window
2288+ * OOOOOOOOOOOOOOOO Offset within SB Address Window
2289+ * a 32-bit access flag
2290+ */
2291+
2292+
2293+/*
2294+ * SSB I/O via SDIO.
2295+ *
2296+ * NOTE: SDIO address @addr is 17 bits long (SDIO address space is 128K).
2297+ */
2298+
2299+static inline struct device *ssb_sdio_dev(struct ssb_bus *bus)
2300+{
2301+ return &bus->host_sdio->dev;
2302+}
2303+
2304+/* host claimed */
2305+static int ssb_sdio_writeb(struct ssb_bus *bus, unsigned int addr, u8 val)
2306+{
2307+ int error = 0;
2308+
2309+ sdio_writeb(bus->host_sdio, val, addr, &error);
2310+ if (unlikely(error)) {
2311+ dev_dbg(ssb_sdio_dev(bus), "%08X <- %02x, error %d\n",
2312+ addr, val, error);
2313+ }
2314+
2315+ return error;
2316+}
2317+
2318+#if 0
2319+static u8 ssb_sdio_readb(struct ssb_bus *bus, unsigned int addr)
2320+{
2321+ u8 val;
2322+ int error = 0;
2323+
2324+ val = sdio_readb(bus->host_sdio, addr, &error);
2325+ if (unlikely(error)) {
2326+ dev_dbg(ssb_sdio_dev(bus), "%08X -> %02x, error %d\n",
2327+ addr, val, error);
2328+ }
2329+
2330+ return val;
2331+}
2332+#endif
2333+
2334+/* host claimed */
2335+static int ssb_sdio_set_sbaddr_window(struct ssb_bus *bus, u32 address)
2336+{
2337+ int error;
2338+
2339+ error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRLOW,
2340+ (address >> 8) & SBSDIO_SBADDRLOW_MASK);
2341+ if (error)
2342+ goto out;
2343+ error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRMID,
2344+ (address >> 16) & SBSDIO_SBADDRMID_MASK);
2345+ if (error)
2346+ goto out;
2347+ error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRHIGH,
2348+ (address >> 24) & SBSDIO_SBADDRHIGH_MASK);
2349+ if (error)
2350+ goto out;
2351+ bus->sdio_sbaddr = address;
2352+out:
2353+ if (error) {
2354+ dev_dbg(ssb_sdio_dev(bus), "failed to set address window"
2355+ " to 0x%08x, error %d\n", address, error);
2356+ }
2357+
2358+ return error;
2359+}
2360+
2361+/* for enumeration use only */
2362+u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset)
2363+{
2364+ u32 val;
2365+ int error;
2366+
2367+ sdio_claim_host(bus->host_sdio);
2368+ val = sdio_readl(bus->host_sdio, offset, &error);
2369+ sdio_release_host(bus->host_sdio);
2370+ if (unlikely(error)) {
2371+ dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
2372+ bus->sdio_sbaddr >> 16, offset, val, error);
2373+ }
2374+
2375+ return val;
2376+}
2377+
2378+/* for enumeration use only */
2379+int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
2380+{
2381+ u32 sbaddr;
2382+ int error;
2383+
2384+ sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
2385+ sdio_claim_host(bus->host_sdio);
2386+ error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
2387+ sdio_release_host(bus->host_sdio);
2388+ if (error) {
2389+ dev_err(ssb_sdio_dev(bus), "failed to switch to core %u,"
2390+ " error %d\n", coreidx, error);
2391+ goto out;
2392+ }
2393+out:
2394+ return error;
2395+}
2396+
2397+/* host must be already claimed */
2398+int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
2399+{
2400+ u8 coreidx = dev->core_index;
2401+ u32 sbaddr;
2402+ int error = 0;
2403+
2404+ sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
2405+ if (unlikely(bus->sdio_sbaddr != sbaddr)) {
2406+#if SSB_VERBOSE_SDIOCORESWITCH_DEBUG
2407+ dev_info(ssb_sdio_dev(bus),
2408+ "switching to %s core, index %d\n",
2409+ ssb_core_name(dev->id.coreid), coreidx);
2410+#endif
2411+ error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
2412+ if (error) {
2413+ dev_dbg(ssb_sdio_dev(bus), "failed to switch to"
2414+ " core %u, error %d\n", coreidx, error);
2415+ goto out;
2416+ }
2417+ bus->mapped_device = dev;
2418+ }
2419+
2420+out:
2421+ return error;
2422+}
2423+
2424+static u8 ssb_sdio_read8(struct ssb_device *dev, u16 offset)
2425+{
2426+ struct ssb_bus *bus = dev->bus;
2427+ u8 val = 0xff;
2428+ int error = 0;
2429+
2430+ sdio_claim_host(bus->host_sdio);
2431+ if (unlikely(ssb_sdio_switch_core(bus, dev)))
2432+ goto out;
2433+ offset |= bus->sdio_sbaddr & 0xffff;
2434+ offset &= SBSDIO_SB_OFT_ADDR_MASK;
2435+ val = sdio_readb(bus->host_sdio, offset, &error);
2436+ if (error) {
2437+ dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %02x, error %d\n",
2438+ bus->sdio_sbaddr >> 16, offset, val, error);
2439+ }
2440+out:
2441+ sdio_release_host(bus->host_sdio);
2442+
2443+ return val;
2444+}
2445+
2446+static u16 ssb_sdio_read16(struct ssb_device *dev, u16 offset)
2447+{
2448+ struct ssb_bus *bus = dev->bus;
2449+ u16 val = 0xffff;
2450+ int error = 0;
2451+
2452+ sdio_claim_host(bus->host_sdio);
2453+ if (unlikely(ssb_sdio_switch_core(bus, dev)))
2454+ goto out;
2455+ offset |= bus->sdio_sbaddr & 0xffff;
2456+ offset &= SBSDIO_SB_OFT_ADDR_MASK;
2457+ val = sdio_readw(bus->host_sdio, offset, &error);
2458+ if (error) {
2459+ dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %04x, error %d\n",
2460+ bus->sdio_sbaddr >> 16, offset, val, error);
2461+ }
2462+out:
2463+ sdio_release_host(bus->host_sdio);
2464+
2465+ return val;
2466+}
2467+
2468+static u32 ssb_sdio_read32(struct ssb_device *dev, u16 offset)
2469+{
2470+ struct ssb_bus *bus = dev->bus;
2471+ u32 val = 0xffffffff;
2472+ int error = 0;
2473+
2474+ sdio_claim_host(bus->host_sdio);
2475+ if (unlikely(ssb_sdio_switch_core(bus, dev)))
2476+ goto out;
2477+ offset |= bus->sdio_sbaddr & 0xffff;
2478+ offset &= SBSDIO_SB_OFT_ADDR_MASK;
2479+ offset |= SBSDIO_SB_ACCESS_2_4B_FLAG; /* 32 bit data access */
2480+ val = sdio_readl(bus->host_sdio, offset, &error);
2481+ if (error) {
2482+ dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
2483+ bus->sdio_sbaddr >> 16, offset, val, error);
2484+ }
2485+out:
2486+ sdio_release_host(bus->host_sdio);
2487+
2488+ return val;
2489+}
2490+
2491+#ifdef CONFIG_SSB_BLOCKIO
2492+static void ssb_sdio_block_read(struct ssb_device *dev, void *buffer,
2493+ size_t count, u16 offset, u8 reg_width)
2494+{
2495+ size_t saved_count = count;
2496+ struct ssb_bus *bus = dev->bus;
2497+ int error = 0;
2498+
2499+ sdio_claim_host(bus->host_sdio);
2500+ if (unlikely(ssb_sdio_switch_core(bus, dev))) {
2501+ error = -EIO;
2502+ memset(buffer, 0xff, count);
2503+ goto err_out;
2504+ }
2505+ offset |= bus->sdio_sbaddr & 0xffff;
2506+ offset &= SBSDIO_SB_OFT_ADDR_MASK;
2507+
2508+ switch (reg_width) {
2509+ case sizeof(u8): {
2510+ error = sdio_readsb(bus->host_sdio, buffer, offset, count);
2511+ break;
2512+ }
2513+ case sizeof(u16): {
2514+ SSB_WARN_ON(count & 1);
2515+ error = sdio_readsb(bus->host_sdio, buffer, offset, count);
2516+ break;
2517+ }
2518+ case sizeof(u32): {
2519+ SSB_WARN_ON(count & 3);
2520+ offset |= SBSDIO_SB_ACCESS_2_4B_FLAG; /* 32 bit data access */
2521+ error = sdio_readsb(bus->host_sdio, buffer, offset, count);
2522+ break;
2523+ }
2524+ default:
2525+ SSB_WARN_ON(1);
2526+ }
2527+ if (!error)
2528+ goto out;
2529+
2530+err_out:
2531+ dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
2532+ bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
2533+out:
2534+ sdio_release_host(bus->host_sdio);
2535+}
2536+#endif /* CONFIG_SSB_BLOCKIO */
2537+
2538+static void ssb_sdio_write8(struct ssb_device *dev, u16 offset, u8 val)
2539+{
2540+ struct ssb_bus *bus = dev->bus;
2541+ int error = 0;
2542+
2543+ sdio_claim_host(bus->host_sdio);
2544+ if (unlikely(ssb_sdio_switch_core(bus, dev)))
2545+ goto out;
2546+ offset |= bus->sdio_sbaddr & 0xffff;
2547+ offset &= SBSDIO_SB_OFT_ADDR_MASK;
2548+ sdio_writeb(bus->host_sdio, val, offset, &error);
2549+ if (error) {
2550+ dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %02x, error %d\n",
2551+ bus->sdio_sbaddr >> 16, offset, val, error);
2552+ }
2553+out:
2554+ sdio_release_host(bus->host_sdio);
2555+}
2556+
2557+static void ssb_sdio_write16(struct ssb_device *dev, u16 offset, u16 val)
2558+{
2559+ struct ssb_bus *bus = dev->bus;
2560+ int error = 0;
2561+
2562+ sdio_claim_host(bus->host_sdio);
2563+ if (unlikely(ssb_sdio_switch_core(bus, dev)))
2564+ goto out;
2565+ offset |= bus->sdio_sbaddr & 0xffff;
2566+ offset &= SBSDIO_SB_OFT_ADDR_MASK;
2567+ sdio_writew(bus->host_sdio, val, offset, &error);
2568+ if (error) {
2569+ dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %04x, error %d\n",
2570+ bus->sdio_sbaddr >> 16, offset, val, error);
2571+ }
2572+out:
2573+ sdio_release_host(bus->host_sdio);
2574+}
2575+
2576+static void ssb_sdio_write32(struct ssb_device *dev, u16 offset, u32 val)
2577+{
2578+ struct ssb_bus *bus = dev->bus;
2579+ int error = 0;
2580+
2581+ sdio_claim_host(bus->host_sdio);
2582+ if (unlikely(ssb_sdio_switch_core(bus, dev)))
2583+ goto out;
2584+ offset |= bus->sdio_sbaddr & 0xffff;
2585+ offset &= SBSDIO_SB_OFT_ADDR_MASK;
2586+ offset |= SBSDIO_SB_ACCESS_2_4B_FLAG; /* 32 bit data access */
2587+ sdio_writel(bus->host_sdio, val, offset, &error);
2588+ if (error) {
2589+ dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %08x, error %d\n",
2590+ bus->sdio_sbaddr >> 16, offset, val, error);
2591+ }
2592+ if (bus->quirks & SSB_QUIRK_SDIO_READ_AFTER_WRITE32)
2593+ sdio_readl(bus->host_sdio, 0, &error);
2594+out:
2595+ sdio_release_host(bus->host_sdio);
2596+}
2597+
2598+#ifdef CONFIG_SSB_BLOCKIO
2599+static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer,
2600+ size_t count, u16 offset, u8 reg_width)
2601+{
2602+ size_t saved_count = count;
2603+ struct ssb_bus *bus = dev->bus;
2604+ int error = 0;
2605+
2606+ sdio_claim_host(bus->host_sdio);
2607+ if (unlikely(ssb_sdio_switch_core(bus, dev))) {
2608+ error = -EIO;
2609+ memset((void *)buffer, 0xff, count);
2610+ goto err_out;
2611+ }
2612+ offset |= bus->sdio_sbaddr & 0xffff;
2613+ offset &= SBSDIO_SB_OFT_ADDR_MASK;
2614+
2615+ switch (reg_width) {
2616+ case sizeof(u8):
2617+ error = sdio_writesb(bus->host_sdio, offset,
2618+ (void *)buffer, count);
2619+ break;
2620+ case sizeof(u16):
2621+ SSB_WARN_ON(count & 1);
2622+ error = sdio_writesb(bus->host_sdio, offset,
2623+ (void *)buffer, count);
2624+ break;
2625+ case sizeof(u32):
2626+ SSB_WARN_ON(count & 3);
2627+ offset |= SBSDIO_SB_ACCESS_2_4B_FLAG; /* 32 bit data access */
2628+ error = sdio_writesb(bus->host_sdio, offset,
2629+ (void *)buffer, count);
2630+ break;
2631+ default:
2632+ SSB_WARN_ON(1);
2633+ }
2634+ if (!error)
2635+ goto out;
2636+
2637+err_out:
2638+ dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
2639+ bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
2640+out:
2641+ sdio_release_host(bus->host_sdio);
2642+}
2643+
2644+#endif /* CONFIG_SSB_BLOCKIO */
2645+
2646+/* Not "static", as it's used in main.c */
2647+const struct ssb_bus_ops ssb_sdio_ops = {
2648+ .read8 = ssb_sdio_read8,
2649+ .read16 = ssb_sdio_read16,
2650+ .read32 = ssb_sdio_read32,
2651+ .write8 = ssb_sdio_write8,
2652+ .write16 = ssb_sdio_write16,
2653+ .write32 = ssb_sdio_write32,
2654+#ifdef CONFIG_SSB_BLOCKIO
2655+ .block_read = ssb_sdio_block_read,
2656+ .block_write = ssb_sdio_block_write,
2657+#endif
2658+};
2659+
2660+#define GOTO_ERROR_ON(condition, description) do { \
2661+ if (unlikely(condition)) { \
2662+ error_description = description; \
2663+ goto error; \
2664+ } \
2665+ } while (0)
2666+
2667+int ssb_sdio_get_invariants(struct ssb_bus *bus,
2668+ struct ssb_init_invariants *iv)
2669+{
2670+ struct ssb_sprom *sprom = &iv->sprom;
2671+ struct ssb_boardinfo *bi = &iv->boardinfo;
2672+ const char *error_description = "none";
2673+ struct sdio_func_tuple *tuple;
2674+ void *mac;
2675+
2676+ memset(sprom, 0xFF, sizeof(*sprom));
2677+ sprom->boardflags_lo = 0;
2678+ sprom->boardflags_hi = 0;
2679+
2680+ tuple = bus->host_sdio->tuples;
2681+ while (tuple) {
2682+ switch (tuple->code) {
2683+ case 0x22: /* extended function */
2684+ switch (tuple->data[0]) {
2685+ case CISTPL_FUNCE_LAN_NODE_ID:
2686+ GOTO_ERROR_ON((tuple->size != 7) &&
2687+ (tuple->data[1] != 6),
2688+ "mac tpl size");
2689+ /* fetch the MAC address. */
2690+ mac = tuple->data + 2;
2691+ memcpy(sprom->il0mac, mac, ETH_ALEN);
2692+ memcpy(sprom->et1mac, mac, ETH_ALEN);
2693+ break;
2694+ default:
2695+ break;
2696+ }
2697+ break;
2698+ case 0x80: /* vendor specific tuple */
2699+ switch (tuple->data[0]) {
2700+ case SSB_SDIO_CIS_SROMREV:
2701+ GOTO_ERROR_ON(tuple->size != 2,
2702+ "sromrev tpl size");
2703+ sprom->revision = tuple->data[1];
2704+ break;
2705+ case SSB_SDIO_CIS_ID:
2706+ GOTO_ERROR_ON((tuple->size != 5) &&
2707+ (tuple->size != 7),
2708+ "id tpl size");
2709+ bi->vendor = tuple->data[1] |
2710+ (tuple->data[2]<<8);
2711+ break;
2712+ case SSB_SDIO_CIS_BOARDREV:
2713+ GOTO_ERROR_ON(tuple->size != 2,
2714+ "boardrev tpl size");
2715+ sprom->board_rev = tuple->data[1];
2716+ break;
2717+ case SSB_SDIO_CIS_PA:
2718+ GOTO_ERROR_ON((tuple->size != 9) &&
2719+ (tuple->size != 10),
2720+ "pa tpl size");
2721+ sprom->pa0b0 = tuple->data[1] |
2722+ ((u16)tuple->data[2] << 8);
2723+ sprom->pa0b1 = tuple->data[3] |
2724+ ((u16)tuple->data[4] << 8);
2725+ sprom->pa0b2 = tuple->data[5] |
2726+ ((u16)tuple->data[6] << 8);
2727+ sprom->itssi_a = tuple->data[7];
2728+ sprom->itssi_bg = tuple->data[7];
2729+ sprom->maxpwr_a = tuple->data[8];
2730+ sprom->maxpwr_bg = tuple->data[8];
2731+ break;
2732+ case SSB_SDIO_CIS_OEMNAME:
2733+ /* Not present */
2734+ break;
2735+ case SSB_SDIO_CIS_CCODE:
2736+ GOTO_ERROR_ON(tuple->size != 2,
2737+ "ccode tpl size");
2738+ sprom->country_code = tuple->data[1];
2739+ break;
2740+ case SSB_SDIO_CIS_ANTENNA:
2741+ GOTO_ERROR_ON(tuple->size != 2,
2742+ "ant tpl size");
2743+ sprom->ant_available_a = tuple->data[1];
2744+ sprom->ant_available_bg = tuple->data[1];
2745+ break;
2746+ case SSB_SDIO_CIS_ANTGAIN:
2747+ GOTO_ERROR_ON(tuple->size != 2,
2748+ "antg tpl size");
2749+ sprom->antenna_gain.ghz24.a0 = tuple->data[1];
2750+ sprom->antenna_gain.ghz24.a1 = tuple->data[1];
2751+ sprom->antenna_gain.ghz24.a2 = tuple->data[1];
2752+ sprom->antenna_gain.ghz24.a3 = tuple->data[1];
2753+ sprom->antenna_gain.ghz5.a0 = tuple->data[1];
2754+ sprom->antenna_gain.ghz5.a1 = tuple->data[1];
2755+ sprom->antenna_gain.ghz5.a2 = tuple->data[1];
2756+ sprom->antenna_gain.ghz5.a3 = tuple->data[1];
2757+ break;
2758+ case SSB_SDIO_CIS_BFLAGS:
2759+ GOTO_ERROR_ON((tuple->size != 3) &&
2760+ (tuple->size != 5),
2761+ "bfl tpl size");
2762+ sprom->boardflags_lo = tuple->data[1] |
2763+ ((u16)tuple->data[2] << 8);
2764+ break;
2765+ case SSB_SDIO_CIS_LEDS:
2766+ GOTO_ERROR_ON(tuple->size != 5,
2767+ "leds tpl size");
2768+ sprom->gpio0 = tuple->data[1];
2769+ sprom->gpio1 = tuple->data[2];
2770+ sprom->gpio2 = tuple->data[3];
2771+ sprom->gpio3 = tuple->data[4];
2772+ break;
2773+ default:
2774+ break;
2775+ }
2776+ break;
2777+ default:
2778+ break;
2779+ }
2780+ tuple = tuple->next;
2781+ }
2782+
2783+ return 0;
2784+error:
2785+ dev_err(ssb_sdio_dev(bus), "failed to fetch device invariants: %s\n",
2786+ error_description);
2787+ return -ENODEV;
2788+}
2789+
2790+void ssb_sdio_exit(struct ssb_bus *bus)
2791+{
2792+ if (bus->bustype != SSB_BUSTYPE_SDIO)
2793+ return;
2794+ /* Nothing to do here. */
2795+}
2796+
2797+int ssb_sdio_init(struct ssb_bus *bus)
2798+{
2799+ if (bus->bustype != SSB_BUSTYPE_SDIO)
2800+ return 0;
2801+
2802+ bus->sdio_sbaddr = ~0;
2803+
2804+ return 0;
2805+}
2806--- a/drivers/ssb/sprom.c
2807+++ b/drivers/ssb/sprom.c
2808@@ -14,9 +14,10 @@
2809 #include "ssb_private.h"
2810 
2811 #include <linux/ctype.h>
2812+#include <linux/slab.h>
2813 
2814 
2815-static const struct ssb_sprom *fallback_sprom;
2816+static int(*get_fallback_sprom)(struct ssb_bus *dev, struct ssb_sprom *out);
2817 
2818 
2819 static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
2820@@ -102,6 +103,7 @@ ssize_t ssb_attr_sprom_store(struct ssb_
2821     u16 *sprom;
2822     int res = 0, err = -ENOMEM;
2823     size_t sprom_size_words = bus->sprom_size;
2824+ struct ssb_freeze_context freeze;
2825 
2826     sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
2827     if (!sprom)
2828@@ -123,18 +125,13 @@ ssize_t ssb_attr_sprom_store(struct ssb_
2829     err = -ERESTARTSYS;
2830     if (mutex_lock_interruptible(&bus->sprom_mutex))
2831         goto out_kfree;
2832- err = ssb_devices_freeze(bus);
2833- if (err == -EOPNOTSUPP) {
2834- ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze devices. "
2835- "No suspend support. Is CONFIG_PM enabled?\n");
2836- goto out_unlock;
2837- }
2838+ err = ssb_devices_freeze(bus, &freeze);
2839     if (err) {
2840         ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n");
2841         goto out_unlock;
2842     }
2843     res = sprom_write(bus, sprom);
2844- err = ssb_devices_thaw(bus);
2845+ err = ssb_devices_thaw(&freeze);
2846     if (err)
2847         ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n");
2848 out_unlock:
2849@@ -148,34 +145,56 @@ out:
2850 }
2851 
2852 /**
2853- * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found.
2854+ * ssb_arch_register_fallback_sprom - Registers a method providing a
2855+ * fallback SPROM if no SPROM is found.
2856  *
2857- * @sprom: The SPROM data structure to register.
2858+ * @sprom_callback: The callback function.
2859  *
2860- * With this function the architecture implementation may register a fallback
2861- * SPROM data structure. The fallback is only used for PCI based SSB devices,
2862- * where no valid SPROM can be found in the shadow registers.
2863+ * With this function the architecture implementation may register a
2864+ * callback handler which fills the SPROM data structure. The fallback is
2865+ * only used for PCI based SSB devices, where no valid SPROM can be found
2866+ * in the shadow registers.
2867  *
2868- * This function is useful for weird architectures that have a half-assed SSB device
2869- * hardwired to their PCI bus.
2870+ * This function is useful for weird architectures that have a half-assed
2871+ * SSB device hardwired to their PCI bus.
2872  *
2873- * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently
2874- * don't use this fallback.
2875- * Architectures must provide the SPROM for native SSB devices anyway,
2876- * so the fallback also isn't used for native devices.
2877+ * Note that it does only work with PCI attached SSB devices. PCMCIA
2878+ * devices currently don't use this fallback.
2879+ * Architectures must provide the SPROM for native SSB devices anyway, so
2880+ * the fallback also isn't used for native devices.
2881  *
2882- * This function is available for architecture code, only. So it is not exported.
2883+ * This function is available for architecture code, only. So it is not
2884+ * exported.
2885  */
2886-int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom)
2887+int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus,
2888+ struct ssb_sprom *out))
2889 {
2890- if (fallback_sprom)
2891+ if (get_fallback_sprom)
2892         return -EEXIST;
2893- fallback_sprom = sprom;
2894+ get_fallback_sprom = sprom_callback;
2895 
2896     return 0;
2897 }
2898 
2899-const struct ssb_sprom *ssb_get_fallback_sprom(void)
2900+int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out)
2901 {
2902- return fallback_sprom;
2903+ if (!get_fallback_sprom)
2904+ return -ENOENT;
2905+
2906+ return get_fallback_sprom(bus, out);
2907+}
2908+
2909+/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
2910+bool ssb_is_sprom_available(struct ssb_bus *bus)
2911+{
2912+ /* status register only exists on chipcomon rev >= 11 and we need check
2913+ for >= 31 only */
2914+ /* this routine differs from specs as we do not access SPROM directly
2915+ on PCMCIA */
2916+ if (bus->bustype == SSB_BUSTYPE_PCI &&
2917+ bus->chipco.dev && /* can be unavailable! */
2918+ bus->chipco.dev->id.revision >= 31)
2919+ return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
2920+
2921+ return true;
2922 }
2923--- a/drivers/ssb/ssb_private.h
2924+++ b/drivers/ssb/ssb_private.h
2925@@ -114,6 +114,46 @@ static inline int ssb_pcmcia_init(struct
2926 }
2927 #endif /* CONFIG_SSB_PCMCIAHOST */
2928 
2929+/* sdio.c */
2930+#ifdef CONFIG_SSB_SDIOHOST
2931+extern int ssb_sdio_get_invariants(struct ssb_bus *bus,
2932+ struct ssb_init_invariants *iv);
2933+
2934+extern u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset);
2935+extern int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev);
2936+extern int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx);
2937+extern int ssb_sdio_hardware_setup(struct ssb_bus *bus);
2938+extern void ssb_sdio_exit(struct ssb_bus *bus);
2939+extern int ssb_sdio_init(struct ssb_bus *bus);
2940+
2941+extern const struct ssb_bus_ops ssb_sdio_ops;
2942+#else /* CONFIG_SSB_SDIOHOST */
2943+static inline u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset)
2944+{
2945+ return 0;
2946+}
2947+static inline int ssb_sdio_switch_core(struct ssb_bus *bus,
2948+ struct ssb_device *dev)
2949+{
2950+ return 0;
2951+}
2952+static inline int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
2953+{
2954+ return 0;
2955+}
2956+static inline int ssb_sdio_hardware_setup(struct ssb_bus *bus)
2957+{
2958+ return 0;
2959+}
2960+static inline void ssb_sdio_exit(struct ssb_bus *bus)
2961+{
2962+}
2963+static inline int ssb_sdio_init(struct ssb_bus *bus)
2964+{
2965+ return 0;
2966+}
2967+#endif /* CONFIG_SSB_SDIOHOST */
2968+
2969 
2970 /* scan.c */
2971 extern const char *ssb_core_name(u16 coreid);
2972@@ -131,24 +171,33 @@ ssize_t ssb_attr_sprom_store(struct ssb_
2973                  const char *buf, size_t count,
2974                  int (*sprom_check_crc)(const u16 *sprom, size_t size),
2975                  int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
2976-extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
2977+extern int ssb_fill_sprom_with_fallback(struct ssb_bus *bus,
2978+ struct ssb_sprom *out);
2979 
2980 
2981 /* core.c */
2982 extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m);
2983-extern int ssb_devices_freeze(struct ssb_bus *bus);
2984-extern int ssb_devices_thaw(struct ssb_bus *bus);
2985 extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev);
2986 int ssb_for_each_bus_call(unsigned long data,
2987               int (*func)(struct ssb_bus *bus, unsigned long data));
2988 extern struct ssb_bus *ssb_pcmcia_dev_to_bus(struct pcmcia_device *pdev);
2989 
2990+struct ssb_freeze_context {
2991+ /* Pointer to the bus */
2992+ struct ssb_bus *bus;
2993+ /* Boolean list to indicate whether a device is frozen on this bus. */
2994+ bool device_frozen[SSB_MAX_NR_CORES];
2995+};
2996+extern int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx);
2997+extern int ssb_devices_thaw(struct ssb_freeze_context *ctx);
2998+
2999+
3000 
3001 /* b43_pci_bridge.c */
3002 #ifdef CONFIG_SSB_B43_PCI_BRIDGE
3003 extern int __init b43_pci_ssb_bridge_init(void);
3004 extern void __exit b43_pci_ssb_bridge_exit(void);
3005-#else /* CONFIG_SSB_B43_PCI_BRIDGR */
3006+#else /* CONFIG_SSB_B43_PCI_BRIDGE */
3007 static inline int b43_pci_ssb_bridge_init(void)
3008 {
3009     return 0;
3010@@ -156,6 +205,6 @@ static inline int b43_pci_ssb_bridge_ini
3011 static inline void b43_pci_ssb_bridge_exit(void)
3012 {
3013 }
3014-#endif /* CONFIG_SSB_PCIHOST */
3015+#endif /* CONFIG_SSB_B43_PCI_BRIDGE */
3016 
3017 #endif /* LINUX_SSB_PRIVATE_H_ */
3018--- a/include/linux/pci_ids.h
3019+++ b/include/linux/pci_ids.h
3020@@ -2017,6 +2017,7 @@
3021 #define PCI_DEVICE_ID_AFAVLAB_P030 0x2182
3022 #define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150
3023 
3024+#define PCI_VENDOR_ID_BCM_GVC 0x14a4
3025 #define PCI_VENDOR_ID_BROADCOM 0x14e4
3026 #define PCI_DEVICE_ID_TIGON3_5752 0x1600
3027 #define PCI_DEVICE_ID_TIGON3_5752M 0x1601
3028--- a/include/linux/ssb/ssb.h
3029+++ b/include/linux/ssb/ssb.h
3030@@ -27,24 +27,60 @@ struct ssb_sprom {
3031     u8 et1mdcport; /* MDIO for enet1 */
3032     u8 board_rev; /* Board revision number from SPROM. */
3033     u8 country_code; /* Country Code */
3034- u8 ant_available_a; /* A-PHY antenna available bits (up to 4) */
3035- u8 ant_available_bg; /* B/G-PHY antenna available bits (up to 4) */
3036+ u16 leddc_on_time; /* LED Powersave Duty Cycle On Count */
3037+ u16 leddc_off_time; /* LED Powersave Duty Cycle Off Count */
3038+ u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */
3039+ u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */
3040     u16 pa0b0;
3041     u16 pa0b1;
3042     u16 pa0b2;
3043     u16 pa1b0;
3044     u16 pa1b1;
3045     u16 pa1b2;
3046+ u16 pa1lob0;
3047+ u16 pa1lob1;
3048+ u16 pa1lob2;
3049+ u16 pa1hib0;
3050+ u16 pa1hib1;
3051+ u16 pa1hib2;
3052     u8 gpio0; /* GPIO pin 0 */
3053     u8 gpio1; /* GPIO pin 1 */
3054     u8 gpio2; /* GPIO pin 2 */
3055     u8 gpio3; /* GPIO pin 3 */
3056- u16 maxpwr_a; /* A-PHY Amplifier Max Power (in dBm Q5.2) */
3057- u16 maxpwr_bg; /* B/G-PHY Amplifier Max Power (in dBm Q5.2) */
3058+ u16 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
3059+ u16 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
3060+ u16 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
3061+ u16 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
3062     u8 itssi_a; /* Idle TSSI Target for A-PHY */
3063     u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */
3064- u16 boardflags_lo; /* Boardflags (low 16 bits) */
3065- u16 boardflags_hi; /* Boardflags (high 16 bits) */
3066+ u8 tri2g; /* 2.4GHz TX isolation */
3067+ u8 tri5gl; /* 5.2GHz TX isolation */
3068+ u8 tri5g; /* 5.3GHz TX isolation */
3069+ u8 tri5gh; /* 5.8GHz TX isolation */
3070+ u8 txpid2g[4]; /* 2GHz TX power index */
3071+ u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */
3072+ u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */
3073+ u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */
3074+ u8 rxpo2g; /* 2GHz RX power offset */
3075+ u8 rxpo5g; /* 5GHz RX power offset */
3076+ u8 rssisav2g; /* 2GHz RSSI params */
3077+ u8 rssismc2g;
3078+ u8 rssismf2g;
3079+ u8 bxa2g; /* 2GHz BX arch */
3080+ u8 rssisav5g; /* 5GHz RSSI params */
3081+ u8 rssismc5g;
3082+ u8 rssismf5g;
3083+ u8 bxa5g; /* 5GHz BX arch */
3084+ u16 cck2gpo; /* CCK power offset */
3085+ u32 ofdm2gpo; /* 2.4GHz OFDM power offset */
3086+ u32 ofdm5glpo; /* 5.2GHz OFDM power offset */
3087+ u32 ofdm5gpo; /* 5.3GHz OFDM power offset */
3088+ u32 ofdm5ghpo; /* 5.8GHz OFDM power offset */
3089+ u16 boardflags_lo; /* Board flags (bits 0-15) */
3090+ u16 boardflags_hi; /* Board flags (bits 16-31) */
3091+ u16 boardflags2_lo; /* Board flags (bits 32-47) */
3092+ u16 boardflags2_hi; /* Board flags (bits 48-63) */
3093+ /* TODO store board flags in a single u64 */
3094 
3095     /* Antenna gain values for up to 4 antennas
3096      * on each band. Values in dBm/4 (Q5.2). Negative gain means the
3097@@ -58,14 +94,14 @@ struct ssb_sprom {
3098         } ghz5; /* 5GHz band */
3099     } antenna_gain;
3100 
3101- /* TODO - add any parameters needed from rev 2, 3, or 4 SPROMs */
3102+ /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
3103 };
3104 
3105 /* Information about the PCB the circuitry is soldered on. */
3106 struct ssb_boardinfo {
3107     u16 vendor;
3108     u16 type;
3109- u16 rev;
3110+ u8 rev;
3111 };
3112 
3113 
3114@@ -137,7 +173,7 @@ struct ssb_device {
3115      * is an optimization. */
3116     const struct ssb_bus_ops *ops;
3117 
3118- struct device *dev;
3119+ struct device *dev, *dma_dev;
3120 
3121     struct ssb_bus *bus;
3122     struct ssb_device_id id;
3123@@ -208,6 +244,7 @@ enum ssb_bustype {
3124     SSB_BUSTYPE_SSB, /* This SSB bus is the system bus */
3125     SSB_BUSTYPE_PCI, /* SSB is connected to PCI bus */
3126     SSB_BUSTYPE_PCMCIA, /* SSB is connected to PCMCIA bus */
3127+ SSB_BUSTYPE_SDIO, /* SSB is connected to SDIO bus */
3128 };
3129 
3130 /* board_vendor */
3131@@ -238,20 +275,33 @@ struct ssb_bus {
3132 
3133     const struct ssb_bus_ops *ops;
3134 
3135- /* The core in the basic address register window. (PCI bus only) */
3136+ /* The core currently mapped into the MMIO window.
3137+ * Not valid on all host-buses. So don't use outside of SSB. */
3138     struct ssb_device *mapped_device;
3139- /* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
3140- u8 mapped_pcmcia_seg;
3141+ union {
3142+ /* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
3143+ u8 mapped_pcmcia_seg;
3144+ /* Current SSB base address window for SDIO. */
3145+ u32 sdio_sbaddr;
3146+ };
3147     /* Lock for core and segment switching.
3148      * On PCMCIA-host busses this is used to protect the whole MMIO access. */
3149     spinlock_t bar_lock;
3150 
3151- /* The bus this backplane is running on. */
3152+ /* The host-bus this backplane is running on. */
3153     enum ssb_bustype bustype;
3154- /* Pointer to the PCI bus (only valid if bustype == SSB_BUSTYPE_PCI). */
3155- struct pci_dev *host_pci;
3156- /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
3157- struct pcmcia_device *host_pcmcia;
3158+ /* Pointers to the host-bus. Check bustype before using any of these pointers. */
3159+ union {
3160+ /* Pointer to the PCI bus (only valid if bustype == SSB_BUSTYPE_PCI). */
3161+ struct pci_dev *host_pci;
3162+ /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
3163+ struct pcmcia_device *host_pcmcia;
3164+ /* Pointer to the SDIO device (only if bustype == SSB_BUSTYPE_SDIO). */
3165+ struct sdio_func *host_sdio;
3166+ };
3167+
3168+ /* See enum ssb_quirks */
3169+ unsigned int quirks;
3170 
3171 #ifdef CONFIG_SSB_SPROM
3172     /* Mutex to protect the SPROM writing. */
3173@@ -260,7 +310,8 @@ struct ssb_bus {
3174 
3175     /* ID information about the Chip. */
3176     u16 chip_id;
3177- u16 chip_rev;
3178+ u8 chip_rev;
3179+ u16 sprom_offset;
3180     u16 sprom_size; /* number of words in sprom */
3181     u8 chip_package;
3182 
3183@@ -306,6 +357,11 @@ struct ssb_bus {
3184 #endif /* DEBUG */
3185 };
3186 
3187+enum ssb_quirks {
3188+ /* SDIO connected card requires performing a read after writing a 32-bit value */
3189+ SSB_QUIRK_SDIO_READ_AFTER_WRITE32 = (1 << 0),
3190+};
3191+
3192 /* The initialization-invariants. */
3193 struct ssb_init_invariants {
3194     /* Versioning information about the PCB. */
3195@@ -336,12 +392,23 @@ extern int ssb_bus_pcmciabus_register(st
3196                       struct pcmcia_device *pcmcia_dev,
3197                       unsigned long baseaddr);
3198 #endif /* CONFIG_SSB_PCMCIAHOST */
3199+#ifdef CONFIG_SSB_SDIOHOST
3200+extern int ssb_bus_sdiobus_register(struct ssb_bus *bus,
3201+ struct sdio_func *sdio_func,
3202+ unsigned int quirks);
3203+#endif /* CONFIG_SSB_SDIOHOST */
3204+
3205 
3206 extern void ssb_bus_unregister(struct ssb_bus *bus);
3207 
3208+/* Does the device have an SPROM? */
3209+extern bool ssb_is_sprom_available(struct ssb_bus *bus);
3210+
3211 /* Set a fallback SPROM.
3212  * See kdoc at the function definition for complete documentation. */
3213-extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
3214+extern int ssb_arch_register_fallback_sprom(
3215+ int (*sprom_callback)(struct ssb_bus *bus,
3216+ struct ssb_sprom *out));
3217 
3218 /* Suspend a SSB bus.
3219  * Call this from the parent bus suspend routine. */
3220@@ -612,6 +679,7 @@ extern int ssb_bus_may_powerdown(struct
3221  * Otherwise static always-on powercontrol will be used. */
3222 extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
3223 
3224+extern void ssb_commit_settings(struct ssb_bus *bus);
3225 
3226 /* Various helper functions */
3227 extern u32 ssb_admatch_base(u32 adm);
3228--- a/include/linux/ssb/ssb_driver_chipcommon.h
3229+++ b/include/linux/ssb/ssb_driver_chipcommon.h
3230@@ -53,6 +53,7 @@
3231 #define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */
3232 #define SSB_CHIPCO_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */
3233 #define SSB_CHIPCO_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */
3234+#define SSB_CHIPCO_CAP_SPROM 0x40000000 /* SPROM present */
3235 #define SSB_CHIPCO_CORECTL 0x0008
3236 #define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
3237 #define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
3238@@ -122,6 +123,8 @@
3239 #define SSB_CHIPCO_FLASHDATA 0x0048
3240 #define SSB_CHIPCO_BCAST_ADDR 0x0050
3241 #define SSB_CHIPCO_BCAST_DATA 0x0054
3242+#define SSB_CHIPCO_GPIOPULLUP 0x0058 /* Rev >= 20 only */
3243+#define SSB_CHIPCO_GPIOPULLDOWN 0x005C /* Rev >= 20 only */
3244 #define SSB_CHIPCO_GPIOIN 0x0060
3245 #define SSB_CHIPCO_GPIOOUT 0x0064
3246 #define SSB_CHIPCO_GPIOOUTEN 0x0068
3247@@ -130,6 +133,9 @@
3248 #define SSB_CHIPCO_GPIOIRQ 0x0074
3249 #define SSB_CHIPCO_WATCHDOG 0x0080
3250 #define SSB_CHIPCO_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */
3251+#define SSB_CHIPCO_GPIOTIMER_OFFTIME 0x0000FFFF
3252+#define SSB_CHIPCO_GPIOTIMER_OFFTIME_SHIFT 0
3253+#define SSB_CHIPCO_GPIOTIMER_ONTIME 0xFFFF0000
3254 #define SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT 16
3255 #define SSB_CHIPCO_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */
3256 #define SSB_CHIPCO_CLOCK_N 0x0090
3257@@ -188,8 +194,10 @@
3258 #define SSB_CHIPCO_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
3259 #define SSB_CHIPCO_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
3260 #define SSB_CHIPCO_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
3261-#define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00010000 /* HT available */
3262-#define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00020000 /* APL available */
3263+#define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
3264+#define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00020000 /* HT available */
3265+#define SSB_CHIPCO_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
3266+#define SSB_CHIPCO_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
3267 #define SSB_CHIPCO_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
3268 #define SSB_CHIPCO_UART0_DATA 0x0300
3269 #define SSB_CHIPCO_UART0_IMR 0x0304
3270@@ -385,6 +393,7 @@
3271 
3272 
3273 /** Chip specific Chip-Status register contents. */
3274+#define SSB_CHIPCO_CHST_4322_SPROM_EXISTS 0x00000040 /* SPROM present */
3275 #define SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL 0x00000003
3276 #define SSB_CHIPCO_CHST_4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
3277 #define SSB_CHIPCO_CHST_4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
3278@@ -398,6 +407,18 @@
3279 #define SSB_CHIPCO_CHST_4325_RCAL_VALUE_SHIFT 4
3280 #define SSB_CHIPCO_CHST_4325_PMUTOP_2B 0x00000200 /* 1 for 2b, 0 for to 2a */
3281 
3282+/** Macros to determine SPROM presence based on Chip-Status register. */
3283+#define SSB_CHIPCO_CHST_4312_SPROM_PRESENT(status) \
3284+ ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
3285+ SSB_CHIPCO_CHST_4325_OTP_SEL)
3286+#define SSB_CHIPCO_CHST_4322_SPROM_PRESENT(status) \
3287+ (status & SSB_CHIPCO_CHST_4322_SPROM_EXISTS)
3288+#define SSB_CHIPCO_CHST_4325_SPROM_PRESENT(status) \
3289+ (((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
3290+ SSB_CHIPCO_CHST_4325_DEFCIS_SEL) && \
3291+ ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
3292+ SSB_CHIPCO_CHST_4325_OTP_SEL))
3293+
3294 
3295 
3296 /** Clockcontrol masks and values **/
3297@@ -564,6 +585,7 @@ struct ssb_chipcommon_pmu {
3298 struct ssb_chipcommon {
3299     struct ssb_device *dev;
3300     u32 capabilities;
3301+ u32 status;
3302     /* Fast Powerup Delay constant */
3303     u16 fast_pwrup_delay;
3304     struct ssb_chipcommon_pmu pmu;
3305@@ -629,5 +651,15 @@ extern int ssb_chipco_serial_init(struct
3306 /* PMU support */
3307 extern void ssb_pmu_init(struct ssb_chipcommon *cc);
3308 
3309+enum ssb_pmu_ldo_volt_id {
3310+ LDO_PAREF = 0,
3311+ LDO_VOLT1,
3312+ LDO_VOLT2,
3313+ LDO_VOLT3,
3314+};
3315+
3316+void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
3317+ enum ssb_pmu_ldo_volt_id id, u32 voltage);
3318+void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
3319 
3320 #endif /* LINUX_SSB_CHIPCO_H_ */
3321--- a/include/linux/ssb/ssb_regs.h
3322+++ b/include/linux/ssb/ssb_regs.h
3323@@ -85,6 +85,8 @@
3324 #define SSB_IMSTATE_AP_RSV 0x00000030 /* Reserved */
3325 #define SSB_IMSTATE_IBE 0x00020000 /* In Band Error */
3326 #define SSB_IMSTATE_TO 0x00040000 /* Timeout */
3327+#define SSB_IMSTATE_BUSY 0x01800000 /* Busy (Backplane rev >= 2.3 only) */
3328+#define SSB_IMSTATE_REJECT 0x02000000 /* Reject (Backplane rev >= 2.3 only) */
3329 #define SSB_INTVEC 0x0F94 /* SB Interrupt Mask */
3330 #define SSB_INTVEC_PCI 0x00000001 /* Enable interrupts for PCI */
3331 #define SSB_INTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */
3332@@ -95,7 +97,7 @@
3333 #define SSB_INTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */
3334 #define SSB_TMSLOW 0x0F98 /* SB Target State Low */
3335 #define SSB_TMSLOW_RESET 0x00000001 /* Reset */
3336-#define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */
3337+#define SSB_TMSLOW_REJECT 0x00000002 /* Reject (Standard Backplane) */
3338 #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */
3339 #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */
3340 #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
3341@@ -162,7 +164,7 @@
3342 
3343 /* SPROM shadow area. If not otherwise noted, fields are
3344  * two bytes wide. Note that the SPROM can _only_ be read
3345- * in two-byte quantinies.
3346+ * in two-byte quantities.
3347  */
3348 #define SSB_SPROMSIZE_WORDS 64
3349 #define SSB_SPROMSIZE_BYTES (SSB_SPROMSIZE_WORDS * sizeof(u16))
3350@@ -170,26 +172,27 @@
3351 #define SSB_SPROMSIZE_WORDS_R4 220
3352 #define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))
3353 #define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16))
3354-#define SSB_SPROM_BASE 0x1000
3355-#define SSB_SPROM_REVISION 0x107E
3356+#define SSB_SPROM_BASE1 0x1000
3357+#define SSB_SPROM_BASE31 0x0800
3358+#define SSB_SPROM_REVISION 0x007E
3359 #define SSB_SPROM_REVISION_REV 0x00FF /* SPROM Revision number */
3360 #define SSB_SPROM_REVISION_CRC 0xFF00 /* SPROM CRC8 value */
3361 #define SSB_SPROM_REVISION_CRC_SHIFT 8
3362 
3363 /* SPROM Revision 1 */
3364-#define SSB_SPROM1_SPID 0x1004 /* Subsystem Product ID for PCI */
3365-#define SSB_SPROM1_SVID 0x1006 /* Subsystem Vendor ID for PCI */
3366-#define SSB_SPROM1_PID 0x1008 /* Product ID for PCI */
3367-#define SSB_SPROM1_IL0MAC 0x1048 /* 6 bytes MAC address for 802.11b/g */
3368-#define SSB_SPROM1_ET0MAC 0x104E /* 6 bytes MAC address for Ethernet */
3369-#define SSB_SPROM1_ET1MAC 0x1054 /* 6 bytes MAC address for 802.11a */
3370-#define SSB_SPROM1_ETHPHY 0x105A /* Ethernet PHY settings */
3371+#define SSB_SPROM1_SPID 0x0004 /* Subsystem Product ID for PCI */
3372+#define SSB_SPROM1_SVID 0x0006 /* Subsystem Vendor ID for PCI */
3373+#define SSB_SPROM1_PID 0x0008 /* Product ID for PCI */
3374+#define SSB_SPROM1_IL0MAC 0x0048 /* 6 bytes MAC address for 802.11b/g */
3375+#define SSB_SPROM1_ET0MAC 0x004E /* 6 bytes MAC address for Ethernet */
3376+#define SSB_SPROM1_ET1MAC 0x0054 /* 6 bytes MAC address for 802.11a */
3377+#define SSB_SPROM1_ETHPHY 0x005A /* Ethernet PHY settings */
3378 #define SSB_SPROM1_ETHPHY_ET0A 0x001F /* MII Address for enet0 */
3379 #define SSB_SPROM1_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */
3380 #define SSB_SPROM1_ETHPHY_ET1A_SHIFT 5
3381 #define SSB_SPROM1_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */
3382 #define SSB_SPROM1_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */
3383-#define SSB_SPROM1_BINF 0x105C /* Board info */
3384+#define SSB_SPROM1_BINF 0x005C /* Board info */
3385 #define SSB_SPROM1_BINF_BREV 0x00FF /* Board Revision */
3386 #define SSB_SPROM1_BINF_CCODE 0x0F00 /* Country Code */
3387 #define SSB_SPROM1_BINF_CCODE_SHIFT 8
3388@@ -197,63 +200,63 @@
3389 #define SSB_SPROM1_BINF_ANTBG_SHIFT 12
3390 #define SSB_SPROM1_BINF_ANTA 0xC000 /* Available A-PHY antennas */
3391 #define SSB_SPROM1_BINF_ANTA_SHIFT 14
3392-#define SSB_SPROM1_PA0B0 0x105E
3393-#define SSB_SPROM1_PA0B1 0x1060
3394-#define SSB_SPROM1_PA0B2 0x1062
3395-#define SSB_SPROM1_GPIOA 0x1064 /* General Purpose IO pins 0 and 1 */
3396+#define SSB_SPROM1_PA0B0 0x005E
3397+#define SSB_SPROM1_PA0B1 0x0060
3398+#define SSB_SPROM1_PA0B2 0x0062
3399+#define SSB_SPROM1_GPIOA 0x0064 /* General Purpose IO pins 0 and 1 */
3400 #define SSB_SPROM1_GPIOA_P0 0x00FF /* Pin 0 */
3401 #define SSB_SPROM1_GPIOA_P1 0xFF00 /* Pin 1 */
3402 #define SSB_SPROM1_GPIOA_P1_SHIFT 8
3403-#define SSB_SPROM1_GPIOB 0x1066 /* General Purpuse IO pins 2 and 3 */
3404+#define SSB_SPROM1_GPIOB 0x0066 /* General Purpuse IO pins 2 and 3 */
3405 #define SSB_SPROM1_GPIOB_P2 0x00FF /* Pin 2 */
3406 #define SSB_SPROM1_GPIOB_P3 0xFF00 /* Pin 3 */
3407 #define SSB_SPROM1_GPIOB_P3_SHIFT 8
3408-#define SSB_SPROM1_MAXPWR 0x1068 /* Power Amplifier Max Power */
3409+#define SSB_SPROM1_MAXPWR 0x0068 /* Power Amplifier Max Power */
3410 #define SSB_SPROM1_MAXPWR_BG 0x00FF /* B-PHY and G-PHY (in dBm Q5.2) */
3411 #define SSB_SPROM1_MAXPWR_A 0xFF00 /* A-PHY (in dBm Q5.2) */
3412 #define SSB_SPROM1_MAXPWR_A_SHIFT 8
3413-#define SSB_SPROM1_PA1B0 0x106A
3414-#define SSB_SPROM1_PA1B1 0x106C
3415-#define SSB_SPROM1_PA1B2 0x106E
3416-#define SSB_SPROM1_ITSSI 0x1070 /* Idle TSSI Target */
3417+#define SSB_SPROM1_PA1B0 0x006A
3418+#define SSB_SPROM1_PA1B1 0x006C
3419+#define SSB_SPROM1_PA1B2 0x006E
3420+#define SSB_SPROM1_ITSSI 0x0070 /* Idle TSSI Target */
3421 #define SSB_SPROM1_ITSSI_BG 0x00FF /* B-PHY and G-PHY*/
3422 #define SSB_SPROM1_ITSSI_A 0xFF00 /* A-PHY */
3423 #define SSB_SPROM1_ITSSI_A_SHIFT 8
3424-#define SSB_SPROM1_BFLLO 0x1072 /* Boardflags (low 16 bits) */
3425-#define SSB_SPROM1_AGAIN 0x1074 /* Antenna Gain (in dBm Q5.2) */
3426+#define SSB_SPROM1_BFLLO 0x0072 /* Boardflags (low 16 bits) */
3427+#define SSB_SPROM1_AGAIN 0x0074 /* Antenna Gain (in dBm Q5.2) */
3428 #define SSB_SPROM1_AGAIN_BG 0x00FF /* B-PHY and G-PHY */
3429 #define SSB_SPROM1_AGAIN_BG_SHIFT 0
3430 #define SSB_SPROM1_AGAIN_A 0xFF00 /* A-PHY */
3431 #define SSB_SPROM1_AGAIN_A_SHIFT 8
3432 
3433 /* SPROM Revision 2 (inherits from rev 1) */
3434-#define SSB_SPROM2_BFLHI 0x1038 /* Boardflags (high 16 bits) */
3435-#define SSB_SPROM2_MAXP_A 0x103A /* A-PHY Max Power */
3436+#define SSB_SPROM2_BFLHI 0x0038 /* Boardflags (high 16 bits) */
3437+#define SSB_SPROM2_MAXP_A 0x003A /* A-PHY Max Power */
3438 #define SSB_SPROM2_MAXP_A_HI 0x00FF /* Max Power High */
3439 #define SSB_SPROM2_MAXP_A_LO 0xFF00 /* Max Power Low */
3440 #define SSB_SPROM2_MAXP_A_LO_SHIFT 8
3441-#define SSB_SPROM2_PA1LOB0 0x103C /* A-PHY PowerAmplifier Low Settings */
3442-#define SSB_SPROM2_PA1LOB1 0x103E /* A-PHY PowerAmplifier Low Settings */
3443-#define SSB_SPROM2_PA1LOB2 0x1040 /* A-PHY PowerAmplifier Low Settings */
3444-#define SSB_SPROM2_PA1HIB0 0x1042 /* A-PHY PowerAmplifier High Settings */
3445-#define SSB_SPROM2_PA1HIB1 0x1044 /* A-PHY PowerAmplifier High Settings */
3446-#define SSB_SPROM2_PA1HIB2 0x1046 /* A-PHY PowerAmplifier High Settings */
3447-#define SSB_SPROM2_OPO 0x1078 /* OFDM Power Offset from CCK Level */
3448+#define SSB_SPROM2_PA1LOB0 0x003C /* A-PHY PowerAmplifier Low Settings */
3449+#define SSB_SPROM2_PA1LOB1 0x003E /* A-PHY PowerAmplifier Low Settings */
3450+#define SSB_SPROM2_PA1LOB2 0x0040 /* A-PHY PowerAmplifier Low Settings */
3451+#define SSB_SPROM2_PA1HIB0 0x0042 /* A-PHY PowerAmplifier High Settings */
3452+#define SSB_SPROM2_PA1HIB1 0x0044 /* A-PHY PowerAmplifier High Settings */
3453+#define SSB_SPROM2_PA1HIB2 0x0046 /* A-PHY PowerAmplifier High Settings */
3454+#define SSB_SPROM2_OPO 0x0078 /* OFDM Power Offset from CCK Level */
3455 #define SSB_SPROM2_OPO_VALUE 0x00FF
3456 #define SSB_SPROM2_OPO_UNUSED 0xFF00
3457-#define SSB_SPROM2_CCODE 0x107C /* Two char Country Code */
3458+#define SSB_SPROM2_CCODE 0x007C /* Two char Country Code */
3459 
3460 /* SPROM Revision 3 (inherits most data from rev 2) */
3461-#define SSB_SPROM3_IL0MAC 0x104A /* 6 bytes MAC address for 802.11b/g */
3462-#define SSB_SPROM3_OFDMAPO 0x102C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
3463-#define SSB_SPROM3_OFDMALPO 0x1030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
3464-#define SSB_SPROM3_OFDMAHPO 0x1034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
3465-#define SSB_SPROM3_GPIOLDC 0x1042 /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */
3466+#define SSB_SPROM3_OFDMAPO 0x002C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
3467+#define SSB_SPROM3_OFDMALPO 0x0030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
3468+#define SSB_SPROM3_OFDMAHPO 0x0034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
3469+#define SSB_SPROM3_GPIOLDC 0x0042 /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */
3470 #define SSB_SPROM3_GPIOLDC_OFF 0x0000FF00 /* Off Count */
3471 #define SSB_SPROM3_GPIOLDC_OFF_SHIFT 8
3472 #define SSB_SPROM3_GPIOLDC_ON 0x00FF0000 /* On Count */
3473 #define SSB_SPROM3_GPIOLDC_ON_SHIFT 16
3474-#define SSB_SPROM3_CCKPO 0x1078 /* CCK Power Offset */
3475+#define SSB_SPROM3_IL0MAC 0x004A /* 6 bytes MAC address for 802.11b/g */
3476+#define SSB_SPROM3_CCKPO 0x0078 /* CCK Power Offset */
3477 #define SSB_SPROM3_CCKPO_1M 0x000F /* 1M Rate PO */
3478 #define SSB_SPROM3_CCKPO_2M 0x00F0 /* 2M Rate PO */
3479 #define SSB_SPROM3_CCKPO_2M_SHIFT 4
3480@@ -264,104 +267,200 @@
3481 #define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
3482 
3483 /* SPROM Revision 4 */
3484-#define SSB_SPROM4_IL0MAC 0x104C /* 6 byte MAC address for a/b/g/n */
3485-#define SSB_SPROM4_ETHPHY 0x105A /* Ethernet PHY settings ?? */
3486+#define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */
3487+#define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */
3488+#define SSB_SPROM4_BFL2LO 0x0048 /* Board flags 2 (low 16 bits) */
3489+#define SSB_SPROM4_BFL2HI 0x004A /* Board flags 2 Hi */
3490+#define SSB_SPROM4_IL0MAC 0x004C /* 6 byte MAC address for a/b/g/n */
3491+#define SSB_SPROM4_CCODE 0x0052 /* Country Code (2 bytes) */
3492+#define SSB_SPROM4_GPIOA 0x0056 /* Gen. Purpose IO # 0 and 1 */
3493+#define SSB_SPROM4_GPIOA_P0 0x00FF /* Pin 0 */
3494+#define SSB_SPROM4_GPIOA_P1 0xFF00 /* Pin 1 */
3495+#define SSB_SPROM4_GPIOA_P1_SHIFT 8
3496+#define SSB_SPROM4_GPIOB 0x0058 /* Gen. Purpose IO # 2 and 3 */
3497+#define SSB_SPROM4_GPIOB_P2 0x00FF /* Pin 2 */
3498+#define SSB_SPROM4_GPIOB_P3 0xFF00 /* Pin 3 */
3499+#define SSB_SPROM4_GPIOB_P3_SHIFT 8
3500+#define SSB_SPROM4_ETHPHY 0x005A /* Ethernet PHY settings ?? */
3501 #define SSB_SPROM4_ETHPHY_ET0A 0x001F /* MII Address for enet0 */
3502 #define SSB_SPROM4_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */
3503 #define SSB_SPROM4_ETHPHY_ET1A_SHIFT 5
3504 #define SSB_SPROM4_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */
3505 #define SSB_SPROM4_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */
3506-#define SSB_SPROM4_CCODE 0x1052 /* Country Code (2 bytes) */
3507-#define SSB_SPROM4_ANTAVAIL 0x105D /* Antenna available bitfields */
3508-#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */
3509-#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0
3510-#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */
3511-#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8
3512-#define SSB_SPROM4_BFLLO 0x1044 /* Boardflags (low 16 bits) */
3513-#define SSB_SPROM4_AGAIN01 0x105E /* Antenna Gain (in dBm Q5.2) */
3514+#define SSB_SPROM4_ANTAVAIL 0x005D /* Antenna available bitfields */
3515+#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */
3516+#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0
3517+#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */
3518+#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8
3519+#define SSB_SPROM4_AGAIN01 0x005E /* Antenna Gain (in dBm Q5.2) */
3520 #define SSB_SPROM4_AGAIN0 0x00FF /* Antenna 0 */
3521 #define SSB_SPROM4_AGAIN0_SHIFT 0
3522 #define SSB_SPROM4_AGAIN1 0xFF00 /* Antenna 1 */
3523 #define SSB_SPROM4_AGAIN1_SHIFT 8
3524-#define SSB_SPROM4_AGAIN23 0x1060
3525+#define SSB_SPROM4_AGAIN23 0x0060
3526 #define SSB_SPROM4_AGAIN2 0x00FF /* Antenna 2 */
3527 #define SSB_SPROM4_AGAIN2_SHIFT 0
3528 #define SSB_SPROM4_AGAIN3 0xFF00 /* Antenna 3 */
3529 #define SSB_SPROM4_AGAIN3_SHIFT 8
3530-#define SSB_SPROM4_BFLHI 0x1046 /* Board Flags Hi */
3531-#define SSB_SPROM4_MAXP_BG 0x1080 /* Max Power BG in path 1 */
3532+#define SSB_SPROM4_TXPID2G01 0x0062 /* TX Power Index 2GHz */
3533+#define SSB_SPROM4_TXPID2G0 0x00FF
3534+#define SSB_SPROM4_TXPID2G0_SHIFT 0
3535+#define SSB_SPROM4_TXPID2G1 0xFF00
3536+#define SSB_SPROM4_TXPID2G1_SHIFT 8
3537+#define SSB_SPROM4_TXPID2G23 0x0064 /* TX Power Index 2GHz */
3538+#define SSB_SPROM4_TXPID2G2 0x00FF
3539+#define SSB_SPROM4_TXPID2G2_SHIFT 0
3540+#define SSB_SPROM4_TXPID2G3 0xFF00
3541+#define SSB_SPROM4_TXPID2G3_SHIFT 8
3542+#define SSB_SPROM4_TXPID5G01 0x0066 /* TX Power Index 5GHz middle subband */
3543+#define SSB_SPROM4_TXPID5G0 0x00FF
3544+#define SSB_SPROM4_TXPID5G0_SHIFT 0
3545+#define SSB_SPROM4_TXPID5G1 0xFF00
3546+#define SSB_SPROM4_TXPID5G1_SHIFT 8
3547+#define SSB_SPROM4_TXPID5G23 0x0068 /* TX Power Index 5GHz middle subband */
3548+#define SSB_SPROM4_TXPID5G2 0x00FF
3549+#define SSB_SPROM4_TXPID5G2_SHIFT 0
3550+#define SSB_SPROM4_TXPID5G3 0xFF00
3551+#define SSB_SPROM4_TXPID5G3_SHIFT 8
3552+#define SSB_SPROM4_TXPID5GL01 0x006A /* TX Power Index 5GHz low subband */
3553+#define SSB_SPROM4_TXPID5GL0 0x00FF
3554+#define SSB_SPROM4_TXPID5GL0_SHIFT 0
3555+#define SSB_SPROM4_TXPID5GL1 0xFF00
3556+#define SSB_SPROM4_TXPID5GL1_SHIFT 8
3557+#define SSB_SPROM4_TXPID5GL23 0x006C /* TX Power Index 5GHz low subband */
3558+#define SSB_SPROM4_TXPID5GL2 0x00FF
3559+#define SSB_SPROM4_TXPID5GL2_SHIFT 0
3560+#define SSB_SPROM4_TXPID5GL3 0xFF00
3561+#define SSB_SPROM4_TXPID5GL3_SHIFT 8
3562+#define SSB_SPROM4_TXPID5GH01 0x006E /* TX Power Index 5GHz high subband */
3563+#define SSB_SPROM4_TXPID5GH0 0x00FF
3564+#define SSB_SPROM4_TXPID5GH0_SHIFT 0
3565+#define SSB_SPROM4_TXPID5GH1 0xFF00
3566+#define SSB_SPROM4_TXPID5GH1_SHIFT 8
3567+#define SSB_SPROM4_TXPID5GH23 0x0070 /* TX Power Index 5GHz high subband */
3568+#define SSB_SPROM4_TXPID5GH2 0x00FF
3569+#define SSB_SPROM4_TXPID5GH2_SHIFT 0
3570+#define SSB_SPROM4_TXPID5GH3 0xFF00
3571+#define SSB_SPROM4_TXPID5GH3_SHIFT 8
3572+#define SSB_SPROM4_MAXP_BG 0x0080 /* Max Power BG in path 1 */
3573 #define SSB_SPROM4_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */
3574 #define SSB_SPROM4_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */
3575 #define SSB_SPROM4_ITSSI_BG_SHIFT 8
3576-#define SSB_SPROM4_MAXP_A 0x108A /* Max Power A in path 1 */
3577+#define SSB_SPROM4_MAXP_A 0x008A /* Max Power A in path 1 */
3578 #define SSB_SPROM4_MAXP_A_MASK 0x00FF /* Mask for Max Power A */
3579 #define SSB_SPROM4_ITSSI_A 0xFF00 /* Mask for path 1 itssi_a */
3580 #define SSB_SPROM4_ITSSI_A_SHIFT 8
3581-#define SSB_SPROM4_GPIOA 0x1056 /* Gen. Purpose IO # 0 and 1 */
3582-#define SSB_SPROM4_GPIOA_P0 0x00FF /* Pin 0 */
3583-#define SSB_SPROM4_GPIOA_P1 0xFF00 /* Pin 1 */
3584-#define SSB_SPROM4_GPIOA_P1_SHIFT 8
3585-#define SSB_SPROM4_GPIOB 0x1058 /* Gen. Purpose IO # 2 and 3 */
3586-#define SSB_SPROM4_GPIOB_P2 0x00FF /* Pin 2 */
3587-#define SSB_SPROM4_GPIOB_P3 0xFF00 /* Pin 3 */
3588-#define SSB_SPROM4_GPIOB_P3_SHIFT 8
3589-#define SSB_SPROM4_PA0B0 0x1082 /* The paXbY locations are */
3590-#define SSB_SPROM4_PA0B1 0x1084 /* only guesses */
3591-#define SSB_SPROM4_PA0B2 0x1086
3592-#define SSB_SPROM4_PA1B0 0x108E
3593-#define SSB_SPROM4_PA1B1 0x1090
3594-#define SSB_SPROM4_PA1B2 0x1092
3595+#define SSB_SPROM4_PA0B0 0x0082 /* The paXbY locations are */
3596+#define SSB_SPROM4_PA0B1 0x0084 /* only guesses */
3597+#define SSB_SPROM4_PA0B2 0x0086
3598+#define SSB_SPROM4_PA1B0 0x008E
3599+#define SSB_SPROM4_PA1B1 0x0090
3600+#define SSB_SPROM4_PA1B2 0x0092
3601 
3602 /* SPROM Revision 5 (inherits most data from rev 4) */
3603-#define SSB_SPROM5_BFLLO 0x104A /* Boardflags (low 16 bits) */
3604-#define SSB_SPROM5_BFLHI 0x104C /* Board Flags Hi */
3605-#define SSB_SPROM5_IL0MAC 0x1052 /* 6 byte MAC address for a/b/g/n */
3606-#define SSB_SPROM5_CCODE 0x1044 /* Country Code (2 bytes) */
3607-#define SSB_SPROM5_GPIOA 0x1076 /* Gen. Purpose IO # 0 and 1 */
3608+#define SSB_SPROM5_CCODE 0x0044 /* Country Code (2 bytes) */
3609+#define SSB_SPROM5_BFLLO 0x004A /* Boardflags (low 16 bits) */
3610+#define SSB_SPROM5_BFLHI 0x004C /* Board Flags Hi */
3611+#define SSB_SPROM5_BFL2LO 0x004E /* Board flags 2 (low 16 bits) */
3612+#define SSB_SPROM5_BFL2HI 0x0050 /* Board flags 2 Hi */
3613+#define SSB_SPROM5_IL0MAC 0x0052 /* 6 byte MAC address for a/b/g/n */
3614+#define SSB_SPROM5_GPIOA 0x0076 /* Gen. Purpose IO # 0 and 1 */
3615 #define SSB_SPROM5_GPIOA_P0 0x00FF /* Pin 0 */
3616 #define SSB_SPROM5_GPIOA_P1 0xFF00 /* Pin 1 */
3617 #define SSB_SPROM5_GPIOA_P1_SHIFT 8
3618-#define SSB_SPROM5_GPIOB 0x1078 /* Gen. Purpose IO # 2 and 3 */
3619+#define SSB_SPROM5_GPIOB 0x0078 /* Gen. Purpose IO # 2 and 3 */
3620 #define SSB_SPROM5_GPIOB_P2 0x00FF /* Pin 2 */
3621 #define SSB_SPROM5_GPIOB_P3 0xFF00 /* Pin 3 */
3622 #define SSB_SPROM5_GPIOB_P3_SHIFT 8
3623 
3624 /* SPROM Revision 8 */
3625-#define SSB_SPROM8_BFLLO 0x1084 /* Boardflags (low 16 bits) */
3626-#define SSB_SPROM8_BFLHI 0x1086 /* Boardflags Hi */
3627-#define SSB_SPROM8_IL0MAC 0x108C /* 6 byte MAC address */
3628-#define SSB_SPROM8_CCODE 0x1092 /* 2 byte country code */
3629-#define SSB_SPROM8_ANTAVAIL 0x109C /* Antenna available bitfields*/
3630-#define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */
3631-#define SSB_SPROM8_ANTAVAIL_A_SHIFT 8
3632-#define SSB_SPROM8_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */
3633-#define SSB_SPROM8_ANTAVAIL_BG_SHIFT 0
3634-#define SSB_SPROM8_AGAIN01 0x109E /* Antenna Gain (in dBm Q5.2) */
3635+#define SSB_SPROM8_BOARDREV 0x0082 /* Board revision */
3636+#define SSB_SPROM8_BFLLO 0x0084 /* Board flags (bits 0-15) */
3637+#define SSB_SPROM8_BFLHI 0x0086 /* Board flags (bits 16-31) */
3638+#define SSB_SPROM8_BFL2LO 0x0088 /* Board flags (bits 32-47) */
3639+#define SSB_SPROM8_BFL2HI 0x008A /* Board flags (bits 48-63) */
3640+#define SSB_SPROM8_IL0MAC 0x008C /* 6 byte MAC address */
3641+#define SSB_SPROM8_CCODE 0x0092 /* 2 byte country code */
3642+#define SSB_SPROM8_GPIOA 0x0096 /*Gen. Purpose IO # 0 and 1 */
3643+#define SSB_SPROM8_GPIOA_P0 0x00FF /* Pin 0 */
3644+#define SSB_SPROM8_GPIOA_P1 0xFF00 /* Pin 1 */
3645+#define SSB_SPROM8_GPIOA_P1_SHIFT 8
3646+#define SSB_SPROM8_GPIOB 0x0098 /* Gen. Purpose IO # 2 and 3 */
3647+#define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */
3648+#define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */
3649+#define SSB_SPROM8_GPIOB_P3_SHIFT 8
3650+#define SSB_SPROM8_ANTAVAIL 0x009C /* Antenna available bitfields*/
3651+#define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */
3652+#define SSB_SPROM8_ANTAVAIL_A_SHIFT 8
3653+#define SSB_SPROM8_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */
3654+#define SSB_SPROM8_ANTAVAIL_BG_SHIFT 0
3655+#define SSB_SPROM8_AGAIN01 0x009E /* Antenna Gain (in dBm Q5.2) */
3656 #define SSB_SPROM8_AGAIN0 0x00FF /* Antenna 0 */
3657 #define SSB_SPROM8_AGAIN0_SHIFT 0
3658 #define SSB_SPROM8_AGAIN1 0xFF00 /* Antenna 1 */
3659 #define SSB_SPROM8_AGAIN1_SHIFT 8
3660-#define SSB_SPROM8_AGAIN23 0x10A0
3661+#define SSB_SPROM8_AGAIN23 0x00A0
3662 #define SSB_SPROM8_AGAIN2 0x00FF /* Antenna 2 */
3663 #define SSB_SPROM8_AGAIN2_SHIFT 0
3664 #define SSB_SPROM8_AGAIN3 0xFF00 /* Antenna 3 */
3665 #define SSB_SPROM8_AGAIN3_SHIFT 8
3666-#define SSB_SPROM8_GPIOA 0x1096 /*Gen. Purpose IO # 0 and 1 */
3667-#define SSB_SPROM8_GPIOA_P0 0x00FF /* Pin 0 */
3668-#define SSB_SPROM8_GPIOA_P1 0xFF00 /* Pin 1 */
3669-#define SSB_SPROM8_GPIOA_P1_SHIFT 8
3670-#define SSB_SPROM8_GPIOB 0x1098 /* Gen. Purpose IO # 2 and 3 */
3671-#define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */
3672-#define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */
3673-#define SSB_SPROM8_GPIOB_P3_SHIFT 8
3674-#define SSB_SPROM8_MAXP_BG 0x10C0 /* Max Power BG in path 1 */
3675-#define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */
3676+#define SSB_SPROM8_RSSIPARM2G 0x00A4 /* RSSI params for 2GHz */
3677+#define SSB_SPROM8_RSSISMF2G 0x000F
3678+#define SSB_SPROM8_RSSISMC2G 0x00F0
3679+#define SSB_SPROM8_RSSISMC2G_SHIFT 4
3680+#define SSB_SPROM8_RSSISAV2G 0x0700
3681+#define SSB_SPROM8_RSSISAV2G_SHIFT 8
3682+#define SSB_SPROM8_BXA2G 0x1800
3683+#define SSB_SPROM8_BXA2G_SHIFT 11
3684+#define SSB_SPROM8_RSSIPARM5G 0x00A6 /* RSSI params for 5GHz */
3685+#define SSB_SPROM8_RSSISMF5G 0x000F
3686+#define SSB_SPROM8_RSSISMC5G 0x00F0
3687+#define SSB_SPROM8_RSSISMC5G_SHIFT 4
3688+#define SSB_SPROM8_RSSISAV5G 0x0700
3689+#define SSB_SPROM8_RSSISAV5G_SHIFT 8
3690+#define SSB_SPROM8_BXA5G 0x1800
3691+#define SSB_SPROM8_BXA5G_SHIFT 11
3692+#define SSB_SPROM8_TRI25G 0x00A8 /* TX isolation 2.4&5.3GHz */
3693+#define SSB_SPROM8_TRI2G 0x00FF /* TX isolation 2.4GHz */
3694+#define SSB_SPROM8_TRI5G 0xFF00 /* TX isolation 5.3GHz */
3695+#define SSB_SPROM8_TRI5G_SHIFT 8
3696+#define SSB_SPROM8_TRI5GHL 0x00AA /* TX isolation 5.2/5.8GHz */
3697+#define SSB_SPROM8_TRI5GL 0x00FF /* TX isolation 5.2GHz */
3698+#define SSB_SPROM8_TRI5GH 0xFF00 /* TX isolation 5.8GHz */
3699+#define SSB_SPROM8_TRI5GH_SHIFT 8
3700+#define SSB_SPROM8_RXPO 0x00AC /* RX power offsets */
3701+#define SSB_SPROM8_RXPO2G 0x00FF /* 2GHz RX power offset */
3702+#define SSB_SPROM8_RXPO5G 0xFF00 /* 5GHz RX power offset */
3703+#define SSB_SPROM8_RXPO5G_SHIFT 8
3704+#define SSB_SPROM8_MAXP_BG 0x00C0 /* Max Power 2GHz in path 1 */
3705+#define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power 2GHz */
3706 #define SSB_SPROM8_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */
3707 #define SSB_SPROM8_ITSSI_BG_SHIFT 8
3708-#define SSB_SPROM8_MAXP_A 0x10C8 /* Max Power A in path 1 */
3709-#define SSB_SPROM8_MAXP_A_MASK 0x00FF /* Mask for Max Power A */
3710+#define SSB_SPROM8_PA0B0 0x00C2 /* 2GHz power amp settings */
3711+#define SSB_SPROM8_PA0B1 0x00C4
3712+#define SSB_SPROM8_PA0B2 0x00C6
3713+#define SSB_SPROM8_MAXP_A 0x00C8 /* Max Power 5.3GHz */
3714+#define SSB_SPROM8_MAXP_A_MASK 0x00FF /* Mask for Max Power 5.3GHz */
3715 #define SSB_SPROM8_ITSSI_A 0xFF00 /* Mask for path 1 itssi_a */
3716 #define SSB_SPROM8_ITSSI_A_SHIFT 8
3717+#define SSB_SPROM8_MAXP_AHL 0x00CA /* Max Power 5.2/5.8GHz */
3718+#define SSB_SPROM8_MAXP_AH_MASK 0x00FF /* Mask for Max Power 5.8GHz */
3719+#define SSB_SPROM8_MAXP_AL_MASK 0xFF00 /* Mask for Max Power 5.2GHz */
3720+#define SSB_SPROM8_MAXP_AL_SHIFT 8
3721+#define SSB_SPROM8_PA1B0 0x00CC /* 5.3GHz power amp settings */
3722+#define SSB_SPROM8_PA1B1 0x00CE
3723+#define SSB_SPROM8_PA1B2 0x00D0
3724+#define SSB_SPROM8_PA1LOB0 0x00D2 /* 5.2GHz power amp settings */
3725+#define SSB_SPROM8_PA1LOB1 0x00D4
3726+#define SSB_SPROM8_PA1LOB2 0x00D6
3727+#define SSB_SPROM8_PA1HIB0 0x00D8 /* 5.8GHz power amp settings */
3728+#define SSB_SPROM8_PA1HIB1 0x00DA
3729+#define SSB_SPROM8_PA1HIB2 0x00DC
3730+#define SSB_SPROM8_CCK2GPO 0x0140 /* CCK power offset */
3731+#define SSB_SPROM8_OFDM2GPO 0x0142 /* 2.4GHz OFDM power offset */
3732+#define SSB_SPROM8_OFDM5GPO 0x0146 /* 5.3GHz OFDM power offset */
3733+#define SSB_SPROM8_OFDM5GLPO 0x014A /* 5.2GHz OFDM power offset */
3734+#define SSB_SPROM8_OFDM5GHPO 0x014E /* 5.8GHz OFDM power offset */
3735 
3736 /* Values for SSB_SPROM1_BINF_CCODE */
3737 enum {
3738

Archive Download this file



interactive