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