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

Archive Download this file



interactive