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