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

Archive Download this file



interactive