ssb: Look for SPROM at different offset on higher rev CC
[linux-2.6.git] / 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 != 0))
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 != 0))
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(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(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 static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
621                         tuple_t *tuple,
622                         void *priv)
623 {
624         struct ssb_sprom *sprom = priv;
625
626         if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
627                 return -EINVAL;
628         if (tuple->TupleDataLen != ETH_ALEN + 2)
629                 return -EINVAL;
630         if (tuple->TupleData[1] != ETH_ALEN)
631                 return -EINVAL;
632         memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
633         return 0;
634 };
635
636 static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
637                                         tuple_t *tuple,
638                                         void *priv)
639 {
640         struct ssb_init_invariants *iv = priv;
641         struct ssb_sprom *sprom = &iv->sprom;
642         struct ssb_boardinfo *bi = &iv->boardinfo;
643         const char *error_description;
644
645         GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
646         switch (tuple->TupleData[0]) {
647         case SSB_PCMCIA_CIS_ID:
648                 GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
649                               (tuple->TupleDataLen != 7),
650                               "id tpl size");
651                 bi->vendor = tuple->TupleData[1] |
652                         ((u16)tuple->TupleData[2] << 8);
653                 break;
654         case SSB_PCMCIA_CIS_BOARDREV:
655                 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
656                         "boardrev tpl size");
657                 sprom->board_rev = tuple->TupleData[1];
658                 break;
659         case SSB_PCMCIA_CIS_PA:
660                 GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
661                         (tuple->TupleDataLen != 10),
662                         "pa tpl size");
663                 sprom->pa0b0 = tuple->TupleData[1] |
664                         ((u16)tuple->TupleData[2] << 8);
665                 sprom->pa0b1 = tuple->TupleData[3] |
666                         ((u16)tuple->TupleData[4] << 8);
667                 sprom->pa0b2 = tuple->TupleData[5] |
668                         ((u16)tuple->TupleData[6] << 8);
669                 sprom->itssi_a = tuple->TupleData[7];
670                 sprom->itssi_bg = tuple->TupleData[7];
671                 sprom->maxpwr_a = tuple->TupleData[8];
672                 sprom->maxpwr_bg = tuple->TupleData[8];
673                 break;
674         case SSB_PCMCIA_CIS_OEMNAME:
675                 /* We ignore this. */
676                 break;
677         case SSB_PCMCIA_CIS_CCODE:
678                 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
679                         "ccode tpl size");
680                 sprom->country_code = tuple->TupleData[1];
681                 break;
682         case SSB_PCMCIA_CIS_ANTENNA:
683                 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
684                         "ant tpl size");
685                 sprom->ant_available_a = tuple->TupleData[1];
686                 sprom->ant_available_bg = tuple->TupleData[1];
687                 break;
688         case SSB_PCMCIA_CIS_ANTGAIN:
689                 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
690                         "antg tpl size");
691                 sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
692                 sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
693                 sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
694                 sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
695                 sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
696                 sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
697                 sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
698                 sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
699                 break;
700         case SSB_PCMCIA_CIS_BFLAGS:
701                 GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
702                         (tuple->TupleDataLen != 5),
703                         "bfl tpl size");
704                 sprom->boardflags_lo = tuple->TupleData[1] |
705                         ((u16)tuple->TupleData[2] << 8);
706                 break;
707         case SSB_PCMCIA_CIS_LEDS:
708                 GOTO_ERROR_ON(tuple->TupleDataLen != 5,
709                         "leds tpl size");
710                 sprom->gpio0 = tuple->TupleData[1];
711                 sprom->gpio1 = tuple->TupleData[2];
712                 sprom->gpio2 = tuple->TupleData[3];
713                 sprom->gpio3 = tuple->TupleData[4];
714                 break;
715         }
716         return -ENOSPC; /* continue with next entry */
717
718 error:
719         ssb_printk(KERN_ERR PFX
720                    "PCMCIA: Failed to fetch device invariants: %s\n",
721                    error_description);
722         return -ENODEV;
723 }
724
725
726 int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
727                               struct ssb_init_invariants *iv)
728 {
729         struct ssb_sprom *sprom = &iv->sprom;
730         int res;
731
732         memset(sprom, 0xFF, sizeof(*sprom));
733         sprom->revision = 1;
734         sprom->boardflags_lo = 0;
735         sprom->boardflags_hi = 0;
736
737         /* First fetch the MAC address. */
738         res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
739                                 ssb_pcmcia_get_mac, sprom);
740         if (res != 0) {
741                 ssb_printk(KERN_ERR PFX
742                         "PCMCIA: Failed to fetch MAC address\n");
743                 return -ENODEV;
744         }
745
746         /* Fetch the vendor specific tuples. */
747         res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
748                                 ssb_pcmcia_do_get_invariants, sprom);
749         if ((res == 0) || (res == -ENOSPC))
750                 return 0;
751
752         ssb_printk(KERN_ERR PFX
753                         "PCMCIA: Failed to fetch device invariants\n");
754         return -ENODEV;
755 }
756
757 static ssize_t ssb_pcmcia_attr_sprom_show(struct device *pcmciadev,
758                                           struct device_attribute *attr,
759                                           char *buf)
760 {
761         struct pcmcia_device *pdev =
762                 container_of(pcmciadev, struct pcmcia_device, dev);
763         struct ssb_bus *bus;
764
765         bus = ssb_pcmcia_dev_to_bus(pdev);
766         if (!bus)
767                 return -ENODEV;
768
769         return ssb_attr_sprom_show(bus, buf,
770                                    ssb_pcmcia_sprom_read_all);
771 }
772
773 static ssize_t ssb_pcmcia_attr_sprom_store(struct device *pcmciadev,
774                                            struct device_attribute *attr,
775                                            const char *buf, size_t count)
776 {
777         struct pcmcia_device *pdev =
778                 container_of(pcmciadev, struct pcmcia_device, dev);
779         struct ssb_bus *bus;
780
781         bus = ssb_pcmcia_dev_to_bus(pdev);
782         if (!bus)
783                 return -ENODEV;
784
785         return ssb_attr_sprom_store(bus, buf, count,
786                                     ssb_pcmcia_sprom_check_crc,
787                                     ssb_pcmcia_sprom_write_all);
788 }
789
790 static DEVICE_ATTR(ssb_sprom, 0600,
791                    ssb_pcmcia_attr_sprom_show,
792                    ssb_pcmcia_attr_sprom_store);
793
794 static int ssb_pcmcia_cor_setup(struct ssb_bus *bus, u8 cor)
795 {
796         u8 val;
797         int err;
798
799         err = ssb_pcmcia_cfg_read(bus, cor, &val);
800         if (err)
801                 return err;
802         val &= ~COR_SOFT_RESET;
803         val |= COR_FUNC_ENA | COR_IREQ_ENA | COR_LEVEL_REQ;
804         err = ssb_pcmcia_cfg_write(bus, cor, val);
805         if (err)
806                 return err;
807         msleep(40);
808
809         return 0;
810 }
811
812 /* Initialize the PCMCIA hardware. This is called on Init and Resume. */
813 int ssb_pcmcia_hardware_setup(struct ssb_bus *bus)
814 {
815         int err;
816
817         if (bus->bustype != SSB_BUSTYPE_PCMCIA)
818                 return 0;
819
820         /* Switch segment to a known state and sync
821          * bus->mapped_pcmcia_seg with hardware state. */
822         ssb_pcmcia_switch_segment(bus, 0);
823         /* Init the COR register. */
824         err = ssb_pcmcia_cor_setup(bus, CISREG_COR);
825         if (err)
826                 return err;
827         /* Some cards also need this register to get poked. */
828         err = ssb_pcmcia_cor_setup(bus, CISREG_COR + 0x80);
829         if (err)
830                 return err;
831
832         return 0;
833 }
834
835 void ssb_pcmcia_exit(struct ssb_bus *bus)
836 {
837         if (bus->bustype != SSB_BUSTYPE_PCMCIA)
838                 return;
839
840         device_remove_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
841 }
842
843 int ssb_pcmcia_init(struct ssb_bus *bus)
844 {
845         int err;
846
847         if (bus->bustype != SSB_BUSTYPE_PCMCIA)
848                 return 0;
849
850         err = ssb_pcmcia_hardware_setup(bus);
851         if (err)
852                 goto error;
853
854         bus->sprom_size = SSB_PCMCIA_SPROM_SIZE;
855         mutex_init(&bus->sprom_mutex);
856         err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
857         if (err)
858                 goto error;
859
860         return 0;
861 error:
862         ssb_printk(KERN_ERR PFX "Failed to initialize PCMCIA host device\n");
863         return err;
864 }