iwlwifi-5000: adding initial recognition for the 5000 family
[linux-2.6] / drivers / ssb / pcmcia.c
1 /*
2  * Sonics Silicon Backplane
3  * PCMCIA-Hostbus related functions
4  *
5  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6  * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
7  *
8  * Licensed under the GNU/GPL. See COPYING for details.
9  */
10
11 #include <linux/ssb/ssb.h>
12 #include <linux/delay.h>
13 #include <linux/io.h>
14 #include <linux/etherdevice.h>
15
16 #include <pcmcia/cs_types.h>
17 #include <pcmcia/cs.h>
18 #include <pcmcia/cistpl.h>
19 #include <pcmcia/ciscode.h>
20 #include <pcmcia/ds.h>
21 #include <pcmcia/cisreg.h>
22
23 #include "ssb_private.h"
24
25
26 /* Define the following to 1 to enable a printk on each coreswitch. */
27 #define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG              0
28
29
30 /* PCMCIA configuration registers */
31 #define SSB_PCMCIA_ADDRESS0             0x2E
32 #define SSB_PCMCIA_ADDRESS1             0x30
33 #define SSB_PCMCIA_ADDRESS2             0x32
34 #define SSB_PCMCIA_MEMSEG               0x34
35 #define SSB_PCMCIA_SPROMCTL             0x36
36 #define  SSB_PCMCIA_SPROMCTL_IDLE       0
37 #define  SSB_PCMCIA_SPROMCTL_WRITE      1
38 #define  SSB_PCMCIA_SPROMCTL_READ       2
39 #define  SSB_PCMCIA_SPROMCTL_WRITEEN    4
40 #define  SSB_PCMCIA_SPROMCTL_WRITEDIS   7
41 #define  SSB_PCMCIA_SPROMCTL_DONE       8
42 #define SSB_PCMCIA_SPROM_DATALO         0x38
43 #define SSB_PCMCIA_SPROM_DATAHI         0x3A
44 #define SSB_PCMCIA_SPROM_ADDRLO         0x3C
45 #define SSB_PCMCIA_SPROM_ADDRHI         0x3E
46
47 /* Hardware invariants CIS tuples */
48 #define SSB_PCMCIA_CIS                  0x80
49 #define  SSB_PCMCIA_CIS_ID              0x01
50 #define  SSB_PCMCIA_CIS_BOARDREV        0x02
51 #define  SSB_PCMCIA_CIS_PA              0x03
52 #define   SSB_PCMCIA_CIS_PA_PA0B0_LO    0
53 #define   SSB_PCMCIA_CIS_PA_PA0B0_HI    1
54 #define   SSB_PCMCIA_CIS_PA_PA0B1_LO    2
55 #define   SSB_PCMCIA_CIS_PA_PA0B1_HI    3
56 #define   SSB_PCMCIA_CIS_PA_PA0B2_LO    4
57 #define   SSB_PCMCIA_CIS_PA_PA0B2_HI    5
58 #define   SSB_PCMCIA_CIS_PA_ITSSI       6
59 #define   SSB_PCMCIA_CIS_PA_MAXPOW      7
60 #define  SSB_PCMCIA_CIS_OEMNAME         0x04
61 #define  SSB_PCMCIA_CIS_CCODE           0x05
62 #define  SSB_PCMCIA_CIS_ANTENNA         0x06
63 #define  SSB_PCMCIA_CIS_ANTGAIN         0x07
64 #define  SSB_PCMCIA_CIS_BFLAGS          0x08
65 #define  SSB_PCMCIA_CIS_LEDS            0x09
66
67 /* PCMCIA SPROM size. */
68 #define SSB_PCMCIA_SPROM_SIZE           256
69 #define SSB_PCMCIA_SPROM_SIZE_BYTES     (SSB_PCMCIA_SPROM_SIZE * sizeof(u16))
70
71
72 /* Write to a PCMCIA configuration register. */
73 static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
74 {
75         conf_reg_t reg;
76         int res;
77
78         memset(&reg, 0, sizeof(reg));
79         reg.Offset = offset;
80         reg.Action = CS_WRITE;
81         reg.Value = value;
82         res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
83         if (unlikely(res != CS_SUCCESS))
84                 return -EBUSY;
85
86         return 0;
87 }
88
89 /* Read from a PCMCIA configuration register. */
90 static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value)
91 {
92         conf_reg_t reg;
93         int res;
94
95         memset(&reg, 0, sizeof(reg));
96         reg.Offset = offset;
97         reg.Action = CS_READ;
98         res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
99         if (unlikely(res != CS_SUCCESS))
100                 return -EBUSY;
101         *value = reg.Value;
102
103         return 0;
104 }
105
106 int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
107                               u8 coreidx)
108 {
109         int err;
110         int attempts = 0;
111         u32 cur_core;
112         u32 addr;
113         u32 read_addr;
114         u8 val;
115
116         addr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
117         while (1) {
118                 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS0,
119                                            (addr & 0x0000F000) >> 12);
120                 if (err)
121                         goto error;
122                 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS1,
123                                            (addr & 0x00FF0000) >> 16);
124                 if (err)
125                         goto error;
126                 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS2,
127                                            (addr & 0xFF000000) >> 24);
128                 if (err)
129                         goto error;
130
131                 read_addr = 0;
132
133                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS0, &val);
134                 if (err)
135                         goto error;
136                 read_addr |= ((u32)(val & 0x0F)) << 12;
137                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS1, &val);
138                 if (err)
139                         goto error;
140                 read_addr |= ((u32)val) << 16;
141                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS2, &val);
142                 if (err)
143                         goto error;
144                 read_addr |= ((u32)val) << 24;
145
146                 cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
147                 if (cur_core == coreidx)
148                         break;
149
150                 err = -ETIMEDOUT;
151                 if (attempts++ > SSB_BAR0_MAX_RETRIES)
152                         goto error;
153                 udelay(10);
154         }
155
156         return 0;
157 error:
158         ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
159         return err;
160 }
161
162 int ssb_pcmcia_switch_core(struct ssb_bus *bus,
163                            struct ssb_device *dev)
164 {
165         int err;
166
167 #if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
168         ssb_printk(KERN_INFO PFX
169                    "Switching to %s core, index %d\n",
170                    ssb_core_name(dev->id.coreid),
171                    dev->core_index);
172 #endif
173
174         err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
175         if (!err)
176                 bus->mapped_device = dev;
177
178         return err;
179 }
180
181 int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
182 {
183         int attempts = 0;
184         int err;
185         u8 val;
186
187         SSB_WARN_ON((seg != 0) && (seg != 1));
188         while (1) {
189                 err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_MEMSEG, seg);
190                 if (err)
191                         goto error;
192                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_MEMSEG, &val);
193                 if (err)
194                         goto error;
195                 if (val == seg)
196                         break;
197
198                 err = -ETIMEDOUT;
199                 if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
200                         goto error;
201                 udelay(10);
202         }
203         bus->mapped_pcmcia_seg = seg;
204
205         return 0;
206 error:
207         ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n");
208         return err;
209 }
210
211 static int select_core_and_segment(struct ssb_device *dev,
212                                    u16 *offset)
213 {
214         struct ssb_bus *bus = dev->bus;
215         int err;
216         u8 need_segment;
217
218         if (*offset >= 0x800) {
219                 *offset -= 0x800;
220                 need_segment = 1;
221         } else
222                 need_segment = 0;
223
224         if (unlikely(dev != bus->mapped_device)) {
225                 err = ssb_pcmcia_switch_core(bus, dev);
226                 if (unlikely(err))
227                         return err;
228         }
229         if (unlikely(need_segment != bus->mapped_pcmcia_seg)) {
230                 err = ssb_pcmcia_switch_segment(bus, need_segment);
231                 if (unlikely(err))
232                         return err;
233         }
234
235         return 0;
236 }
237
238 static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset)
239 {
240         struct ssb_bus *bus = dev->bus;
241         unsigned long flags;
242         int err;
243         u8 value = 0xFF;
244
245         spin_lock_irqsave(&bus->bar_lock, flags);
246         err = select_core_and_segment(dev, &offset);
247         if (likely(!err))
248                 value = readb(bus->mmio + offset);
249         spin_unlock_irqrestore(&bus->bar_lock, flags);
250
251         return value;
252 }
253
254 static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
255 {
256         struct ssb_bus *bus = dev->bus;
257         unsigned long flags;
258         int err;
259         u16 value = 0xFFFF;
260
261         spin_lock_irqsave(&bus->bar_lock, flags);
262         err = select_core_and_segment(dev, &offset);
263         if (likely(!err))
264                 value = readw(bus->mmio + offset);
265         spin_unlock_irqrestore(&bus->bar_lock, flags);
266
267         return value;
268 }
269
270 static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
271 {
272         struct ssb_bus *bus = dev->bus;
273         unsigned long flags;
274         int err;
275         u32 lo = 0xFFFFFFFF, hi = 0xFFFFFFFF;
276
277         spin_lock_irqsave(&bus->bar_lock, flags);
278         err = select_core_and_segment(dev, &offset);
279         if (likely(!err)) {
280                 lo = readw(bus->mmio + offset);
281                 hi = readw(bus->mmio + offset + 2);
282         }
283         spin_unlock_irqrestore(&bus->bar_lock, flags);
284
285         return (lo | (hi << 16));
286 }
287
288 #ifdef CONFIG_SSB_BLOCKIO
289 static void ssb_pcmcia_block_read(struct ssb_device *dev, void *buffer,
290                                   size_t count, u16 offset, u8 reg_width)
291 {
292         struct ssb_bus *bus = dev->bus;
293         unsigned long flags;
294         void __iomem *addr = bus->mmio + offset;
295         int err;
296
297         spin_lock_irqsave(&bus->bar_lock, flags);
298         err = select_core_and_segment(dev, &offset);
299         if (unlikely(err)) {
300                 memset(buffer, 0xFF, count);
301                 goto unlock;
302         }
303         switch (reg_width) {
304         case sizeof(u8): {
305                 u8 *buf = buffer;
306
307                 while (count) {
308                         *buf = __raw_readb(addr);
309                         buf++;
310                         count--;
311                 }
312                 break;
313         }
314         case sizeof(u16): {
315                 __le16 *buf = buffer;
316
317                 SSB_WARN_ON(count & 1);
318                 while (count) {
319                         *buf = (__force __le16)__raw_readw(addr);
320                         buf++;
321                         count -= 2;
322                 }
323                 break;
324         }
325         case sizeof(u32): {
326                 __le16 *buf = buffer;
327
328                 SSB_WARN_ON(count & 3);
329                 while (count) {
330                         *buf = (__force __le16)__raw_readw(addr);
331                         buf++;
332                         *buf = (__force __le16)__raw_readw(addr + 2);
333                         buf++;
334                         count -= 4;
335                 }
336                 break;
337         }
338         default:
339                 SSB_WARN_ON(1);
340         }
341 unlock:
342         spin_unlock_irqrestore(&bus->bar_lock, flags);
343 }
344 #endif /* CONFIG_SSB_BLOCKIO */
345
346 static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value)
347 {
348         struct ssb_bus *bus = dev->bus;
349         unsigned long flags;
350         int err;
351
352         spin_lock_irqsave(&bus->bar_lock, flags);
353         err = select_core_and_segment(dev, &offset);
354         if (likely(!err))
355                 writeb(value, bus->mmio + offset);
356         mmiowb();
357         spin_unlock_irqrestore(&bus->bar_lock, flags);
358 }
359
360 static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
361 {
362         struct ssb_bus *bus = dev->bus;
363         unsigned long flags;
364         int err;
365
366         spin_lock_irqsave(&bus->bar_lock, flags);
367         err = select_core_and_segment(dev, &offset);
368         if (likely(!err))
369                 writew(value, bus->mmio + offset);
370         mmiowb();
371         spin_unlock_irqrestore(&bus->bar_lock, flags);
372 }
373
374 static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
375 {
376         struct ssb_bus *bus = dev->bus;
377         unsigned long flags;
378         int err;
379
380         spin_lock_irqsave(&bus->bar_lock, flags);
381         err = select_core_and_segment(dev, &offset);
382         if (likely(!err)) {
383                 writew((value & 0x0000FFFF), bus->mmio + offset);
384                 writew(((value & 0xFFFF0000) >> 16), bus->mmio + offset + 2);
385         }
386         mmiowb();
387         spin_unlock_irqrestore(&bus->bar_lock, flags);
388 }
389
390 #ifdef CONFIG_SSB_BLOCKIO
391 static void ssb_pcmcia_block_write(struct ssb_device *dev, const void *buffer,
392                                    size_t count, u16 offset, u8 reg_width)
393 {
394         struct ssb_bus *bus = dev->bus;
395         unsigned long flags;
396         void __iomem *addr = bus->mmio + offset;
397         int err;
398
399         spin_lock_irqsave(&bus->bar_lock, flags);
400         err = select_core_and_segment(dev, &offset);
401         if (unlikely(err))
402                 goto unlock;
403         switch (reg_width) {
404         case sizeof(u8): {
405                 const u8 *buf = buffer;
406
407                 while (count) {
408                         __raw_writeb(*buf, addr);
409                         buf++;
410                         count--;
411                 }
412                 break;
413         }
414         case sizeof(u16): {
415                 const __le16 *buf = buffer;
416
417                 SSB_WARN_ON(count & 1);
418                 while (count) {
419                         __raw_writew((__force u16)(*buf), addr);
420                         buf++;
421                         count -= 2;
422                 }
423                 break;
424         }
425         case sizeof(u32): {
426                 const __le16 *buf = buffer;
427
428                 SSB_WARN_ON(count & 3);
429                 while (count) {
430                         __raw_writew((__force u16)(*buf), addr);
431                         buf++;
432                         __raw_writew((__force u16)(*buf), addr + 2);
433                         buf++;
434                         count -= 4;
435                 }
436                 break;
437         }
438         default:
439                 SSB_WARN_ON(1);
440         }
441 unlock:
442         mmiowb();
443         spin_unlock_irqrestore(&bus->bar_lock, flags);
444 }
445 #endif /* CONFIG_SSB_BLOCKIO */
446
447 /* Not "static", as it's used in main.c */
448 const struct ssb_bus_ops ssb_pcmcia_ops = {
449         .read8          = ssb_pcmcia_read8,
450         .read16         = ssb_pcmcia_read16,
451         .read32         = ssb_pcmcia_read32,
452         .write8         = ssb_pcmcia_write8,
453         .write16        = ssb_pcmcia_write16,
454         .write32        = ssb_pcmcia_write32,
455 #ifdef CONFIG_SSB_BLOCKIO
456         .block_read     = ssb_pcmcia_block_read,
457         .block_write    = ssb_pcmcia_block_write,
458 #endif
459 };
460
461 static int ssb_pcmcia_sprom_command(struct ssb_bus *bus, u8 command)
462 {
463         unsigned int i;
464         int err;
465         u8 value;
466
467         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROMCTL, command);
468         if (err)
469                 return err;
470         for (i = 0; i < 1000; i++) {
471                 err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROMCTL, &value);
472                 if (err)
473                         return err;
474                 if (value & SSB_PCMCIA_SPROMCTL_DONE)
475                         return 0;
476                 udelay(10);
477         }
478
479         return -ETIMEDOUT;
480 }
481
482 /* offset is the 16bit word offset */
483 static int ssb_pcmcia_sprom_read(struct ssb_bus *bus, u16 offset, u16 *value)
484 {
485         int err;
486         u8 lo, hi;
487
488         offset *= 2; /* Make byte offset */
489
490         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
491                                    (offset & 0x00FF));
492         if (err)
493                 return err;
494         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
495                                    (offset & 0xFF00) >> 8);
496         if (err)
497                 return err;
498         err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_READ);
499         if (err)
500                 return err;
501         err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATALO, &lo);
502         if (err)
503                 return err;
504         err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATAHI, &hi);
505         if (err)
506                 return err;
507         *value = (lo | (((u16)hi) << 8));
508
509         return 0;
510 }
511
512 /* offset is the 16bit word offset */
513 static int ssb_pcmcia_sprom_write(struct ssb_bus *bus, u16 offset, u16 value)
514 {
515         int err;
516
517         offset *= 2; /* Make byte offset */
518
519         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
520                                    (offset & 0x00FF));
521         if (err)
522                 return err;
523         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
524                                    (offset & 0xFF00) >> 8);
525         if (err)
526                 return err;
527         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATALO,
528                                    (value & 0x00FF));
529         if (err)
530                 return err;
531         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATAHI,
532                                    (value & 0xFF00) >> 8);
533         if (err)
534                 return err;
535         err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITE);
536         if (err)
537                 return err;
538         msleep(20);
539
540         return 0;
541 }
542
543 /* Read the SPROM image. bufsize is in 16bit words. */
544 static int ssb_pcmcia_sprom_read_all(struct ssb_bus *bus, u16 *sprom)
545 {
546         int err, i;
547
548         for (i = 0; i < SSB_PCMCIA_SPROM_SIZE; i++) {
549                 err = ssb_pcmcia_sprom_read(bus, i, &sprom[i]);
550                 if (err)
551                         return err;
552         }
553
554         return 0;
555 }
556
557 /* Write the SPROM image. size is in 16bit words. */
558 static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom)
559 {
560         int i, err;
561         bool failed = 0;
562         size_t size = SSB_PCMCIA_SPROM_SIZE;
563
564         ssb_printk(KERN_NOTICE PFX
565                    "Writing SPROM. Do NOT turn off the power! "
566                    "Please stand by...\n");
567         err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN);
568         if (err) {
569                 ssb_printk(KERN_NOTICE PFX
570                            "Could not enable SPROM write access.\n");
571                 return -EBUSY;
572         }
573         ssb_printk(KERN_NOTICE PFX "[ 0%%");
574         msleep(500);
575         for (i = 0; i < size; i++) {
576                 if (i == size / 4)
577                         ssb_printk("25%%");
578                 else if (i == size / 2)
579                         ssb_printk("50%%");
580                 else if (i == (size * 3) / 4)
581                         ssb_printk("75%%");
582                 else if (i % 2)
583                         ssb_printk(".");
584                 err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
585                 if (err) {
586                         ssb_printk("\n" KERN_NOTICE PFX
587                                    "Failed to write to SPROM.\n");
588                         failed = 1;
589                         break;
590                 }
591         }
592         err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
593         if (err) {
594                 ssb_printk("\n" KERN_NOTICE PFX
595                            "Could not disable SPROM write access.\n");
596                 failed = 1;
597         }
598         msleep(500);
599         if (!failed) {
600                 ssb_printk("100%% ]\n");
601                 ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
602         }
603
604         return failed ? -EBUSY : 0;
605 }
606
607 static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
608 {
609         //TODO
610         return 0;
611 }
612
613 #define GOTO_ERROR_ON(condition, description) do {      \
614         if (unlikely(condition)) {                      \
615                 error_description = description;        \
616                 goto error;                             \
617         }                                               \
618   } while (0)
619
620 int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
621                               struct ssb_init_invariants *iv)
622 {
623         tuple_t tuple;
624         int res;
625         unsigned char buf[32];
626         struct ssb_sprom *sprom = &iv->sprom;
627         struct ssb_boardinfo *bi = &iv->boardinfo;
628         const char *error_description;
629
630         memset(sprom, 0xFF, sizeof(*sprom));
631         sprom->revision = 1;
632         sprom->boardflags_lo = 0;
633         sprom->boardflags_hi = 0;
634
635         /* First fetch the MAC address. */
636         memset(&tuple, 0, sizeof(tuple));
637         tuple.DesiredTuple = CISTPL_FUNCE;
638         tuple.TupleData = buf;
639         tuple.TupleDataMax = sizeof(buf);
640         res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
641         GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl");
642         res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
643         GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl data");
644         while (1) {
645                 GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
646                 if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
647                         break;
648                 res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
649                 GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl");
650                 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
651                 GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl data");
652         }
653         GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
654         memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
655
656         /* Fetch the vendor specific tuples. */
657         memset(&tuple, 0, sizeof(tuple));
658         tuple.DesiredTuple = SSB_PCMCIA_CIS;
659         tuple.TupleData = buf;
660         tuple.TupleDataMax = sizeof(buf);
661         res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
662         GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl");
663         res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
664         GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl data");
665         while (1) {
666                 GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
667                 switch (tuple.TupleData[0]) {
668                 case SSB_PCMCIA_CIS_ID:
669                         GOTO_ERROR_ON((tuple.TupleDataLen != 5) &&
670                                       (tuple.TupleDataLen != 7),
671                                       "id tpl size");
672                         bi->vendor = tuple.TupleData[1] |
673                                ((u16)tuple.TupleData[2] << 8);
674                         break;
675                 case SSB_PCMCIA_CIS_BOARDREV:
676                         GOTO_ERROR_ON(tuple.TupleDataLen != 2,
677                                       "boardrev tpl size");
678                         sprom->board_rev = tuple.TupleData[1];
679                         break;
680                 case SSB_PCMCIA_CIS_PA:
681                         GOTO_ERROR_ON(tuple.TupleDataLen != 9,
682                                       "pa tpl size");
683                         sprom->pa0b0 = tuple.TupleData[1] |
684                                  ((u16)tuple.TupleData[2] << 8);
685                         sprom->pa0b1 = tuple.TupleData[3] |
686                                  ((u16)tuple.TupleData[4] << 8);
687                         sprom->pa0b2 = tuple.TupleData[5] |
688                                  ((u16)tuple.TupleData[6] << 8);
689                         sprom->itssi_a = tuple.TupleData[7];
690                         sprom->itssi_bg = tuple.TupleData[7];
691                         sprom->maxpwr_a = tuple.TupleData[8];
692                         sprom->maxpwr_bg = tuple.TupleData[8];
693                         break;
694                 case SSB_PCMCIA_CIS_OEMNAME:
695                         /* We ignore this. */
696                         break;
697                 case SSB_PCMCIA_CIS_CCODE:
698                         GOTO_ERROR_ON(tuple.TupleDataLen != 2,
699                                       "ccode tpl size");
700                         sprom->country_code = tuple.TupleData[1];
701                         break;
702                 case SSB_PCMCIA_CIS_ANTENNA:
703                         GOTO_ERROR_ON(tuple.TupleDataLen != 2,
704                                       "ant tpl size");
705                         sprom->ant_available_a = tuple.TupleData[1];
706                         sprom->ant_available_bg = tuple.TupleData[1];
707                         break;
708                 case SSB_PCMCIA_CIS_ANTGAIN:
709                         GOTO_ERROR_ON(tuple.TupleDataLen != 2,
710                                       "antg tpl size");
711                         sprom->antenna_gain.ghz24.a0 = tuple.TupleData[1];
712                         sprom->antenna_gain.ghz24.a1 = tuple.TupleData[1];
713                         sprom->antenna_gain.ghz24.a2 = tuple.TupleData[1];
714                         sprom->antenna_gain.ghz24.a3 = tuple.TupleData[1];
715                         sprom->antenna_gain.ghz5.a0 = tuple.TupleData[1];
716                         sprom->antenna_gain.ghz5.a1 = tuple.TupleData[1];
717                         sprom->antenna_gain.ghz5.a2 = tuple.TupleData[1];
718                         sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
719                         break;
720                 case SSB_PCMCIA_CIS_BFLAGS:
721                         GOTO_ERROR_ON(tuple.TupleDataLen != 3,
722                                       "bfl tpl size");
723                         sprom->boardflags_lo = tuple.TupleData[1] |
724                                          ((u16)tuple.TupleData[2] << 8);
725                         break;
726                 case SSB_PCMCIA_CIS_LEDS:
727                         GOTO_ERROR_ON(tuple.TupleDataLen != 5,
728                                       "leds tpl size");
729                         sprom->gpio0 = tuple.TupleData[1];
730                         sprom->gpio1 = tuple.TupleData[2];
731                         sprom->gpio2 = tuple.TupleData[3];
732                         sprom->gpio3 = tuple.TupleData[4];
733                         break;
734                 }
735                 res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
736                 if (res == CS_NO_MORE_ITEMS)
737                         break;
738                 GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl");
739                 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
740                 GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl data");
741         }
742
743         return 0;
744 error:
745         ssb_printk(KERN_ERR PFX
746                    "PCMCIA: Failed to fetch device invariants: %s\n",
747                    error_description);
748         return -ENODEV;
749 }
750
751 static ssize_t ssb_pcmcia_attr_sprom_show(struct device *pcmciadev,
752                                           struct device_attribute *attr,
753                                           char *buf)
754 {
755         struct pcmcia_device *pdev =
756                 container_of(pcmciadev, struct pcmcia_device, dev);
757         struct ssb_bus *bus;
758
759         bus = ssb_pcmcia_dev_to_bus(pdev);
760         if (!bus)
761                 return -ENODEV;
762
763         return ssb_attr_sprom_show(bus, buf,
764                                    ssb_pcmcia_sprom_read_all);
765 }
766
767 static ssize_t ssb_pcmcia_attr_sprom_store(struct device *pcmciadev,
768                                            struct device_attribute *attr,
769                                            const char *buf, size_t count)
770 {
771         struct pcmcia_device *pdev =
772                 container_of(pcmciadev, struct pcmcia_device, dev);
773         struct ssb_bus *bus;
774
775         bus = ssb_pcmcia_dev_to_bus(pdev);
776         if (!bus)
777                 return -ENODEV;
778
779         return ssb_attr_sprom_store(bus, buf, count,
780                                     ssb_pcmcia_sprom_check_crc,
781                                     ssb_pcmcia_sprom_write_all);
782 }
783
784 static DEVICE_ATTR(ssb_sprom, 0600,
785                    ssb_pcmcia_attr_sprom_show,
786                    ssb_pcmcia_attr_sprom_store);
787
788 static int ssb_pcmcia_cor_setup(struct ssb_bus *bus, u8 cor)
789 {
790         u8 val;
791         int err;
792
793         err = ssb_pcmcia_cfg_read(bus, cor, &val);
794         if (err)
795                 return err;
796         val &= ~COR_SOFT_RESET;
797         val |= COR_FUNC_ENA | COR_IREQ_ENA | COR_LEVEL_REQ;
798         err = ssb_pcmcia_cfg_write(bus, cor, val);
799         if (err)
800                 return err;
801         msleep(40);
802
803         return 0;
804 }
805
806 /* Initialize the PCMCIA hardware. This is called on Init and Resume. */
807 int ssb_pcmcia_hardware_setup(struct ssb_bus *bus)
808 {
809         int err;
810
811         if (bus->bustype != SSB_BUSTYPE_PCMCIA)
812                 return 0;
813
814         /* Switch segment to a known state and sync
815          * bus->mapped_pcmcia_seg with hardware state. */
816         ssb_pcmcia_switch_segment(bus, 0);
817         /* Init the COR register. */
818         err = ssb_pcmcia_cor_setup(bus, CISREG_COR);
819         if (err)
820                 return err;
821         /* Some cards also need this register to get poked. */
822         err = ssb_pcmcia_cor_setup(bus, CISREG_COR + 0x80);
823         if (err)
824                 return err;
825
826         return 0;
827 }
828
829 void ssb_pcmcia_exit(struct ssb_bus *bus)
830 {
831         if (bus->bustype != SSB_BUSTYPE_PCMCIA)
832                 return;
833
834         device_remove_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
835 }
836
837 int ssb_pcmcia_init(struct ssb_bus *bus)
838 {
839         int err;
840
841         if (bus->bustype != SSB_BUSTYPE_PCMCIA)
842                 return 0;
843
844         err = ssb_pcmcia_hardware_setup(bus);
845         if (err)
846                 goto error;
847
848         bus->sprom_size = SSB_PCMCIA_SPROM_SIZE;
849         mutex_init(&bus->sprom_mutex);
850         err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
851         if (err)
852                 goto error;
853
854         return 0;
855 error:
856         ssb_printk(KERN_ERR PFX "Failed to initialize PCMCIA host device\n");
857         return err;
858 }