Root/target/linux/generic-2.6/patches-2.6.30/941-ssb_update.patch

1--- a/drivers/ssb/driver_chipcommon_pmu.c
2+++ b/drivers/ssb/driver_chipcommon_pmu.c
3@@ -28,6 +28,21 @@ static void ssb_chipco_pll_write(struct
4     chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value);
5 }
6 
7+static void ssb_chipco_regctl_maskset(struct ssb_chipcommon *cc,
8+ u32 offset, u32 mask, u32 set)
9+{
10+ u32 value;
11+
12+ chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
13+ chipco_write32(cc, SSB_CHIPCO_REGCTL_ADDR, offset);
14+ chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
15+ value = chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
16+ value &= mask;
17+ value |= set;
18+ chipco_write32(cc, SSB_CHIPCO_REGCTL_DATA, value);
19+ chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
20+}
21+
22 struct pmu0_plltab_entry {
23     u16 freq; /* Crystal frequency in kHz.*/
24     u8 xf; /* Crystal frequency value for PMU control */
25@@ -317,6 +332,12 @@ static void ssb_pmu_pll_init(struct ssb_
26     case 0x5354:
27         ssb_pmu0_pllinit_r0(cc, crystalfreq);
28         break;
29+ case 0x4322:
30+ if (cc->pmu.rev == 2) {
31+ chipco_write32(cc, SSB_CHIPCO_PLLCTL_ADDR, 0x0000000A);
32+ chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0);
33+ }
34+ break;
35     default:
36         ssb_printk(KERN_ERR PFX
37                "ERROR: PLL init unknown for device %04X\n",
38@@ -402,6 +423,7 @@ static void ssb_pmu_resources_init(struc
39 
40     switch (bus->chip_id) {
41     case 0x4312:
42+ case 0x4322:
43         /* We keep the default settings:
44          * min_msk = 0xCBB
45          * max_msk = 0x7FFFF
46@@ -506,3 +528,82 @@ void ssb_pmu_init(struct ssb_chipcommon
47     ssb_pmu_pll_init(cc);
48     ssb_pmu_resources_init(cc);
49 }
50+
51+void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
52+ enum ssb_pmu_ldo_volt_id id, u32 voltage)
53+{
54+ struct ssb_bus *bus = cc->dev->bus;
55+ u32 addr, shift, mask;
56+
57+ switch (bus->chip_id) {
58+ case 0x4328:
59+ case 0x5354:
60+ switch (id) {
61+ case LDO_VOLT1:
62+ addr = 2;
63+ shift = 25;
64+ mask = 0xF;
65+ break;
66+ case LDO_VOLT2:
67+ addr = 3;
68+ shift = 1;
69+ mask = 0xF;
70+ break;
71+ case LDO_VOLT3:
72+ addr = 3;
73+ shift = 9;
74+ mask = 0xF;
75+ break;
76+ case LDO_PAREF:
77+ addr = 3;
78+ shift = 17;
79+ mask = 0x3F;
80+ break;
81+ default:
82+ SSB_WARN_ON(1);
83+ return;
84+ }
85+ break;
86+ case 0x4312:
87+ if (SSB_WARN_ON(id != LDO_PAREF))
88+ return;
89+ addr = 0;
90+ shift = 21;
91+ mask = 0x3F;
92+ break;
93+ default:
94+ return;
95+ }
96+
97+ ssb_chipco_regctl_maskset(cc, addr, ~(mask << shift),
98+ (voltage & mask) << shift);
99+}
100+
101+void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
102+{
103+ struct ssb_bus *bus = cc->dev->bus;
104+ int ldo;
105+
106+ switch (bus->chip_id) {
107+ case 0x4312:
108+ ldo = SSB_PMURES_4312_PA_REF_LDO;
109+ break;
110+ case 0x4328:
111+ ldo = SSB_PMURES_4328_PA_REF_LDO;
112+ break;
113+ case 0x5354:
114+ ldo = SSB_PMURES_5354_PA_REF_LDO;
115+ break;
116+ default:
117+ return;
118+ }
119+
120+ if (on)
121+ chipco_set32(cc, SSB_CHIPCO_PMU_MINRES_MSK, 1 << ldo);
122+ else
123+ chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK, ~(1 << ldo));
124+ chipco_read32(cc, SSB_CHIPCO_PMU_MINRES_MSK); //SPEC FIXME found via mmiotrace - dummy read?
125+}
126+
127+EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
128+EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
129--- a/drivers/ssb/main.c
130+++ b/drivers/ssb/main.c
131@@ -120,6 +120,19 @@ static void ssb_device_put(struct ssb_de
132         put_device(dev->dev);
133 }
134 
135+static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv)
136+{
137+ if (drv)
138+ get_driver(&drv->drv);
139+ return drv;
140+}
141+
142+static inline void ssb_driver_put(struct ssb_driver *drv)
143+{
144+ if (drv)
145+ put_driver(&drv->drv);
146+}
147+
148 static int ssb_device_resume(struct device *dev)
149 {
150     struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
151@@ -190,90 +203,81 @@ int ssb_bus_suspend(struct ssb_bus *bus)
152 EXPORT_SYMBOL(ssb_bus_suspend);
153 
154 #ifdef CONFIG_SSB_SPROM
155-int ssb_devices_freeze(struct ssb_bus *bus)
156+/** ssb_devices_freeze - Freeze all devices on the bus.
157+ *
158+ * After freezing no device driver will be handling a device
159+ * on this bus anymore. ssb_devices_thaw() must be called after
160+ * a successful freeze to reactivate the devices.
161+ *
162+ * @bus: The bus.
163+ * @ctx: Context structure. Pass this to ssb_devices_thaw().
164+ */
165+int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx)
166 {
167- struct ssb_device *dev;
168- struct ssb_driver *drv;
169- int err = 0;
170- int i;
171- pm_message_t state = PMSG_FREEZE;
172+ struct ssb_device *sdev;
173+ struct ssb_driver *sdrv;
174+ unsigned int i;
175+
176+ memset(ctx, 0, sizeof(*ctx));
177+ ctx->bus = bus;
178+ SSB_WARN_ON(bus->nr_devices > ARRAY_SIZE(ctx->device_frozen));
179 
180- /* First check that we are capable to freeze all devices. */
181     for (i = 0; i < bus->nr_devices; i++) {
182- dev = &(bus->devices[i]);
183- if (!dev->dev ||
184- !dev->dev->driver ||
185- !device_is_registered(dev->dev))
186- continue;
187- drv = drv_to_ssb_drv(dev->dev->driver);
188- if (!drv)
189+ sdev = ssb_device_get(&bus->devices[i]);
190+
191+ if (!sdev->dev || !sdev->dev->driver ||
192+ !device_is_registered(sdev->dev)) {
193+ ssb_device_put(sdev);
194             continue;
195- if (!drv->suspend) {
196- /* Nope, can't suspend this one. */
197- return -EOPNOTSUPP;
198         }
199- }
200- /* Now suspend all devices */
201- for (i = 0; i < bus->nr_devices; i++) {
202- dev = &(bus->devices[i]);
203- if (!dev->dev ||
204- !dev->dev->driver ||
205- !device_is_registered(dev->dev))
206- continue;
207- drv = drv_to_ssb_drv(dev->dev->driver);
208- if (!drv)
209+ sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver));
210+ if (!sdrv || SSB_WARN_ON(!sdrv->remove)) {
211+ ssb_device_put(sdev);
212             continue;
213- err = drv->suspend(dev, state);
214- if (err) {
215- ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n",
216- dev_name(dev->dev));
217- goto err_unwind;
218         }
219+ sdrv->remove(sdev);
220+ ctx->device_frozen[i] = 1;
221     }
222 
223     return 0;
224-err_unwind:
225- for (i--; i >= 0; i--) {
226- dev = &(bus->devices[i]);
227- if (!dev->dev ||
228- !dev->dev->driver ||
229- !device_is_registered(dev->dev))
230- continue;
231- drv = drv_to_ssb_drv(dev->dev->driver);
232- if (!drv)
233- continue;
234- if (drv->resume)
235- drv->resume(dev);
236- }
237- return err;
238 }
239 
240-int ssb_devices_thaw(struct ssb_bus *bus)
241+/** ssb_devices_thaw - Unfreeze all devices on the bus.
242+ *
243+ * This will re-attach the device drivers and re-init the devices.
244+ *
245+ * @ctx: The context structure from ssb_devices_freeze()
246+ */
247+int ssb_devices_thaw(struct ssb_freeze_context *ctx)
248 {
249- struct ssb_device *dev;
250- struct ssb_driver *drv;
251- int err;
252- int i;
253+ struct ssb_bus *bus = ctx->bus;
254+ struct ssb_device *sdev;
255+ struct ssb_driver *sdrv;
256+ unsigned int i;
257+ int err, result = 0;
258 
259     for (i = 0; i < bus->nr_devices; i++) {
260- dev = &(bus->devices[i]);
261- if (!dev->dev ||
262- !dev->dev->driver ||
263- !device_is_registered(dev->dev))
264+ if (!ctx->device_frozen[i])
265             continue;
266- drv = drv_to_ssb_drv(dev->dev->driver);
267- if (!drv)
268+ sdev = &bus->devices[i];
269+
270+ if (SSB_WARN_ON(!sdev->dev || !sdev->dev->driver))
271             continue;
272- if (SSB_WARN_ON(!drv->resume))
273+ sdrv = drv_to_ssb_drv(sdev->dev->driver);
274+ if (SSB_WARN_ON(!sdrv || !sdrv->probe))
275             continue;
276- err = drv->resume(dev);
277+
278+ err = sdrv->probe(sdev, &sdev->id);
279         if (err) {
280             ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n",
281- dev_name(dev->dev));
282+ dev_name(sdev->dev));
283+ result = err;
284         }
285+ ssb_driver_put(sdrv);
286+ ssb_device_put(sdev);
287     }
288 
289- return 0;
290+ return result;
291 }
292 #endif /* CONFIG_SSB_SPROM */
293 
294@@ -472,6 +476,8 @@ static int ssb_devices_register(struct s
295         case SSB_BUSTYPE_SSB:
296             dev->dma_mask = &dev->coherent_dma_mask;
297             break;
298+ default:
299+ break;
300         }
301 
302         sdev->dev = dev;
303@@ -1358,8 +1364,10 @@ static int __init ssb_modinit(void)
304     ssb_buses_lock();
305     err = ssb_attach_queued_buses();
306     ssb_buses_unlock();
307- if (err)
308+ if (err) {
309         bus_unregister(&ssb_bustype);
310+ goto out;
311+ }
312 
313     err = b43_pci_ssb_bridge_init();
314     if (err) {
315@@ -1375,7 +1383,7 @@ static int __init ssb_modinit(void)
316         /* don't fail SSB init because of this */
317         err = 0;
318     }
319-
320+out:
321     return err;
322 }
323 /* ssb must be initialized after PCI but before the ssb drivers.
324--- a/drivers/ssb/pci.c
325+++ b/drivers/ssb/pci.c
326@@ -167,10 +167,16 @@ err_pci:
327 }
328 
329 /* Get the word-offset for a SSB_SPROM_XXX define. */
330-#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16))
331+#define SPOFF(offset) ((offset) / sizeof(u16))
332 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
333-#define SPEX(_outvar, _offset, _mask, _shift) \
334+#define SPEX16(_outvar, _offset, _mask, _shift) \
335     out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
336+#define SPEX32(_outvar, _offset, _mask, _shift) \
337+ out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
338+ in[SPOFF(_offset)]) & (_mask)) >> (_shift))
339+#define SPEX(_outvar, _offset, _mask, _shift) \
340+ SPEX16(_outvar, _offset, _mask, _shift)
341+
342 
343 static inline u8 ssb_crc8(u8 crc, u8 data)
344 {
345@@ -247,7 +253,7 @@ static int sprom_do_read(struct ssb_bus
346     int i;
347 
348     for (i = 0; i < bus->sprom_size; i++)
349- sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
350+ sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2));
351 
352     return 0;
353 }
354@@ -278,7 +284,7 @@ static int sprom_do_write(struct ssb_bus
355             ssb_printk("75%%");
356         else if (i % 2)
357             ssb_printk(".");
358- writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
359+ writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
360         mmiowb();
361         msleep(20);
362     }
363@@ -474,12 +480,14 @@ static void sprom_extract_r8(struct ssb_
364 
365     /* extract the MAC address */
366     for (i = 0; i < 3; i++) {
367- v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
368+ v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
369         *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
370     }
371     SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
372     SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
373     SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
374+ SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
375+ SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
376     SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
377          SSB_SPROM8_ANTAVAIL_A_SHIFT);
378     SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
379@@ -490,12 +498,55 @@ static void sprom_extract_r8(struct ssb_
380     SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
381     SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
382          SSB_SPROM8_ITSSI_A_SHIFT);
383+ SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
384+ SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
385+ SSB_SPROM8_MAXP_AL_SHIFT);
386     SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
387     SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
388          SSB_SPROM8_GPIOA_P1_SHIFT);
389     SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
390     SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
391          SSB_SPROM8_GPIOB_P3_SHIFT);
392+ SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
393+ SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
394+ SSB_SPROM8_TRI5G_SHIFT);
395+ SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
396+ SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
397+ SSB_SPROM8_TRI5GH_SHIFT);
398+ SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0);
399+ SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
400+ SSB_SPROM8_RXPO5G_SHIFT);
401+ SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
402+ SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
403+ SSB_SPROM8_RSSISMC2G_SHIFT);
404+ SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
405+ SSB_SPROM8_RSSISAV2G_SHIFT);
406+ SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
407+ SSB_SPROM8_BXA2G_SHIFT);
408+ SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
409+ SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
410+ SSB_SPROM8_RSSISMC5G_SHIFT);
411+ SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
412+ SSB_SPROM8_RSSISAV5G_SHIFT);
413+ SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
414+ SSB_SPROM8_BXA5G_SHIFT);
415+ SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
416+ SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
417+ SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
418+ SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
419+ SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
420+ SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
421+ SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
422+ SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
423+ SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
424+ SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
425+ SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
426+ SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
427+ SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
428+ SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
429+ SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
430+ SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
431+ SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
432 
433     /* Extract the antenna gain values. */
434     SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
435@@ -549,6 +600,7 @@ static int sprom_extract(struct ssb_bus
436             ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
437                    " revision %d detected. Will extract"
438                    " v1\n", out->revision);
439+ out->revision = 1;
440             sprom_extract_r123(out, in);
441         }
442     }
443@@ -568,6 +620,14 @@ static int ssb_pci_sprom_get(struct ssb_
444     int err = -ENOMEM;
445     u16 *buf;
446 
447+ if (!ssb_is_sprom_available(bus)) {
448+ ssb_printk(KERN_ERR PFX "No SPROM available!\n");
449+ return -ENODEV;
450+ }
451+
452+ bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ?
453+ SSB_SPROM_BASE1 : SSB_SPROM_BASE31;
454+
455     buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
456     if (!buf)
457         goto out;
458--- a/drivers/ssb/pcmcia.c
459+++ b/drivers/ssb/pcmcia.c
460@@ -583,7 +583,7 @@ static int ssb_pcmcia_sprom_write_all(st
461             ssb_printk(".");
462         err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
463         if (err) {
464- ssb_printk("\n" KERN_NOTICE PFX
465+ ssb_printk(KERN_NOTICE PFX
466                    "Failed to write to SPROM.\n");
467             failed = 1;
468             break;
469@@ -591,7 +591,7 @@ static int ssb_pcmcia_sprom_write_all(st
470     }
471     err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
472     if (err) {
473- ssb_printk("\n" KERN_NOTICE PFX
474+ ssb_printk(KERN_NOTICE PFX
475                "Could not disable SPROM write access.\n");
476         failed = 1;
477     }
478@@ -617,134 +617,140 @@ static int ssb_pcmcia_sprom_check_crc(co
479     } \
480   } while (0)
481 
482-int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
483- struct ssb_init_invariants *iv)
484+static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
485+ tuple_t *tuple,
486+ void *priv)
487 {
488- tuple_t tuple;
489- int res;
490- unsigned char buf[32];
491+ struct ssb_sprom *sprom = priv;
492+
493+ if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
494+ return -EINVAL;
495+ if (tuple->TupleDataLen != ETH_ALEN + 2)
496+ return -EINVAL;
497+ if (tuple->TupleData[1] != ETH_ALEN)
498+ return -EINVAL;
499+ memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
500+ return 0;
501+};
502+
503+static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
504+ tuple_t *tuple,
505+ void *priv)
506+{
507+ struct ssb_init_invariants *iv = priv;
508     struct ssb_sprom *sprom = &iv->sprom;
509     struct ssb_boardinfo *bi = &iv->boardinfo;
510     const char *error_description;
511 
512+ GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
513+ switch (tuple->TupleData[0]) {
514+ case SSB_PCMCIA_CIS_ID:
515+ GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
516+ (tuple->TupleDataLen != 7),
517+ "id tpl size");
518+ bi->vendor = tuple->TupleData[1] |
519+ ((u16)tuple->TupleData[2] << 8);
520+ break;
521+ case SSB_PCMCIA_CIS_BOARDREV:
522+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
523+ "boardrev tpl size");
524+ sprom->board_rev = tuple->TupleData[1];
525+ break;
526+ case SSB_PCMCIA_CIS_PA:
527+ GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
528+ (tuple->TupleDataLen != 10),
529+ "pa tpl size");
530+ sprom->pa0b0 = tuple->TupleData[1] |
531+ ((u16)tuple->TupleData[2] << 8);
532+ sprom->pa0b1 = tuple->TupleData[3] |
533+ ((u16)tuple->TupleData[4] << 8);
534+ sprom->pa0b2 = tuple->TupleData[5] |
535+ ((u16)tuple->TupleData[6] << 8);
536+ sprom->itssi_a = tuple->TupleData[7];
537+ sprom->itssi_bg = tuple->TupleData[7];
538+ sprom->maxpwr_a = tuple->TupleData[8];
539+ sprom->maxpwr_bg = tuple->TupleData[8];
540+ break;
541+ case SSB_PCMCIA_CIS_OEMNAME:
542+ /* We ignore this. */
543+ break;
544+ case SSB_PCMCIA_CIS_CCODE:
545+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
546+ "ccode tpl size");
547+ sprom->country_code = tuple->TupleData[1];
548+ break;
549+ case SSB_PCMCIA_CIS_ANTENNA:
550+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
551+ "ant tpl size");
552+ sprom->ant_available_a = tuple->TupleData[1];
553+ sprom->ant_available_bg = tuple->TupleData[1];
554+ break;
555+ case SSB_PCMCIA_CIS_ANTGAIN:
556+ GOTO_ERROR_ON(tuple->TupleDataLen != 2,
557+ "antg tpl size");
558+ sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
559+ sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
560+ sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
561+ sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
562+ sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
563+ sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
564+ sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
565+ sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
566+ break;
567+ case SSB_PCMCIA_CIS_BFLAGS:
568+ GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
569+ (tuple->TupleDataLen != 5),
570+ "bfl tpl size");
571+ sprom->boardflags_lo = tuple->TupleData[1] |
572+ ((u16)tuple->TupleData[2] << 8);
573+ break;
574+ case SSB_PCMCIA_CIS_LEDS:
575+ GOTO_ERROR_ON(tuple->TupleDataLen != 5,
576+ "leds tpl size");
577+ sprom->gpio0 = tuple->TupleData[1];
578+ sprom->gpio1 = tuple->TupleData[2];
579+ sprom->gpio2 = tuple->TupleData[3];
580+ sprom->gpio3 = tuple->TupleData[4];
581+ break;
582+ }
583+ return -ENOSPC; /* continue with next entry */
584+
585+error:
586+ ssb_printk(KERN_ERR PFX
587+ "PCMCIA: Failed to fetch device invariants: %s\n",
588+ error_description);
589+ return -ENODEV;
590+}
591+
592+
593+int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
594+ struct ssb_init_invariants *iv)
595+{
596+ struct ssb_sprom *sprom = &iv->sprom;
597+ int res;
598+
599     memset(sprom, 0xFF, sizeof(*sprom));
600     sprom->revision = 1;
601     sprom->boardflags_lo = 0;
602     sprom->boardflags_hi = 0;
603 
604     /* First fetch the MAC address. */
605- memset(&tuple, 0, sizeof(tuple));
606- tuple.DesiredTuple = CISTPL_FUNCE;
607- tuple.TupleData = buf;
608- tuple.TupleDataMax = sizeof(buf);
609- res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
610- GOTO_ERROR_ON(res != 0, "MAC first tpl");
611- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
612- GOTO_ERROR_ON(res != 0, "MAC first tpl data");
613- while (1) {
614- GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
615- if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
616- break;
617- res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
618- GOTO_ERROR_ON(res != 0, "MAC next tpl");
619- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
620- GOTO_ERROR_ON(res != 0, "MAC next tpl data");
621+ res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
622+ ssb_pcmcia_get_mac, sprom);
623+ if (res != 0) {
624+ ssb_printk(KERN_ERR PFX
625+ "PCMCIA: Failed to fetch MAC address\n");
626+ return -ENODEV;
627     }
628- GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
629- memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
630 
631     /* Fetch the vendor specific tuples. */
632- memset(&tuple, 0, sizeof(tuple));
633- tuple.DesiredTuple = SSB_PCMCIA_CIS;
634- tuple.TupleData = buf;
635- tuple.TupleDataMax = sizeof(buf);
636- res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
637- GOTO_ERROR_ON(res != 0, "VEN first tpl");
638- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
639- GOTO_ERROR_ON(res != 0, "VEN first tpl data");
640- while (1) {
641- GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
642- switch (tuple.TupleData[0]) {
643- case SSB_PCMCIA_CIS_ID:
644- GOTO_ERROR_ON((tuple.TupleDataLen != 5) &&
645- (tuple.TupleDataLen != 7),
646- "id tpl size");
647- bi->vendor = tuple.TupleData[1] |
648- ((u16)tuple.TupleData[2] << 8);
649- break;
650- case SSB_PCMCIA_CIS_BOARDREV:
651- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
652- "boardrev tpl size");
653- sprom->board_rev = tuple.TupleData[1];
654- break;
655- case SSB_PCMCIA_CIS_PA:
656- GOTO_ERROR_ON(tuple.TupleDataLen != 9,
657- "pa tpl size");
658- sprom->pa0b0 = tuple.TupleData[1] |
659- ((u16)tuple.TupleData[2] << 8);
660- sprom->pa0b1 = tuple.TupleData[3] |
661- ((u16)tuple.TupleData[4] << 8);
662- sprom->pa0b2 = tuple.TupleData[5] |
663- ((u16)tuple.TupleData[6] << 8);
664- sprom->itssi_a = tuple.TupleData[7];
665- sprom->itssi_bg = tuple.TupleData[7];
666- sprom->maxpwr_a = tuple.TupleData[8];
667- sprom->maxpwr_bg = tuple.TupleData[8];
668- break;
669- case SSB_PCMCIA_CIS_OEMNAME:
670- /* We ignore this. */
671- break;
672- case SSB_PCMCIA_CIS_CCODE:
673- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
674- "ccode tpl size");
675- sprom->country_code = tuple.TupleData[1];
676- break;
677- case SSB_PCMCIA_CIS_ANTENNA:
678- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
679- "ant tpl size");
680- sprom->ant_available_a = tuple.TupleData[1];
681- sprom->ant_available_bg = tuple.TupleData[1];
682- break;
683- case SSB_PCMCIA_CIS_ANTGAIN:
684- GOTO_ERROR_ON(tuple.TupleDataLen != 2,
685- "antg tpl size");
686- sprom->antenna_gain.ghz24.a0 = tuple.TupleData[1];
687- sprom->antenna_gain.ghz24.a1 = tuple.TupleData[1];
688- sprom->antenna_gain.ghz24.a2 = tuple.TupleData[1];
689- sprom->antenna_gain.ghz24.a3 = tuple.TupleData[1];
690- sprom->antenna_gain.ghz5.a0 = tuple.TupleData[1];
691- sprom->antenna_gain.ghz5.a1 = tuple.TupleData[1];
692- sprom->antenna_gain.ghz5.a2 = tuple.TupleData[1];
693- sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
694- break;
695- case SSB_PCMCIA_CIS_BFLAGS:
696- GOTO_ERROR_ON(tuple.TupleDataLen != 3,
697- "bfl tpl size");
698- sprom->boardflags_lo = tuple.TupleData[1] |
699- ((u16)tuple.TupleData[2] << 8);
700- break;
701- case SSB_PCMCIA_CIS_LEDS:
702- GOTO_ERROR_ON(tuple.TupleDataLen != 5,
703- "leds tpl size");
704- sprom->gpio0 = tuple.TupleData[1];
705- sprom->gpio1 = tuple.TupleData[2];
706- sprom->gpio2 = tuple.TupleData[3];
707- sprom->gpio3 = tuple.TupleData[4];
708- break;
709- }
710- res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
711- if (res == -ENOSPC)
712- break;
713- GOTO_ERROR_ON(res != 0, "VEN next tpl");
714- res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
715- GOTO_ERROR_ON(res != 0, "VEN next tpl data");
716- }
717+ res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
718+ ssb_pcmcia_do_get_invariants, sprom);
719+ if ((res == 0) || (res == -ENOSPC))
720+ return 0;
721 
722- return 0;
723-error:
724     ssb_printk(KERN_ERR PFX
725- "PCMCIA: Failed to fetch device invariants: %s\n",
726- error_description);
727+ "PCMCIA: Failed to fetch device invariants\n");
728     return -ENODEV;
729 }
730 
731--- a/include/linux/ssb/ssb.h
732+++ b/include/linux/ssb/ssb.h
733@@ -27,24 +27,54 @@ struct ssb_sprom {
734     u8 et1mdcport; /* MDIO for enet1 */
735     u8 board_rev; /* Board revision number from SPROM. */
736     u8 country_code; /* Country Code */
737- u8 ant_available_a; /* A-PHY antenna available bits (up to 4) */
738- u8 ant_available_bg; /* B/G-PHY antenna available bits (up to 4) */
739+ u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */
740+ u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */
741     u16 pa0b0;
742     u16 pa0b1;
743     u16 pa0b2;
744     u16 pa1b0;
745     u16 pa1b1;
746     u16 pa1b2;
747+ u16 pa1lob0;
748+ u16 pa1lob1;
749+ u16 pa1lob2;
750+ u16 pa1hib0;
751+ u16 pa1hib1;
752+ u16 pa1hib2;
753     u8 gpio0; /* GPIO pin 0 */
754     u8 gpio1; /* GPIO pin 1 */
755     u8 gpio2; /* GPIO pin 2 */
756     u8 gpio3; /* GPIO pin 3 */
757- u16 maxpwr_a; /* A-PHY Amplifier Max Power (in dBm Q5.2) */
758- u16 maxpwr_bg; /* B/G-PHY Amplifier Max Power (in dBm Q5.2) */
759+ u16 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
760+ u16 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
761+ u16 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
762+ u16 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
763     u8 itssi_a; /* Idle TSSI Target for A-PHY */
764     u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */
765- u16 boardflags_lo; /* Boardflags (low 16 bits) */
766- u16 boardflags_hi; /* Boardflags (high 16 bits) */
767+ u8 tri2g; /* 2.4GHz TX isolation */
768+ u8 tri5gl; /* 5.2GHz TX isolation */
769+ u8 tri5g; /* 5.3GHz TX isolation */
770+ u8 tri5gh; /* 5.8GHz TX isolation */
771+ u8 rxpo2g; /* 2GHz RX power offset */
772+ u8 rxpo5g; /* 5GHz RX power offset */
773+ u8 rssisav2g; /* 2GHz RSSI params */
774+ u8 rssismc2g;
775+ u8 rssismf2g;
776+ u8 bxa2g; /* 2GHz BX arch */
777+ u8 rssisav5g; /* 5GHz RSSI params */
778+ u8 rssismc5g;
779+ u8 rssismf5g;
780+ u8 bxa5g; /* 5GHz BX arch */
781+ u16 cck2gpo; /* CCK power offset */
782+ u32 ofdm2gpo; /* 2.4GHz OFDM power offset */
783+ u32 ofdm5glpo; /* 5.2GHz OFDM power offset */
784+ u32 ofdm5gpo; /* 5.3GHz OFDM power offset */
785+ u32 ofdm5ghpo; /* 5.8GHz OFDM power offset */
786+ u16 boardflags_lo; /* Board flags (bits 0-15) */
787+ u16 boardflags_hi; /* Board flags (bits 16-31) */
788+ u16 boardflags2_lo; /* Board flags (bits 32-47) */
789+ u16 boardflags2_hi; /* Board flags (bits 48-63) */
790+ /* TODO store board flags in a single u64 */
791 
792     /* Antenna gain values for up to 4 antennas
793      * on each band. Values in dBm/4 (Q5.2). Negative gain means the
794@@ -58,7 +88,7 @@ struct ssb_sprom {
795         } ghz5; /* 5GHz band */
796     } antenna_gain;
797 
798- /* TODO - add any parameters needed from rev 2, 3, or 4 SPROMs */
799+ /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
800 };
801 
802 /* Information about the PCB the circuitry is soldered on. */
803@@ -208,6 +238,7 @@ enum ssb_bustype {
804     SSB_BUSTYPE_SSB, /* This SSB bus is the system bus */
805     SSB_BUSTYPE_PCI, /* SSB is connected to PCI bus */
806     SSB_BUSTYPE_PCMCIA, /* SSB is connected to PCMCIA bus */
807+ SSB_BUSTYPE_SDIO, /* SSB is connected to SDIO bus */
808 };
809 
810 /* board_vendor */
811@@ -238,20 +269,33 @@ struct ssb_bus {
812 
813     const struct ssb_bus_ops *ops;
814 
815- /* The core in the basic address register window. (PCI bus only) */
816+ /* The core currently mapped into the MMIO window.
817+ * Not valid on all host-buses. So don't use outside of SSB. */
818     struct ssb_device *mapped_device;
819- /* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
820- u8 mapped_pcmcia_seg;
821+ union {
822+ /* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
823+ u8 mapped_pcmcia_seg;
824+ /* Current SSB base address window for SDIO. */
825+ u32 sdio_sbaddr;
826+ };
827     /* Lock for core and segment switching.
828      * On PCMCIA-host busses this is used to protect the whole MMIO access. */
829     spinlock_t bar_lock;
830 
831- /* The bus this backplane is running on. */
832+ /* The host-bus this backplane is running on. */
833     enum ssb_bustype bustype;
834- /* Pointer to the PCI bus (only valid if bustype == SSB_BUSTYPE_PCI). */
835- struct pci_dev *host_pci;
836- /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
837- struct pcmcia_device *host_pcmcia;
838+ /* Pointers to the host-bus. Check bustype before using any of these pointers. */
839+ union {
840+ /* Pointer to the PCI bus (only valid if bustype == SSB_BUSTYPE_PCI). */
841+ struct pci_dev *host_pci;
842+ /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
843+ struct pcmcia_device *host_pcmcia;
844+ /* Pointer to the SDIO device (only if bustype == SSB_BUSTYPE_SDIO). */
845+ struct sdio_func *host_sdio;
846+ };
847+
848+ /* See enum ssb_quirks */
849+ unsigned int quirks;
850 
851 #ifdef CONFIG_SSB_SPROM
852     /* Mutex to protect the SPROM writing. */
853@@ -261,6 +305,7 @@ struct ssb_bus {
854     /* ID information about the Chip. */
855     u16 chip_id;
856     u16 chip_rev;
857+ u16 sprom_offset;
858     u16 sprom_size; /* number of words in sprom */
859     u8 chip_package;
860 
861@@ -306,6 +351,11 @@ struct ssb_bus {
862 #endif /* DEBUG */
863 };
864 
865+enum ssb_quirks {
866+ /* SDIO connected card requires performing a read after writing a 32-bit value */
867+ SSB_QUIRK_SDIO_READ_AFTER_WRITE32 = (1 << 0),
868+};
869+
870 /* The initialization-invariants. */
871 struct ssb_init_invariants {
872     /* Versioning information about the PCB. */
873@@ -336,9 +386,18 @@ extern int ssb_bus_pcmciabus_register(st
874                       struct pcmcia_device *pcmcia_dev,
875                       unsigned long baseaddr);
876 #endif /* CONFIG_SSB_PCMCIAHOST */
877+#ifdef CONFIG_SSB_SDIOHOST
878+extern int ssb_bus_sdiobus_register(struct ssb_bus *bus,
879+ struct sdio_func *sdio_func,
880+ unsigned int quirks);
881+#endif /* CONFIG_SSB_SDIOHOST */
882+
883 
884 extern void ssb_bus_unregister(struct ssb_bus *bus);
885 
886+/* Does the device have an SPROM? */
887+extern bool ssb_is_sprom_available(struct ssb_bus *bus);
888+
889 /* Set a fallback SPROM.
890  * See kdoc at the function definition for complete documentation. */
891 extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
892--- a/include/linux/ssb/ssb_driver_chipcommon.h
893+++ b/include/linux/ssb/ssb_driver_chipcommon.h
894@@ -53,6 +53,7 @@
895 #define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */
896 #define SSB_CHIPCO_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */
897 #define SSB_CHIPCO_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */
898+#define SSB_CHIPCO_CAP_SPROM 0x40000000 /* SPROM present */
899 #define SSB_CHIPCO_CORECTL 0x0008
900 #define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
901 #define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
902@@ -385,6 +386,7 @@
903 
904 
905 /** Chip specific Chip-Status register contents. */
906+#define SSB_CHIPCO_CHST_4322_SPROM_EXISTS 0x00000040 /* SPROM present */
907 #define SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL 0x00000003
908 #define SSB_CHIPCO_CHST_4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
909 #define SSB_CHIPCO_CHST_4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
910@@ -398,6 +400,18 @@
911 #define SSB_CHIPCO_CHST_4325_RCAL_VALUE_SHIFT 4
912 #define SSB_CHIPCO_CHST_4325_PMUTOP_2B 0x00000200 /* 1 for 2b, 0 for to 2a */
913 
914+/** Macros to determine SPROM presence based on Chip-Status register. */
915+#define SSB_CHIPCO_CHST_4312_SPROM_PRESENT(status) \
916+ ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
917+ SSB_CHIPCO_CHST_4325_OTP_SEL)
918+#define SSB_CHIPCO_CHST_4322_SPROM_PRESENT(status) \
919+ (status & SSB_CHIPCO_CHST_4322_SPROM_EXISTS)
920+#define SSB_CHIPCO_CHST_4325_SPROM_PRESENT(status) \
921+ (((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
922+ SSB_CHIPCO_CHST_4325_DEFCIS_SEL) && \
923+ ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
924+ SSB_CHIPCO_CHST_4325_OTP_SEL))
925+
926 
927 
928 /** Clockcontrol masks and values **/
929@@ -564,6 +578,7 @@ struct ssb_chipcommon_pmu {
930 struct ssb_chipcommon {
931     struct ssb_device *dev;
932     u32 capabilities;
933+ u32 status;
934     /* Fast Powerup Delay constant */
935     u16 fast_pwrup_delay;
936     struct ssb_chipcommon_pmu pmu;
937@@ -629,5 +644,15 @@ extern int ssb_chipco_serial_init(struct
938 /* PMU support */
939 extern void ssb_pmu_init(struct ssb_chipcommon *cc);
940 
941+enum ssb_pmu_ldo_volt_id {
942+ LDO_PAREF = 0,
943+ LDO_VOLT1,
944+ LDO_VOLT2,
945+ LDO_VOLT3,
946+};
947+
948+void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
949+ enum ssb_pmu_ldo_volt_id id, u32 voltage);
950+void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
951 
952 #endif /* LINUX_SSB_CHIPCO_H_ */
953--- a/include/linux/ssb/ssb_regs.h
954+++ b/include/linux/ssb/ssb_regs.h
955@@ -162,7 +162,7 @@
956 
957 /* SPROM shadow area. If not otherwise noted, fields are
958  * two bytes wide. Note that the SPROM can _only_ be read
959- * in two-byte quantinies.
960+ * in two-byte quantities.
961  */
962 #define SSB_SPROMSIZE_WORDS 64
963 #define SSB_SPROMSIZE_BYTES (SSB_SPROMSIZE_WORDS * sizeof(u16))
964@@ -170,26 +170,27 @@
965 #define SSB_SPROMSIZE_WORDS_R4 220
966 #define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))
967 #define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16))
968-#define SSB_SPROM_BASE 0x1000
969-#define SSB_SPROM_REVISION 0x107E
970+#define SSB_SPROM_BASE1 0x1000
971+#define SSB_SPROM_BASE31 0x0800
972+#define SSB_SPROM_REVISION 0x007E
973 #define SSB_SPROM_REVISION_REV 0x00FF /* SPROM Revision number */
974 #define SSB_SPROM_REVISION_CRC 0xFF00 /* SPROM CRC8 value */
975 #define SSB_SPROM_REVISION_CRC_SHIFT 8
976 
977 /* SPROM Revision 1 */
978-#define SSB_SPROM1_SPID 0x1004 /* Subsystem Product ID for PCI */
979-#define SSB_SPROM1_SVID 0x1006 /* Subsystem Vendor ID for PCI */
980-#define SSB_SPROM1_PID 0x1008 /* Product ID for PCI */
981-#define SSB_SPROM1_IL0MAC 0x1048 /* 6 bytes MAC address for 802.11b/g */
982-#define SSB_SPROM1_ET0MAC 0x104E /* 6 bytes MAC address for Ethernet */
983-#define SSB_SPROM1_ET1MAC 0x1054 /* 6 bytes MAC address for 802.11a */
984-#define SSB_SPROM1_ETHPHY 0x105A /* Ethernet PHY settings */
985+#define SSB_SPROM1_SPID 0x0004 /* Subsystem Product ID for PCI */
986+#define SSB_SPROM1_SVID 0x0006 /* Subsystem Vendor ID for PCI */
987+#define SSB_SPROM1_PID 0x0008 /* Product ID for PCI */
988+#define SSB_SPROM1_IL0MAC 0x0048 /* 6 bytes MAC address for 802.11b/g */
989+#define SSB_SPROM1_ET0MAC 0x004E /* 6 bytes MAC address for Ethernet */
990+#define SSB_SPROM1_ET1MAC 0x0054 /* 6 bytes MAC address for 802.11a */
991+#define SSB_SPROM1_ETHPHY 0x005A /* Ethernet PHY settings */
992 #define SSB_SPROM1_ETHPHY_ET0A 0x001F /* MII Address for enet0 */
993 #define SSB_SPROM1_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */
994 #define SSB_SPROM1_ETHPHY_ET1A_SHIFT 5
995 #define SSB_SPROM1_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */
996 #define SSB_SPROM1_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */
997-#define SSB_SPROM1_BINF 0x105C /* Board info */
998+#define SSB_SPROM1_BINF 0x005C /* Board info */
999 #define SSB_SPROM1_BINF_BREV 0x00FF /* Board Revision */
1000 #define SSB_SPROM1_BINF_CCODE 0x0F00 /* Country Code */
1001 #define SSB_SPROM1_BINF_CCODE_SHIFT 8
1002@@ -197,63 +198,63 @@
1003 #define SSB_SPROM1_BINF_ANTBG_SHIFT 12
1004 #define SSB_SPROM1_BINF_ANTA 0xC000 /* Available A-PHY antennas */
1005 #define SSB_SPROM1_BINF_ANTA_SHIFT 14
1006-#define SSB_SPROM1_PA0B0 0x105E
1007-#define SSB_SPROM1_PA0B1 0x1060
1008-#define SSB_SPROM1_PA0B2 0x1062
1009-#define SSB_SPROM1_GPIOA 0x1064 /* General Purpose IO pins 0 and 1 */
1010+#define SSB_SPROM1_PA0B0 0x005E
1011+#define SSB_SPROM1_PA0B1 0x0060
1012+#define SSB_SPROM1_PA0B2 0x0062
1013+#define SSB_SPROM1_GPIOA 0x0064 /* General Purpose IO pins 0 and 1 */
1014 #define SSB_SPROM1_GPIOA_P0 0x00FF /* Pin 0 */
1015 #define SSB_SPROM1_GPIOA_P1 0xFF00 /* Pin 1 */
1016 #define SSB_SPROM1_GPIOA_P1_SHIFT 8
1017-#define SSB_SPROM1_GPIOB 0x1066 /* General Purpuse IO pins 2 and 3 */
1018+#define SSB_SPROM1_GPIOB 0x0066 /* General Purpuse IO pins 2 and 3 */
1019 #define SSB_SPROM1_GPIOB_P2 0x00FF /* Pin 2 */
1020 #define SSB_SPROM1_GPIOB_P3 0xFF00 /* Pin 3 */
1021 #define SSB_SPROM1_GPIOB_P3_SHIFT 8
1022-#define SSB_SPROM1_MAXPWR 0x1068 /* Power Amplifier Max Power */
1023+#define SSB_SPROM1_MAXPWR 0x0068 /* Power Amplifier Max Power */
1024 #define SSB_SPROM1_MAXPWR_BG 0x00FF /* B-PHY and G-PHY (in dBm Q5.2) */
1025 #define SSB_SPROM1_MAXPWR_A 0xFF00 /* A-PHY (in dBm Q5.2) */
1026 #define SSB_SPROM1_MAXPWR_A_SHIFT 8
1027-#define SSB_SPROM1_PA1B0 0x106A
1028-#define SSB_SPROM1_PA1B1 0x106C
1029-#define SSB_SPROM1_PA1B2 0x106E
1030-#define SSB_SPROM1_ITSSI 0x1070 /* Idle TSSI Target */
1031+#define SSB_SPROM1_PA1B0 0x006A
1032+#define SSB_SPROM1_PA1B1 0x006C
1033+#define SSB_SPROM1_PA1B2 0x006E
1034+#define SSB_SPROM1_ITSSI 0x0070 /* Idle TSSI Target */
1035 #define SSB_SPROM1_ITSSI_BG 0x00FF /* B-PHY and G-PHY*/
1036 #define SSB_SPROM1_ITSSI_A 0xFF00 /* A-PHY */
1037 #define SSB_SPROM1_ITSSI_A_SHIFT 8
1038-#define SSB_SPROM1_BFLLO 0x1072 /* Boardflags (low 16 bits) */
1039-#define SSB_SPROM1_AGAIN 0x1074 /* Antenna Gain (in dBm Q5.2) */
1040+#define SSB_SPROM1_BFLLO 0x0072 /* Boardflags (low 16 bits) */
1041+#define SSB_SPROM1_AGAIN 0x0074 /* Antenna Gain (in dBm Q5.2) */
1042 #define SSB_SPROM1_AGAIN_BG 0x00FF /* B-PHY and G-PHY */
1043 #define SSB_SPROM1_AGAIN_BG_SHIFT 0
1044 #define SSB_SPROM1_AGAIN_A 0xFF00 /* A-PHY */
1045 #define SSB_SPROM1_AGAIN_A_SHIFT 8
1046 
1047 /* SPROM Revision 2 (inherits from rev 1) */
1048-#define SSB_SPROM2_BFLHI 0x1038 /* Boardflags (high 16 bits) */
1049-#define SSB_SPROM2_MAXP_A 0x103A /* A-PHY Max Power */
1050+#define SSB_SPROM2_BFLHI 0x0038 /* Boardflags (high 16 bits) */
1051+#define SSB_SPROM2_MAXP_A 0x003A /* A-PHY Max Power */
1052 #define SSB_SPROM2_MAXP_A_HI 0x00FF /* Max Power High */
1053 #define SSB_SPROM2_MAXP_A_LO 0xFF00 /* Max Power Low */
1054 #define SSB_SPROM2_MAXP_A_LO_SHIFT 8
1055-#define SSB_SPROM2_PA1LOB0 0x103C /* A-PHY PowerAmplifier Low Settings */
1056-#define SSB_SPROM2_PA1LOB1 0x103E /* A-PHY PowerAmplifier Low Settings */
1057-#define SSB_SPROM2_PA1LOB2 0x1040 /* A-PHY PowerAmplifier Low Settings */
1058-#define SSB_SPROM2_PA1HIB0 0x1042 /* A-PHY PowerAmplifier High Settings */
1059-#define SSB_SPROM2_PA1HIB1 0x1044 /* A-PHY PowerAmplifier High Settings */
1060-#define SSB_SPROM2_PA1HIB2 0x1046 /* A-PHY PowerAmplifier High Settings */
1061-#define SSB_SPROM2_OPO 0x1078 /* OFDM Power Offset from CCK Level */
1062+#define SSB_SPROM2_PA1LOB0 0x003C /* A-PHY PowerAmplifier Low Settings */
1063+#define SSB_SPROM2_PA1LOB1 0x003E /* A-PHY PowerAmplifier Low Settings */
1064+#define SSB_SPROM2_PA1LOB2 0x0040 /* A-PHY PowerAmplifier Low Settings */
1065+#define SSB_SPROM2_PA1HIB0 0x0042 /* A-PHY PowerAmplifier High Settings */
1066+#define SSB_SPROM2_PA1HIB1 0x0044 /* A-PHY PowerAmplifier High Settings */
1067+#define SSB_SPROM2_PA1HIB2 0x0046 /* A-PHY PowerAmplifier High Settings */
1068+#define SSB_SPROM2_OPO 0x0078 /* OFDM Power Offset from CCK Level */
1069 #define SSB_SPROM2_OPO_VALUE 0x00FF
1070 #define SSB_SPROM2_OPO_UNUSED 0xFF00
1071-#define SSB_SPROM2_CCODE 0x107C /* Two char Country Code */
1072+#define SSB_SPROM2_CCODE 0x007C /* Two char Country Code */
1073 
1074 /* SPROM Revision 3 (inherits most data from rev 2) */
1075-#define SSB_SPROM3_IL0MAC 0x104A /* 6 bytes MAC address for 802.11b/g */
1076-#define SSB_SPROM3_OFDMAPO 0x102C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
1077-#define SSB_SPROM3_OFDMALPO 0x1030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
1078-#define SSB_SPROM3_OFDMAHPO 0x1034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
1079-#define SSB_SPROM3_GPIOLDC 0x1042 /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */
1080+#define SSB_SPROM3_OFDMAPO 0x002C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
1081+#define SSB_SPROM3_OFDMALPO 0x0030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
1082+#define SSB_SPROM3_OFDMAHPO 0x0034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
1083+#define SSB_SPROM3_GPIOLDC 0x0042 /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */
1084 #define SSB_SPROM3_GPIOLDC_OFF 0x0000FF00 /* Off Count */
1085 #define SSB_SPROM3_GPIOLDC_OFF_SHIFT 8
1086 #define SSB_SPROM3_GPIOLDC_ON 0x00FF0000 /* On Count */
1087 #define SSB_SPROM3_GPIOLDC_ON_SHIFT 16
1088-#define SSB_SPROM3_CCKPO 0x1078 /* CCK Power Offset */
1089+#define SSB_SPROM3_IL0MAC 0x004A /* 6 bytes MAC address for 802.11b/g */
1090+#define SSB_SPROM3_CCKPO 0x0078 /* CCK Power Offset */
1091 #define SSB_SPROM3_CCKPO_1M 0x000F /* 1M Rate PO */
1092 #define SSB_SPROM3_CCKPO_2M 0x00F0 /* 2M Rate PO */
1093 #define SSB_SPROM3_CCKPO_2M_SHIFT 4
1094@@ -264,104 +265,156 @@
1095 #define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
1096 
1097 /* SPROM Revision 4 */
1098-#define SSB_SPROM4_IL0MAC 0x104C /* 6 byte MAC address for a/b/g/n */
1099-#define SSB_SPROM4_ETHPHY 0x105A /* Ethernet PHY settings ?? */
1100+#define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */
1101+#define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */
1102+#define SSB_SPROM4_IL0MAC 0x004C /* 6 byte MAC address for a/b/g/n */
1103+#define SSB_SPROM4_CCODE 0x0052 /* Country Code (2 bytes) */
1104+#define SSB_SPROM4_GPIOA 0x0056 /* Gen. Purpose IO # 0 and 1 */
1105+#define SSB_SPROM4_GPIOA_P0 0x00FF /* Pin 0 */
1106+#define SSB_SPROM4_GPIOA_P1 0xFF00 /* Pin 1 */
1107+#define SSB_SPROM4_GPIOA_P1_SHIFT 8
1108+#define SSB_SPROM4_GPIOB 0x0058 /* Gen. Purpose IO # 2 and 3 */
1109+#define SSB_SPROM4_GPIOB_P2 0x00FF /* Pin 2 */
1110+#define SSB_SPROM4_GPIOB_P3 0xFF00 /* Pin 3 */
1111+#define SSB_SPROM4_GPIOB_P3_SHIFT 8
1112+#define SSB_SPROM4_ETHPHY 0x005A /* Ethernet PHY settings ?? */
1113 #define SSB_SPROM4_ETHPHY_ET0A 0x001F /* MII Address for enet0 */
1114 #define SSB_SPROM4_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */
1115 #define SSB_SPROM4_ETHPHY_ET1A_SHIFT 5
1116 #define SSB_SPROM4_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */
1117 #define SSB_SPROM4_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */
1118-#define SSB_SPROM4_CCODE 0x1052 /* Country Code (2 bytes) */
1119-#define SSB_SPROM4_ANTAVAIL 0x105D /* Antenna available bitfields */
1120-#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */
1121-#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0
1122-#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */
1123-#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8
1124-#define SSB_SPROM4_BFLLO 0x1044 /* Boardflags (low 16 bits) */
1125-#define SSB_SPROM4_AGAIN01 0x105E /* Antenna Gain (in dBm Q5.2) */
1126+#define SSB_SPROM4_ANTAVAIL 0x005D /* Antenna available bitfields */
1127+#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */
1128+#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0
1129+#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */
1130+#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8
1131+#define SSB_SPROM4_AGAIN01 0x005E /* Antenna Gain (in dBm Q5.2) */
1132 #define SSB_SPROM4_AGAIN0 0x00FF /* Antenna 0 */
1133 #define SSB_SPROM4_AGAIN0_SHIFT 0
1134 #define SSB_SPROM4_AGAIN1 0xFF00 /* Antenna 1 */
1135 #define SSB_SPROM4_AGAIN1_SHIFT 8
1136-#define SSB_SPROM4_AGAIN23 0x1060
1137+#define SSB_SPROM4_AGAIN23 0x0060
1138 #define SSB_SPROM4_AGAIN2 0x00FF /* Antenna 2 */
1139 #define SSB_SPROM4_AGAIN2_SHIFT 0
1140 #define SSB_SPROM4_AGAIN3 0xFF00 /* Antenna 3 */
1141 #define SSB_SPROM4_AGAIN3_SHIFT 8
1142-#define SSB_SPROM4_BFLHI 0x1046 /* Board Flags Hi */
1143-#define SSB_SPROM4_MAXP_BG 0x1080 /* Max Power BG in path 1 */
1144+#define SSB_SPROM4_MAXP_BG 0x0080 /* Max Power BG in path 1 */
1145 #define SSB_SPROM4_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */
1146 #define SSB_SPROM4_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */
1147 #define SSB_SPROM4_ITSSI_BG_SHIFT 8
1148-#define SSB_SPROM4_MAXP_A 0x108A /* Max Power A in path 1 */
1149+#define SSB_SPROM4_MAXP_A 0x008A /* Max Power A in path 1 */
1150 #define SSB_SPROM4_MAXP_A_MASK 0x00FF /* Mask for Max Power A */
1151 #define SSB_SPROM4_ITSSI_A 0xFF00 /* Mask for path 1 itssi_a */
1152 #define SSB_SPROM4_ITSSI_A_SHIFT 8
1153-#define SSB_SPROM4_GPIOA 0x1056 /* Gen. Purpose IO # 0 and 1 */
1154-#define SSB_SPROM4_GPIOA_P0 0x00FF /* Pin 0 */
1155-#define SSB_SPROM4_GPIOA_P1 0xFF00 /* Pin 1 */
1156-#define SSB_SPROM4_GPIOA_P1_SHIFT 8
1157-#define SSB_SPROM4_GPIOB 0x1058 /* Gen. Purpose IO # 2 and 3 */
1158-#define SSB_SPROM4_GPIOB_P2 0x00FF /* Pin 2 */
1159-#define SSB_SPROM4_GPIOB_P3 0xFF00 /* Pin 3 */
1160-#define SSB_SPROM4_GPIOB_P3_SHIFT 8
1161-#define SSB_SPROM4_PA0B0 0x1082 /* The paXbY locations are */
1162-#define SSB_SPROM4_PA0B1 0x1084 /* only guesses */
1163-#define SSB_SPROM4_PA0B2 0x1086
1164-#define SSB_SPROM4_PA1B0 0x108E
1165-#define SSB_SPROM4_PA1B1 0x1090
1166-#define SSB_SPROM4_PA1B2 0x1092
1167+#define SSB_SPROM4_PA0B0 0x0082 /* The paXbY locations are */
1168+#define SSB_SPROM4_PA0B1 0x0084 /* only guesses */
1169+#define SSB_SPROM4_PA0B2 0x0086
1170+#define SSB_SPROM4_PA1B0 0x008E
1171+#define SSB_SPROM4_PA1B1 0x0090
1172+#define SSB_SPROM4_PA1B2 0x0092
1173 
1174 /* SPROM Revision 5 (inherits most data from rev 4) */
1175-#define SSB_SPROM5_BFLLO 0x104A /* Boardflags (low 16 bits) */
1176-#define SSB_SPROM5_BFLHI 0x104C /* Board Flags Hi */
1177-#define SSB_SPROM5_IL0MAC 0x1052 /* 6 byte MAC address for a/b/g/n */
1178-#define SSB_SPROM5_CCODE 0x1044 /* Country Code (2 bytes) */
1179-#define SSB_SPROM5_GPIOA 0x1076 /* Gen. Purpose IO # 0 and 1 */
1180+#define SSB_SPROM5_CCODE 0x0044 /* Country Code (2 bytes) */
1181+#define SSB_SPROM5_BFLLO 0x004A /* Boardflags (low 16 bits) */
1182+#define SSB_SPROM5_BFLHI 0x004C /* Board Flags Hi */
1183+#define SSB_SPROM5_IL0MAC 0x0052 /* 6 byte MAC address for a/b/g/n */
1184+#define SSB_SPROM5_GPIOA 0x0076 /* Gen. Purpose IO # 0 and 1 */
1185 #define SSB_SPROM5_GPIOA_P0 0x00FF /* Pin 0 */
1186 #define SSB_SPROM5_GPIOA_P1 0xFF00 /* Pin 1 */
1187 #define SSB_SPROM5_GPIOA_P1_SHIFT 8
1188-#define SSB_SPROM5_GPIOB 0x1078 /* Gen. Purpose IO # 2 and 3 */
1189+#define SSB_SPROM5_GPIOB 0x0078 /* Gen. Purpose IO # 2 and 3 */
1190 #define SSB_SPROM5_GPIOB_P2 0x00FF /* Pin 2 */
1191 #define SSB_SPROM5_GPIOB_P3 0xFF00 /* Pin 3 */
1192 #define SSB_SPROM5_GPIOB_P3_SHIFT 8
1193 
1194 /* SPROM Revision 8 */
1195-#define SSB_SPROM8_BFLLO 0x1084 /* Boardflags (low 16 bits) */
1196-#define SSB_SPROM8_BFLHI 0x1086 /* Boardflags Hi */
1197-#define SSB_SPROM8_IL0MAC 0x108C /* 6 byte MAC address */
1198-#define SSB_SPROM8_CCODE 0x1092 /* 2 byte country code */
1199-#define SSB_SPROM8_ANTAVAIL 0x109C /* Antenna available bitfields*/
1200-#define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */
1201-#define SSB_SPROM8_ANTAVAIL_A_SHIFT 8
1202-#define SSB_SPROM8_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */
1203-#define SSB_SPROM8_ANTAVAIL_BG_SHIFT 0
1204-#define SSB_SPROM8_AGAIN01 0x109E /* Antenna Gain (in dBm Q5.2) */
1205+#define SSB_SPROM8_BOARDREV 0x0082 /* Board revision */
1206+#define SSB_SPROM8_BFLLO 0x0084 /* Board flags (bits 0-15) */
1207+#define SSB_SPROM8_BFLHI 0x0086 /* Board flags (bits 16-31) */
1208+#define SSB_SPROM8_BFL2LO 0x0088 /* Board flags (bits 32-47) */
1209+#define SSB_SPROM8_BFL2HI 0x008A /* Board flags (bits 48-63) */
1210+#define SSB_SPROM8_IL0MAC 0x008C /* 6 byte MAC address */
1211+#define SSB_SPROM8_CCODE 0x0092 /* 2 byte country code */
1212+#define SSB_SPROM8_GPIOA 0x0096 /*Gen. Purpose IO # 0 and 1 */
1213+#define SSB_SPROM8_GPIOA_P0 0x00FF /* Pin 0 */
1214+#define SSB_SPROM8_GPIOA_P1 0xFF00 /* Pin 1 */
1215+#define SSB_SPROM8_GPIOA_P1_SHIFT 8
1216+#define SSB_SPROM8_GPIOB 0x0098 /* Gen. Purpose IO # 2 and 3 */
1217+#define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */
1218+#define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */
1219+#define SSB_SPROM8_GPIOB_P3_SHIFT 8
1220+#define SSB_SPROM8_ANTAVAIL 0x009C /* Antenna available bitfields*/
1221+#define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */
1222+#define SSB_SPROM8_ANTAVAIL_A_SHIFT 8
1223+#define SSB_SPROM8_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */
1224+#define SSB_SPROM8_ANTAVAIL_BG_SHIFT 0
1225+#define SSB_SPROM8_AGAIN01 0x009E /* Antenna Gain (in dBm Q5.2) */
1226 #define SSB_SPROM8_AGAIN0 0x00FF /* Antenna 0 */
1227 #define SSB_SPROM8_AGAIN0_SHIFT 0
1228 #define SSB_SPROM8_AGAIN1 0xFF00 /* Antenna 1 */
1229 #define SSB_SPROM8_AGAIN1_SHIFT 8
1230-#define SSB_SPROM8_AGAIN23 0x10A0
1231+#define SSB_SPROM8_AGAIN23 0x00A0
1232 #define SSB_SPROM8_AGAIN2 0x00FF /* Antenna 2 */
1233 #define SSB_SPROM8_AGAIN2_SHIFT 0
1234 #define SSB_SPROM8_AGAIN3 0xFF00 /* Antenna 3 */
1235 #define SSB_SPROM8_AGAIN3_SHIFT 8
1236-#define SSB_SPROM8_GPIOA 0x1096 /*Gen. Purpose IO # 0 and 1 */
1237-#define SSB_SPROM8_GPIOA_P0 0x00FF /* Pin 0 */
1238-#define SSB_SPROM8_GPIOA_P1 0xFF00 /* Pin 1 */
1239-#define SSB_SPROM8_GPIOA_P1_SHIFT 8
1240-#define SSB_SPROM8_GPIOB 0x1098 /* Gen. Purpose IO # 2 and 3 */
1241-#define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */
1242-#define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */
1243-#define SSB_SPROM8_GPIOB_P3_SHIFT 8
1244-#define SSB_SPROM8_MAXP_BG 0x10C0 /* Max Power BG in path 1 */
1245-#define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */
1246+#define SSB_SPROM8_RSSIPARM2G 0x00A4 /* RSSI params for 2GHz */
1247+#define SSB_SPROM8_RSSISMF2G 0x000F
1248+#define SSB_SPROM8_RSSISMC2G 0x00F0
1249+#define SSB_SPROM8_RSSISMC2G_SHIFT 4
1250+#define SSB_SPROM8_RSSISAV2G 0x0700
1251+#define SSB_SPROM8_RSSISAV2G_SHIFT 8
1252+#define SSB_SPROM8_BXA2G 0x1800
1253+#define SSB_SPROM8_BXA2G_SHIFT 11
1254+#define SSB_SPROM8_RSSIPARM5G 0x00A6 /* RSSI params for 5GHz */
1255+#define SSB_SPROM8_RSSISMF5G 0x000F
1256+#define SSB_SPROM8_RSSISMC5G 0x00F0
1257+#define SSB_SPROM8_RSSISMC5G_SHIFT 4
1258+#define SSB_SPROM8_RSSISAV5G 0x0700
1259+#define SSB_SPROM8_RSSISAV5G_SHIFT 8
1260+#define SSB_SPROM8_BXA5G 0x1800
1261+#define SSB_SPROM8_BXA5G_SHIFT 11
1262+#define SSB_SPROM8_TRI25G 0x00A8 /* TX isolation 2.4&5.3GHz */
1263+#define SSB_SPROM8_TRI2G 0x00FF /* TX isolation 2.4GHz */
1264+#define SSB_SPROM8_TRI5G 0xFF00 /* TX isolation 5.3GHz */
1265+#define SSB_SPROM8_TRI5G_SHIFT 8
1266+#define SSB_SPROM8_TRI5GHL 0x00AA /* TX isolation 5.2/5.8GHz */
1267+#define SSB_SPROM8_TRI5GL 0x00FF /* TX isolation 5.2GHz */
1268+#define SSB_SPROM8_TRI5GH 0xFF00 /* TX isolation 5.8GHz */
1269+#define SSB_SPROM8_TRI5GH_SHIFT 8
1270+#define SSB_SPROM8_RXPO 0x00AC /* RX power offsets */
1271+#define SSB_SPROM8_RXPO2G 0x00FF /* 2GHz RX power offset */
1272+#define SSB_SPROM8_RXPO5G 0xFF00 /* 5GHz RX power offset */
1273+#define SSB_SPROM8_RXPO5G_SHIFT 8
1274+#define SSB_SPROM8_MAXP_BG 0x00C0 /* Max Power 2GHz in path 1 */
1275+#define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power 2GHz */
1276 #define SSB_SPROM8_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */
1277 #define SSB_SPROM8_ITSSI_BG_SHIFT 8
1278-#define SSB_SPROM8_MAXP_A 0x10C8 /* Max Power A in path 1 */
1279-#define SSB_SPROM8_MAXP_A_MASK 0x00FF /* Mask for Max Power A */
1280+#define SSB_SPROM8_PA0B0 0x00C2 /* 2GHz power amp settings */
1281+#define SSB_SPROM8_PA0B1 0x00C4
1282+#define SSB_SPROM8_PA0B2 0x00C6
1283+#define SSB_SPROM8_MAXP_A 0x00C8 /* Max Power 5.3GHz */
1284+#define SSB_SPROM8_MAXP_A_MASK 0x00FF /* Mask for Max Power 5.3GHz */
1285 #define SSB_SPROM8_ITSSI_A 0xFF00 /* Mask for path 1 itssi_a */
1286 #define SSB_SPROM8_ITSSI_A_SHIFT 8
1287+#define SSB_SPROM8_MAXP_AHL 0x00CA /* Max Power 5.2/5.8GHz */
1288+#define SSB_SPROM8_MAXP_AH_MASK 0x00FF /* Mask for Max Power 5.8GHz */
1289+#define SSB_SPROM8_MAXP_AL_MASK 0xFF00 /* Mask for Max Power 5.2GHz */
1290+#define SSB_SPROM8_MAXP_AL_SHIFT 8
1291+#define SSB_SPROM8_PA1B0 0x00CC /* 5.3GHz power amp settings */
1292+#define SSB_SPROM8_PA1B1 0x00CE
1293+#define SSB_SPROM8_PA1B2 0x00D0
1294+#define SSB_SPROM8_PA1LOB0 0x00D2 /* 5.2GHz power amp settings */
1295+#define SSB_SPROM8_PA1LOB1 0x00D4
1296+#define SSB_SPROM8_PA1LOB2 0x00D6
1297+#define SSB_SPROM8_PA1HIB0 0x00D8 /* 5.8GHz power amp settings */
1298+#define SSB_SPROM8_PA1HIB1 0x00DA
1299+#define SSB_SPROM8_PA1HIB2 0x00DC
1300+#define SSB_SPROM8_CCK2GPO 0x0140 /* CCK power offset */
1301+#define SSB_SPROM8_OFDM2GPO 0x0142 /* 2.4GHz OFDM power offset */
1302+#define SSB_SPROM8_OFDM5GPO 0x0146 /* 5.3GHz OFDM power offset */
1303+#define SSB_SPROM8_OFDM5GLPO 0x014A /* 5.2GHz OFDM power offset */
1304+#define SSB_SPROM8_OFDM5GHPO 0x014E /* 5.8GHz OFDM power offset */
1305 
1306 /* Values for SSB_SPROM1_BINF_CCODE */
1307 enum {
1308--- a/drivers/ssb/scan.c
1309+++ b/drivers/ssb/scan.c
1310@@ -162,6 +162,8 @@ static u8 chipid_to_nrcores(u16 chipid)
1311 static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
1312                u16 offset)
1313 {
1314+ u32 lo, hi;
1315+
1316     switch (bus->bustype) {
1317     case SSB_BUSTYPE_SSB:
1318         offset += current_coreidx * SSB_CORE_SIZE;
1319@@ -174,6 +176,10 @@ static u32 scan_read32(struct ssb_bus *b
1320             offset -= 0x800;
1321         } else
1322             ssb_pcmcia_switch_segment(bus, 0);
1323+ lo = readw(bus->mmio + offset);
1324+ hi = readw(bus->mmio + offset + 2);
1325+ return lo | (hi << 16);
1326+ default:
1327         break;
1328     }
1329     return readl(bus->mmio + offset);
1330@@ -188,6 +194,8 @@ static int scan_switchcore(struct ssb_bu
1331         return ssb_pci_switch_coreidx(bus, coreidx);
1332     case SSB_BUSTYPE_PCMCIA:
1333         return ssb_pcmcia_switch_coreidx(bus, coreidx);
1334+ default:
1335+ break;
1336     }
1337     return 0;
1338 }
1339@@ -206,6 +214,8 @@ void ssb_iounmap(struct ssb_bus *bus)
1340         SSB_BUG_ON(1); /* Can't reach this code. */
1341 #endif
1342         break;
1343+ default:
1344+ break;
1345     }
1346     bus->mmio = NULL;
1347     bus->mapped_device = NULL;
1348@@ -230,6 +240,8 @@ static void __iomem *ssb_ioremap(struct
1349         SSB_BUG_ON(1); /* Can't reach this code. */
1350 #endif
1351         break;
1352+ default:
1353+ break;
1354     }
1355 
1356     return mmio;
1357@@ -339,7 +351,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
1358         dev->bus = bus;
1359         dev->ops = bus->ops;
1360 
1361- ssb_dprintk(KERN_INFO PFX
1362+ printk(KERN_DEBUG PFX
1363                 "Core %d found: %s "
1364                 "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
1365                 i, ssb_core_name(dev->id.coreid),
1366--- a/drivers/ssb/driver_chipcommon.c
1367+++ b/drivers/ssb/driver_chipcommon.c
1368@@ -233,6 +233,8 @@ void ssb_chipcommon_init(struct ssb_chip
1369 {
1370     if (!cc->dev)
1371         return; /* We don't have a ChipCommon */
1372+ if (cc->dev->id.revision >= 11)
1373+ cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
1374     ssb_pmu_init(cc);
1375     chipco_powercontrol_init(cc);
1376     ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
1377@@ -370,6 +372,7 @@ u32 ssb_chipco_gpio_control(struct ssb_c
1378 {
1379     return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
1380 }
1381+EXPORT_SYMBOL(ssb_chipco_gpio_control);
1382 
1383 u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
1384 {
1385--- a/drivers/ssb/driver_mipscore.c
1386+++ b/drivers/ssb/driver_mipscore.c
1387@@ -49,29 +49,54 @@ static const u32 ipsflag_irq_shift[] = {
1388 
1389 static inline u32 ssb_irqflag(struct ssb_device *dev)
1390 {
1391- return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
1392+ u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG);
1393+ if (tpsflag)
1394+ return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
1395+ else
1396+ /* not irq supported */
1397+ return 0x3f;
1398+}
1399+
1400+static struct ssb_device *find_device(struct ssb_device *rdev, int irqflag)
1401+{
1402+ struct ssb_bus *bus = rdev->bus;
1403+ int i;
1404+ for (i = 0; i < bus->nr_devices; i++) {
1405+ struct ssb_device *dev;
1406+ dev = &(bus->devices[i]);
1407+ if (ssb_irqflag(dev) == irqflag)
1408+ return dev;
1409+ }
1410+ return NULL;
1411 }
1412 
1413 /* Get the MIPS IRQ assignment for a specified device.
1414  * If unassigned, 0 is returned.
1415+ * If disabled, 5 is returned.
1416+ * If not supported, 6 is returned.
1417  */
1418 unsigned int ssb_mips_irq(struct ssb_device *dev)
1419 {
1420     struct ssb_bus *bus = dev->bus;
1421+ struct ssb_device *mdev = bus->mipscore.dev;
1422     u32 irqflag;
1423     u32 ipsflag;
1424     u32 tmp;
1425     unsigned int irq;
1426 
1427     irqflag = ssb_irqflag(dev);
1428+ if (irqflag == 0x3f)
1429+ return 6;
1430     ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG);
1431     for (irq = 1; irq <= 4; irq++) {
1432         tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]);
1433         if (tmp == irqflag)
1434             break;
1435     }
1436- if (irq == 5)
1437- irq = 0;
1438+ if (irq == 5) {
1439+ if ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC))
1440+ irq = 0;
1441+ }
1442 
1443     return irq;
1444 }
1445@@ -97,25 +122,56 @@ static void set_irq(struct ssb_device *d
1446     struct ssb_device *mdev = bus->mipscore.dev;
1447     u32 irqflag = ssb_irqflag(dev);
1448 
1449+ BUG_ON(oldirq == 6);
1450+
1451     dev->irq = irq + 2;
1452 
1453- ssb_dprintk(KERN_INFO PFX
1454- "set_irq: core 0x%04x, irq %d => %d\n",
1455- dev->id.coreid, oldirq, irq);
1456     /* clear the old irq */
1457     if (oldirq == 0)
1458         ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
1459- else
1460+ else if (oldirq != 5)
1461         clear_irq(bus, oldirq);
1462 
1463     /* assign the new one */
1464     if (irq == 0) {
1465         ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) | ssb_read32(mdev, SSB_INTVEC)));
1466     } else {
1467+ u32 ipsflag = ssb_read32(mdev, SSB_IPSFLAG);
1468+ if ((ipsflag & ipsflag_irq_mask[irq]) != ipsflag_irq_mask[irq]) {
1469+ u32 oldipsflag = (ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq];
1470+ struct ssb_device *olddev = find_device(dev, oldipsflag);
1471+ if (olddev)
1472+ set_irq(olddev, 0);
1473+ }
1474         irqflag <<= ipsflag_irq_shift[irq];
1475- irqflag |= (ssb_read32(mdev, SSB_IPSFLAG) & ~ipsflag_irq_mask[irq]);
1476+ irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]);
1477         ssb_write32(mdev, SSB_IPSFLAG, irqflag);
1478     }
1479+ ssb_dprintk(KERN_INFO PFX
1480+ "set_irq: core 0x%04x, irq %d => %d\n",
1481+ dev->id.coreid, oldirq+2, irq+2);
1482+}
1483+
1484+static void print_irq(struct ssb_device *dev, unsigned int irq)
1485+{
1486+ int i;
1487+ static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
1488+ ssb_dprintk(KERN_INFO PFX
1489+ "core 0x%04x, irq :", dev->id.coreid);
1490+ for (i = 0; i <= 6; i++) {
1491+ ssb_dprintk(" %s%s", irq_name[i], i==irq?"*":" ");
1492+ }
1493+ ssb_dprintk("\n");
1494+}
1495+
1496+static void dump_irq(struct ssb_bus *bus)
1497+{
1498+ int i;
1499+ for (i = 0; i < bus->nr_devices; i++) {
1500+ struct ssb_device *dev;
1501+ dev = &(bus->devices[i]);
1502+ print_irq(dev, ssb_mips_irq(dev));
1503+ }
1504 }
1505 
1506 static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
1507@@ -197,17 +253,23 @@ void ssb_mipscore_init(struct ssb_mipsco
1508 
1509     /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
1510     for (irq = 2, i = 0; i < bus->nr_devices; i++) {
1511+ int mips_irq;
1512         dev = &(bus->devices[i]);
1513- dev->irq = ssb_mips_irq(dev) + 2;
1514+ mips_irq = ssb_mips_irq(dev);
1515+ if (mips_irq > 4)
1516+ dev->irq = 0;
1517+ else
1518+ dev->irq = mips_irq + 2;
1519+ if (dev->irq > 5)
1520+ continue;
1521         switch (dev->id.coreid) {
1522         case SSB_DEV_USB11_HOST:
1523             /* shouldn't need a separate irq line for non-4710, most of them have a proper
1524              * external usb controller on the pci */
1525             if ((bus->chip_id == 0x4710) && (irq <= 4)) {
1526                 set_irq(dev, irq++);
1527- break;
1528             }
1529- /* fallthrough */
1530+ break;
1531         case SSB_DEV_PCI:
1532         case SSB_DEV_ETHERNET:
1533         case SSB_DEV_ETHERNET_GBIT:
1534@@ -218,8 +280,14 @@ void ssb_mipscore_init(struct ssb_mipsco
1535                 set_irq(dev, irq++);
1536                 break;
1537             }
1538+ /* fallthrough */
1539+ case SSB_DEV_EXTIF:
1540+ set_irq(dev, 0);
1541+ break;
1542         }
1543     }
1544+ ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n");
1545+ dump_irq(bus);
1546 
1547     ssb_mips_serial_init(mcore);
1548     ssb_mips_flash_detect(mcore);
1549--- a/drivers/ssb/sprom.c
1550+++ b/drivers/ssb/sprom.c
1551@@ -13,6 +13,9 @@
1552 
1553 #include "ssb_private.h"
1554 
1555+#include <linux/ctype.h>
1556+#include <linux/slab.h>
1557+
1558 
1559 static const struct ssb_sprom *fallback_sprom;
1560 
1561@@ -33,17 +36,27 @@ static int sprom2hex(const u16 *sprom, c
1562 static int hex2sprom(u16 *sprom, const char *dump, size_t len,
1563              size_t sprom_size_words)
1564 {
1565- char tmp[5] = { 0 };
1566- int cnt = 0;
1567+ char c, tmp[5] = { 0 };
1568+ int err, cnt = 0;
1569     unsigned long parsed;
1570 
1571- if (len < sprom_size_words * 2)
1572+ /* Strip whitespace at the end. */
1573+ while (len) {
1574+ c = dump[len - 1];
1575+ if (!isspace(c) && c != '\0')
1576+ break;
1577+ len--;
1578+ }
1579+ /* Length must match exactly. */
1580+ if (len != sprom_size_words * 4)
1581         return -EINVAL;
1582 
1583     while (cnt < sprom_size_words) {
1584         memcpy(tmp, dump, 4);
1585         dump += 4;
1586- parsed = simple_strtoul(tmp, NULL, 16);
1587+ err = strict_strtoul(tmp, 16, &parsed);
1588+ if (err)
1589+ return err;
1590         sprom[cnt++] = swab16((u16)parsed);
1591     }
1592 
1593@@ -90,6 +103,7 @@ ssize_t ssb_attr_sprom_store(struct ssb_
1594     u16 *sprom;
1595     int res = 0, err = -ENOMEM;
1596     size_t sprom_size_words = bus->sprom_size;
1597+ struct ssb_freeze_context freeze;
1598 
1599     sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
1600     if (!sprom)
1601@@ -111,18 +125,13 @@ ssize_t ssb_attr_sprom_store(struct ssb_
1602     err = -ERESTARTSYS;
1603     if (mutex_lock_interruptible(&bus->sprom_mutex))
1604         goto out_kfree;
1605- err = ssb_devices_freeze(bus);
1606- if (err == -EOPNOTSUPP) {
1607- ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze devices. "
1608- "No suspend support. Is CONFIG_PM enabled?\n");
1609- goto out_unlock;
1610- }
1611+ err = ssb_devices_freeze(bus, &freeze);
1612     if (err) {
1613         ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n");
1614         goto out_unlock;
1615     }
1616     res = sprom_write(bus, sprom);
1617- err = ssb_devices_thaw(bus);
1618+ err = ssb_devices_thaw(&freeze);
1619     if (err)
1620         ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n");
1621 out_unlock:
1622@@ -167,3 +176,17 @@ const struct ssb_sprom *ssb_get_fallback
1623 {
1624     return fallback_sprom;
1625 }
1626+
1627+/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
1628+bool ssb_is_sprom_available(struct ssb_bus *bus)
1629+{
1630+ /* status register only exists on chipcomon rev >= 11 and we need check
1631+ for >= 31 only */
1632+ /* this routine differs from specs as we do not access SPROM directly
1633+ on PCMCIA */
1634+ if (bus->bustype == SSB_BUSTYPE_PCI &&
1635+ bus->chipco.dev->id.revision >= 31)
1636+ return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
1637+
1638+ return true;
1639+}
1640--- a/drivers/ssb/ssb_private.h
1641+++ b/drivers/ssb/ssb_private.h
1642@@ -136,19 +136,27 @@ extern const struct ssb_sprom *ssb_get_f
1643 
1644 /* core.c */
1645 extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m);
1646-extern int ssb_devices_freeze(struct ssb_bus *bus);
1647-extern int ssb_devices_thaw(struct ssb_bus *bus);
1648 extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev);
1649 int ssb_for_each_bus_call(unsigned long data,
1650               int (*func)(struct ssb_bus *bus, unsigned long data));
1651 extern struct ssb_bus *ssb_pcmcia_dev_to_bus(struct pcmcia_device *pdev);
1652 
1653+struct ssb_freeze_context {
1654+ /* Pointer to the bus */
1655+ struct ssb_bus *bus;
1656+ /* Boolean list to indicate whether a device is frozen on this bus. */
1657+ bool device_frozen[SSB_MAX_NR_CORES];
1658+};
1659+extern int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx);
1660+extern int ssb_devices_thaw(struct ssb_freeze_context *ctx);
1661+
1662+
1663 
1664 /* b43_pci_bridge.c */
1665 #ifdef CONFIG_SSB_B43_PCI_BRIDGE
1666 extern int __init b43_pci_ssb_bridge_init(void);
1667 extern void __exit b43_pci_ssb_bridge_exit(void);
1668-#else /* CONFIG_SSB_B43_PCI_BRIDGR */
1669+#else /* CONFIG_SSB_B43_PCI_BRIDGE */
1670 static inline int b43_pci_ssb_bridge_init(void)
1671 {
1672     return 0;
1673@@ -156,6 +164,6 @@ static inline int b43_pci_ssb_bridge_ini
1674 static inline void b43_pci_ssb_bridge_exit(void)
1675 {
1676 }
1677-#endif /* CONFIG_SSB_PCIHOST */
1678+#endif /* CONFIG_SSB_B43_PCI_BRIDGE */
1679 
1680 #endif /* LINUX_SSB_PRIVATE_H_ */
1681

Archive Download this file



interactive