Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Sonics Silicon Backplane
0003  * PCMCIA-Hostbus related functions
0004  *
0005  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
0006  * Copyright 2007-2008 Michael Buesch <m@bues.ch>
0007  *
0008  * Licensed under the GNU/GPL. See COPYING for details.
0009  */
0010 
0011 #include "ssb_private.h"
0012 
0013 #include <linux/ssb/ssb.h>
0014 #include <linux/delay.h>
0015 #include <linux/io.h>
0016 #include <linux/etherdevice.h>
0017 
0018 #include <pcmcia/cistpl.h>
0019 #include <pcmcia/ciscode.h>
0020 #include <pcmcia/ds.h>
0021 #include <pcmcia/cisreg.h>
0022 
0023 
0024 /* Define the following to 1 to enable a printk on each coreswitch. */
0025 #define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG      0
0026 
0027 
0028 /* PCMCIA configuration registers */
0029 #define SSB_PCMCIA_ADDRESS0     0x2E
0030 #define SSB_PCMCIA_ADDRESS1     0x30
0031 #define SSB_PCMCIA_ADDRESS2     0x32
0032 #define SSB_PCMCIA_MEMSEG       0x34
0033 #define SSB_PCMCIA_SPROMCTL     0x36
0034 #define  SSB_PCMCIA_SPROMCTL_IDLE   0
0035 #define  SSB_PCMCIA_SPROMCTL_WRITE  1
0036 #define  SSB_PCMCIA_SPROMCTL_READ   2
0037 #define  SSB_PCMCIA_SPROMCTL_WRITEEN    4
0038 #define  SSB_PCMCIA_SPROMCTL_WRITEDIS   7
0039 #define  SSB_PCMCIA_SPROMCTL_DONE   8
0040 #define SSB_PCMCIA_SPROM_DATALO     0x38
0041 #define SSB_PCMCIA_SPROM_DATAHI     0x3A
0042 #define SSB_PCMCIA_SPROM_ADDRLO     0x3C
0043 #define SSB_PCMCIA_SPROM_ADDRHI     0x3E
0044 
0045 /* Hardware invariants CIS tuples */
0046 #define SSB_PCMCIA_CIS          0x80
0047 #define  SSB_PCMCIA_CIS_ID      0x01
0048 #define  SSB_PCMCIA_CIS_BOARDREV    0x02
0049 #define  SSB_PCMCIA_CIS_PA      0x03
0050 #define   SSB_PCMCIA_CIS_PA_PA0B0_LO    0
0051 #define   SSB_PCMCIA_CIS_PA_PA0B0_HI    1
0052 #define   SSB_PCMCIA_CIS_PA_PA0B1_LO    2
0053 #define   SSB_PCMCIA_CIS_PA_PA0B1_HI    3
0054 #define   SSB_PCMCIA_CIS_PA_PA0B2_LO    4
0055 #define   SSB_PCMCIA_CIS_PA_PA0B2_HI    5
0056 #define   SSB_PCMCIA_CIS_PA_ITSSI   6
0057 #define   SSB_PCMCIA_CIS_PA_MAXPOW  7
0058 #define  SSB_PCMCIA_CIS_OEMNAME     0x04
0059 #define  SSB_PCMCIA_CIS_CCODE       0x05
0060 #define  SSB_PCMCIA_CIS_ANTENNA     0x06
0061 #define  SSB_PCMCIA_CIS_ANTGAIN     0x07
0062 #define  SSB_PCMCIA_CIS_BFLAGS      0x08
0063 #define  SSB_PCMCIA_CIS_LEDS        0x09
0064 
0065 /* PCMCIA SPROM size. */
0066 #define SSB_PCMCIA_SPROM_SIZE       256
0067 #define SSB_PCMCIA_SPROM_SIZE_BYTES (SSB_PCMCIA_SPROM_SIZE * sizeof(u16))
0068 
0069 
0070 /* Write to a PCMCIA configuration register. */
0071 static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
0072 {
0073     int res;
0074 
0075     res = pcmcia_write_config_byte(bus->host_pcmcia, offset, value);
0076     if (unlikely(res != 0))
0077         return -EBUSY;
0078 
0079     return 0;
0080 }
0081 
0082 /* Read from a PCMCIA configuration register. */
0083 static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value)
0084 {
0085     int res;
0086 
0087     res = pcmcia_read_config_byte(bus->host_pcmcia, offset, value);
0088     if (unlikely(res != 0))
0089         return -EBUSY;
0090 
0091     return 0;
0092 }
0093 
0094 int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
0095                   u8 coreidx)
0096 {
0097     int err;
0098     int attempts = 0;
0099     u32 cur_core;
0100     u32 addr;
0101     u32 read_addr;
0102     u8 val;
0103 
0104     addr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
0105     while (1) {
0106         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS0,
0107                        (addr & 0x0000F000) >> 12);
0108         if (err)
0109             goto error;
0110         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS1,
0111                        (addr & 0x00FF0000) >> 16);
0112         if (err)
0113             goto error;
0114         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS2,
0115                        (addr & 0xFF000000) >> 24);
0116         if (err)
0117             goto error;
0118 
0119         read_addr = 0;
0120 
0121         err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS0, &val);
0122         if (err)
0123             goto error;
0124         read_addr |= ((u32)(val & 0x0F)) << 12;
0125         err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS1, &val);
0126         if (err)
0127             goto error;
0128         read_addr |= ((u32)val) << 16;
0129         err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS2, &val);
0130         if (err)
0131             goto error;
0132         read_addr |= ((u32)val) << 24;
0133 
0134         cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
0135         if (cur_core == coreidx)
0136             break;
0137 
0138         err = -ETIMEDOUT;
0139         if (attempts++ > SSB_BAR0_MAX_RETRIES)
0140             goto error;
0141         udelay(10);
0142     }
0143 
0144     return 0;
0145 error:
0146     pr_err("Failed to switch to core %u\n", coreidx);
0147     return err;
0148 }
0149 
0150 static int ssb_pcmcia_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
0151 {
0152     int err;
0153 
0154 #if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
0155     pr_info("Switching to %s core, index %d\n",
0156         ssb_core_name(dev->id.coreid), dev->core_index);
0157 #endif
0158 
0159     err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
0160     if (!err)
0161         bus->mapped_device = dev;
0162 
0163     return err;
0164 }
0165 
0166 int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
0167 {
0168     int attempts = 0;
0169     int err;
0170     u8 val;
0171 
0172     WARN_ON((seg != 0) && (seg != 1));
0173     while (1) {
0174         err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_MEMSEG, seg);
0175         if (err)
0176             goto error;
0177         err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_MEMSEG, &val);
0178         if (err)
0179             goto error;
0180         if (val == seg)
0181             break;
0182 
0183         err = -ETIMEDOUT;
0184         if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
0185             goto error;
0186         udelay(10);
0187     }
0188     bus->mapped_pcmcia_seg = seg;
0189 
0190     return 0;
0191 error:
0192     pr_err("Failed to switch pcmcia segment\n");
0193     return err;
0194 }
0195 
0196 static int select_core_and_segment(struct ssb_device *dev,
0197                    u16 *offset)
0198 {
0199     struct ssb_bus *bus = dev->bus;
0200     int err;
0201     u8 need_segment;
0202 
0203     if (*offset >= 0x800) {
0204         *offset -= 0x800;
0205         need_segment = 1;
0206     } else
0207         need_segment = 0;
0208 
0209     if (unlikely(dev != bus->mapped_device)) {
0210         err = ssb_pcmcia_switch_core(bus, dev);
0211         if (unlikely(err))
0212             return err;
0213     }
0214     if (unlikely(need_segment != bus->mapped_pcmcia_seg)) {
0215         err = ssb_pcmcia_switch_segment(bus, need_segment);
0216         if (unlikely(err))
0217             return err;
0218     }
0219 
0220     return 0;
0221 }
0222 
0223 static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset)
0224 {
0225     struct ssb_bus *bus = dev->bus;
0226     unsigned long flags;
0227     int err;
0228     u8 value = 0xFF;
0229 
0230     spin_lock_irqsave(&bus->bar_lock, flags);
0231     err = select_core_and_segment(dev, &offset);
0232     if (likely(!err))
0233         value = readb(bus->mmio + offset);
0234     spin_unlock_irqrestore(&bus->bar_lock, flags);
0235 
0236     return value;
0237 }
0238 
0239 static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
0240 {
0241     struct ssb_bus *bus = dev->bus;
0242     unsigned long flags;
0243     int err;
0244     u16 value = 0xFFFF;
0245 
0246     spin_lock_irqsave(&bus->bar_lock, flags);
0247     err = select_core_and_segment(dev, &offset);
0248     if (likely(!err))
0249         value = readw(bus->mmio + offset);
0250     spin_unlock_irqrestore(&bus->bar_lock, flags);
0251 
0252     return value;
0253 }
0254 
0255 static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
0256 {
0257     struct ssb_bus *bus = dev->bus;
0258     unsigned long flags;
0259     int err;
0260     u32 lo = 0xFFFFFFFF, hi = 0xFFFFFFFF;
0261 
0262     spin_lock_irqsave(&bus->bar_lock, flags);
0263     err = select_core_and_segment(dev, &offset);
0264     if (likely(!err)) {
0265         lo = readw(bus->mmio + offset);
0266         hi = readw(bus->mmio + offset + 2);
0267     }
0268     spin_unlock_irqrestore(&bus->bar_lock, flags);
0269 
0270     return (lo | (hi << 16));
0271 }
0272 
0273 #ifdef CONFIG_SSB_BLOCKIO
0274 static void ssb_pcmcia_block_read(struct ssb_device *dev, void *buffer,
0275                   size_t count, u16 offset, u8 reg_width)
0276 {
0277     struct ssb_bus *bus = dev->bus;
0278     unsigned long flags;
0279     void __iomem *addr = bus->mmio + offset;
0280     int err;
0281 
0282     spin_lock_irqsave(&bus->bar_lock, flags);
0283     err = select_core_and_segment(dev, &offset);
0284     if (unlikely(err)) {
0285         memset(buffer, 0xFF, count);
0286         goto unlock;
0287     }
0288     switch (reg_width) {
0289     case sizeof(u8): {
0290         u8 *buf = buffer;
0291 
0292         while (count) {
0293             *buf = __raw_readb(addr);
0294             buf++;
0295             count--;
0296         }
0297         break;
0298     }
0299     case sizeof(u16): {
0300         __le16 *buf = buffer;
0301 
0302         WARN_ON(count & 1);
0303         while (count) {
0304             *buf = (__force __le16)__raw_readw(addr);
0305             buf++;
0306             count -= 2;
0307         }
0308         break;
0309     }
0310     case sizeof(u32): {
0311         __le16 *buf = buffer;
0312 
0313         WARN_ON(count & 3);
0314         while (count) {
0315             *buf = (__force __le16)__raw_readw(addr);
0316             buf++;
0317             *buf = (__force __le16)__raw_readw(addr + 2);
0318             buf++;
0319             count -= 4;
0320         }
0321         break;
0322     }
0323     default:
0324         WARN_ON(1);
0325     }
0326 unlock:
0327     spin_unlock_irqrestore(&bus->bar_lock, flags);
0328 }
0329 #endif /* CONFIG_SSB_BLOCKIO */
0330 
0331 static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value)
0332 {
0333     struct ssb_bus *bus = dev->bus;
0334     unsigned long flags;
0335     int err;
0336 
0337     spin_lock_irqsave(&bus->bar_lock, flags);
0338     err = select_core_and_segment(dev, &offset);
0339     if (likely(!err))
0340         writeb(value, bus->mmio + offset);
0341     spin_unlock_irqrestore(&bus->bar_lock, flags);
0342 }
0343 
0344 static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
0345 {
0346     struct ssb_bus *bus = dev->bus;
0347     unsigned long flags;
0348     int err;
0349 
0350     spin_lock_irqsave(&bus->bar_lock, flags);
0351     err = select_core_and_segment(dev, &offset);
0352     if (likely(!err))
0353         writew(value, bus->mmio + offset);
0354     spin_unlock_irqrestore(&bus->bar_lock, flags);
0355 }
0356 
0357 static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
0358 {
0359     struct ssb_bus *bus = dev->bus;
0360     unsigned long flags;
0361     int err;
0362 
0363     spin_lock_irqsave(&bus->bar_lock, flags);
0364     err = select_core_and_segment(dev, &offset);
0365     if (likely(!err)) {
0366         writew((value & 0x0000FFFF), bus->mmio + offset);
0367         writew(((value & 0xFFFF0000) >> 16), bus->mmio + offset + 2);
0368     }
0369     spin_unlock_irqrestore(&bus->bar_lock, flags);
0370 }
0371 
0372 #ifdef CONFIG_SSB_BLOCKIO
0373 static void ssb_pcmcia_block_write(struct ssb_device *dev, const void *buffer,
0374                    size_t count, u16 offset, u8 reg_width)
0375 {
0376     struct ssb_bus *bus = dev->bus;
0377     unsigned long flags;
0378     void __iomem *addr = bus->mmio + offset;
0379     int err;
0380 
0381     spin_lock_irqsave(&bus->bar_lock, flags);
0382     err = select_core_and_segment(dev, &offset);
0383     if (unlikely(err))
0384         goto unlock;
0385     switch (reg_width) {
0386     case sizeof(u8): {
0387         const u8 *buf = buffer;
0388 
0389         while (count) {
0390             __raw_writeb(*buf, addr);
0391             buf++;
0392             count--;
0393         }
0394         break;
0395     }
0396     case sizeof(u16): {
0397         const __le16 *buf = buffer;
0398 
0399         WARN_ON(count & 1);
0400         while (count) {
0401             __raw_writew((__force u16)(*buf), addr);
0402             buf++;
0403             count -= 2;
0404         }
0405         break;
0406     }
0407     case sizeof(u32): {
0408         const __le16 *buf = buffer;
0409 
0410         WARN_ON(count & 3);
0411         while (count) {
0412             __raw_writew((__force u16)(*buf), addr);
0413             buf++;
0414             __raw_writew((__force u16)(*buf), addr + 2);
0415             buf++;
0416             count -= 4;
0417         }
0418         break;
0419     }
0420     default:
0421         WARN_ON(1);
0422     }
0423 unlock:
0424     spin_unlock_irqrestore(&bus->bar_lock, flags);
0425 }
0426 #endif /* CONFIG_SSB_BLOCKIO */
0427 
0428 /* Not "static", as it's used in main.c */
0429 const struct ssb_bus_ops ssb_pcmcia_ops = {
0430     .read8      = ssb_pcmcia_read8,
0431     .read16     = ssb_pcmcia_read16,
0432     .read32     = ssb_pcmcia_read32,
0433     .write8     = ssb_pcmcia_write8,
0434     .write16    = ssb_pcmcia_write16,
0435     .write32    = ssb_pcmcia_write32,
0436 #ifdef CONFIG_SSB_BLOCKIO
0437     .block_read = ssb_pcmcia_block_read,
0438     .block_write    = ssb_pcmcia_block_write,
0439 #endif
0440 };
0441 
0442 static int ssb_pcmcia_sprom_command(struct ssb_bus *bus, u8 command)
0443 {
0444     unsigned int i;
0445     int err;
0446     u8 value;
0447 
0448     err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROMCTL, command);
0449     if (err)
0450         return err;
0451     for (i = 0; i < 1000; i++) {
0452         err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROMCTL, &value);
0453         if (err)
0454             return err;
0455         if (value & SSB_PCMCIA_SPROMCTL_DONE)
0456             return 0;
0457         udelay(10);
0458     }
0459 
0460     return -ETIMEDOUT;
0461 }
0462 
0463 /* offset is the 16bit word offset */
0464 static int ssb_pcmcia_sprom_read(struct ssb_bus *bus, u16 offset, u16 *value)
0465 {
0466     int err;
0467     u8 lo, hi;
0468 
0469     offset *= 2; /* Make byte offset */
0470 
0471     err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
0472                    (offset & 0x00FF));
0473     if (err)
0474         return err;
0475     err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
0476                    (offset & 0xFF00) >> 8);
0477     if (err)
0478         return err;
0479     err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_READ);
0480     if (err)
0481         return err;
0482     err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATALO, &lo);
0483     if (err)
0484         return err;
0485     err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATAHI, &hi);
0486     if (err)
0487         return err;
0488     *value = (lo | (((u16)hi) << 8));
0489 
0490     return 0;
0491 }
0492 
0493 /* offset is the 16bit word offset */
0494 static int ssb_pcmcia_sprom_write(struct ssb_bus *bus, u16 offset, u16 value)
0495 {
0496     int err;
0497 
0498     offset *= 2; /* Make byte offset */
0499 
0500     err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
0501                    (offset & 0x00FF));
0502     if (err)
0503         return err;
0504     err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
0505                    (offset & 0xFF00) >> 8);
0506     if (err)
0507         return err;
0508     err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATALO,
0509                    (value & 0x00FF));
0510     if (err)
0511         return err;
0512     err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATAHI,
0513                    (value & 0xFF00) >> 8);
0514     if (err)
0515         return err;
0516     err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITE);
0517     if (err)
0518         return err;
0519     msleep(20);
0520 
0521     return 0;
0522 }
0523 
0524 /* Read the SPROM image. bufsize is in 16bit words. */
0525 static int ssb_pcmcia_sprom_read_all(struct ssb_bus *bus, u16 *sprom)
0526 {
0527     int err, i;
0528 
0529     for (i = 0; i < SSB_PCMCIA_SPROM_SIZE; i++) {
0530         err = ssb_pcmcia_sprom_read(bus, i, &sprom[i]);
0531         if (err)
0532             return err;
0533     }
0534 
0535     return 0;
0536 }
0537 
0538 /* Write the SPROM image. size is in 16bit words. */
0539 static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom)
0540 {
0541     int i, err;
0542     bool failed = 0;
0543     size_t size = SSB_PCMCIA_SPROM_SIZE;
0544 
0545     pr_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n");
0546     err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN);
0547     if (err) {
0548         pr_notice("Could not enable SPROM write access\n");
0549         return -EBUSY;
0550     }
0551     pr_notice("[ 0%%");
0552     msleep(500);
0553     for (i = 0; i < size; i++) {
0554         if (i == size / 4)
0555             pr_cont("25%%");
0556         else if (i == size / 2)
0557             pr_cont("50%%");
0558         else if (i == (size * 3) / 4)
0559             pr_cont("75%%");
0560         else if (i % 2)
0561             pr_cont(".");
0562         err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
0563         if (err) {
0564             pr_notice("Failed to write to SPROM\n");
0565             failed = 1;
0566             break;
0567         }
0568     }
0569     err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
0570     if (err) {
0571         pr_notice("Could not disable SPROM write access\n");
0572         failed = 1;
0573     }
0574     msleep(500);
0575     if (!failed) {
0576         pr_cont("100%% ]\n");
0577         pr_notice("SPROM written\n");
0578     }
0579 
0580     return failed ? -EBUSY : 0;
0581 }
0582 
0583 static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
0584 {
0585     //TODO
0586     return 0;
0587 }
0588 
0589 #define GOTO_ERROR_ON(condition, description) do {  \
0590     if (unlikely(condition)) {          \
0591         error_description = description;    \
0592         goto error;             \
0593     }                       \
0594   } while (0)
0595 
0596 static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
0597             tuple_t *tuple,
0598             void *priv)
0599 {
0600     struct ssb_sprom *sprom = priv;
0601 
0602     if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
0603         return -EINVAL;
0604     if (tuple->TupleDataLen != ETH_ALEN + 2)
0605         return -EINVAL;
0606     if (tuple->TupleData[1] != ETH_ALEN)
0607         return -EINVAL;
0608     memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
0609     return 0;
0610 };
0611 
0612 static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
0613                     tuple_t *tuple,
0614                     void *priv)
0615 {
0616     struct ssb_init_invariants *iv = priv;
0617     struct ssb_sprom *sprom = &iv->sprom;
0618     struct ssb_boardinfo *bi = &iv->boardinfo;
0619     const char *error_description;
0620 
0621     GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
0622     switch (tuple->TupleData[0]) {
0623     case SSB_PCMCIA_CIS_ID:
0624         GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
0625                   (tuple->TupleDataLen != 7),
0626                   "id tpl size");
0627         bi->vendor = tuple->TupleData[1] |
0628             ((u16)tuple->TupleData[2] << 8);
0629         break;
0630     case SSB_PCMCIA_CIS_BOARDREV:
0631         GOTO_ERROR_ON(tuple->TupleDataLen != 2,
0632             "boardrev tpl size");
0633         sprom->board_rev = tuple->TupleData[1];
0634         break;
0635     case SSB_PCMCIA_CIS_PA:
0636         GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
0637             (tuple->TupleDataLen != 10),
0638             "pa tpl size");
0639         sprom->pa0b0 = tuple->TupleData[1] |
0640             ((u16)tuple->TupleData[2] << 8);
0641         sprom->pa0b1 = tuple->TupleData[3] |
0642             ((u16)tuple->TupleData[4] << 8);
0643         sprom->pa0b2 = tuple->TupleData[5] |
0644             ((u16)tuple->TupleData[6] << 8);
0645         sprom->itssi_a = tuple->TupleData[7];
0646         sprom->itssi_bg = tuple->TupleData[7];
0647         sprom->maxpwr_a = tuple->TupleData[8];
0648         sprom->maxpwr_bg = tuple->TupleData[8];
0649         break;
0650     case SSB_PCMCIA_CIS_OEMNAME:
0651         /* We ignore this. */
0652         break;
0653     case SSB_PCMCIA_CIS_CCODE:
0654         GOTO_ERROR_ON(tuple->TupleDataLen != 2,
0655             "ccode tpl size");
0656         sprom->country_code = tuple->TupleData[1];
0657         break;
0658     case SSB_PCMCIA_CIS_ANTENNA:
0659         GOTO_ERROR_ON(tuple->TupleDataLen != 2,
0660             "ant tpl size");
0661         sprom->ant_available_a = tuple->TupleData[1];
0662         sprom->ant_available_bg = tuple->TupleData[1];
0663         break;
0664     case SSB_PCMCIA_CIS_ANTGAIN:
0665         GOTO_ERROR_ON(tuple->TupleDataLen != 2,
0666             "antg tpl size");
0667         sprom->antenna_gain.a0 = tuple->TupleData[1];
0668         sprom->antenna_gain.a1 = tuple->TupleData[1];
0669         sprom->antenna_gain.a2 = tuple->TupleData[1];
0670         sprom->antenna_gain.a3 = tuple->TupleData[1];
0671         break;
0672     case SSB_PCMCIA_CIS_BFLAGS:
0673         GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
0674             (tuple->TupleDataLen != 5),
0675             "bfl tpl size");
0676         sprom->boardflags_lo = tuple->TupleData[1] |
0677             ((u16)tuple->TupleData[2] << 8);
0678         break;
0679     case SSB_PCMCIA_CIS_LEDS:
0680         GOTO_ERROR_ON(tuple->TupleDataLen != 5,
0681             "leds tpl size");
0682         sprom->gpio0 = tuple->TupleData[1];
0683         sprom->gpio1 = tuple->TupleData[2];
0684         sprom->gpio2 = tuple->TupleData[3];
0685         sprom->gpio3 = tuple->TupleData[4];
0686         break;
0687     }
0688     return -ENOSPC; /* continue with next entry */
0689 
0690 error:
0691     pr_err("PCMCIA: Failed to fetch device invariants: %s\n",
0692            error_description);
0693     return -ENODEV;
0694 }
0695 
0696 
0697 int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
0698                   struct ssb_init_invariants *iv)
0699 {
0700     struct ssb_sprom *sprom = &iv->sprom;
0701     int res;
0702 
0703     memset(sprom, 0xFF, sizeof(*sprom));
0704     sprom->revision = 1;
0705     sprom->boardflags_lo = 0;
0706     sprom->boardflags_hi = 0;
0707 
0708     /* First fetch the MAC address. */
0709     res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
0710                 ssb_pcmcia_get_mac, sprom);
0711     if (res != 0) {
0712         pr_err("PCMCIA: Failed to fetch MAC address\n");
0713         return -ENODEV;
0714     }
0715 
0716     /* Fetch the vendor specific tuples. */
0717     res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
0718                 ssb_pcmcia_do_get_invariants, iv);
0719     if ((res == 0) || (res == -ENOSPC))
0720         return 0;
0721 
0722     pr_err("PCMCIA: Failed to fetch device invariants\n");
0723     return -ENODEV;
0724 }
0725 
0726 static ssize_t ssb_sprom_show(struct device *pcmciadev,
0727                   struct device_attribute *attr,
0728                   char *buf)
0729 {
0730     struct pcmcia_device *pdev =
0731         container_of(pcmciadev, struct pcmcia_device, dev);
0732     struct ssb_bus *bus;
0733 
0734     bus = ssb_pcmcia_dev_to_bus(pdev);
0735     if (!bus)
0736         return -ENODEV;
0737 
0738     return ssb_attr_sprom_show(bus, buf,
0739                    ssb_pcmcia_sprom_read_all);
0740 }
0741 
0742 static ssize_t ssb_sprom_store(struct device *pcmciadev,
0743                    struct device_attribute *attr,
0744                    const char *buf, size_t count)
0745 {
0746     struct pcmcia_device *pdev =
0747         container_of(pcmciadev, struct pcmcia_device, dev);
0748     struct ssb_bus *bus;
0749 
0750     bus = ssb_pcmcia_dev_to_bus(pdev);
0751     if (!bus)
0752         return -ENODEV;
0753 
0754     return ssb_attr_sprom_store(bus, buf, count,
0755                     ssb_pcmcia_sprom_check_crc,
0756                     ssb_pcmcia_sprom_write_all);
0757 }
0758 
0759 static DEVICE_ATTR_ADMIN_RW(ssb_sprom);
0760 
0761 static int ssb_pcmcia_cor_setup(struct ssb_bus *bus, u8 cor)
0762 {
0763     u8 val;
0764     int err;
0765 
0766     err = ssb_pcmcia_cfg_read(bus, cor, &val);
0767     if (err)
0768         return err;
0769     val &= ~COR_SOFT_RESET;
0770     val |= COR_FUNC_ENA | COR_IREQ_ENA | COR_LEVEL_REQ;
0771     err = ssb_pcmcia_cfg_write(bus, cor, val);
0772     if (err)
0773         return err;
0774     msleep(40);
0775 
0776     return 0;
0777 }
0778 
0779 /* Initialize the PCMCIA hardware. This is called on Init and Resume. */
0780 int ssb_pcmcia_hardware_setup(struct ssb_bus *bus)
0781 {
0782     int err;
0783 
0784     if (bus->bustype != SSB_BUSTYPE_PCMCIA)
0785         return 0;
0786 
0787     /* Switch segment to a known state and sync
0788      * bus->mapped_pcmcia_seg with hardware state. */
0789     ssb_pcmcia_switch_segment(bus, 0);
0790     /* Init the COR register. */
0791     err = ssb_pcmcia_cor_setup(bus, CISREG_COR);
0792     if (err)
0793         return err;
0794     /* Some cards also need this register to get poked. */
0795     err = ssb_pcmcia_cor_setup(bus, CISREG_COR + 0x80);
0796     if (err)
0797         return err;
0798 
0799     return 0;
0800 }
0801 
0802 void ssb_pcmcia_exit(struct ssb_bus *bus)
0803 {
0804     if (bus->bustype != SSB_BUSTYPE_PCMCIA)
0805         return;
0806 
0807     device_remove_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
0808 }
0809 
0810 int ssb_pcmcia_init(struct ssb_bus *bus)
0811 {
0812     int err;
0813 
0814     if (bus->bustype != SSB_BUSTYPE_PCMCIA)
0815         return 0;
0816 
0817     err = ssb_pcmcia_hardware_setup(bus);
0818     if (err)
0819         goto error;
0820 
0821     bus->sprom_size = SSB_PCMCIA_SPROM_SIZE;
0822     mutex_init(&bus->sprom_mutex);
0823     err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
0824     if (err)
0825         goto error;
0826 
0827     return 0;
0828 error:
0829     pr_err("Failed to initialize PCMCIA host device\n");
0830     return err;
0831 }