0001
0002
0003
0004
0005
0006
0007
0008
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
0025 #define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 0
0026
0027
0028
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
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
0066 #define SSB_PCMCIA_SPROM_SIZE 256
0067 #define SSB_PCMCIA_SPROM_SIZE_BYTES (SSB_PCMCIA_SPROM_SIZE * sizeof(u16))
0068
0069
0070
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
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
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
0427
0428
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
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;
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
0494 static int ssb_pcmcia_sprom_write(struct ssb_bus *bus, u16 offset, u16 value)
0495 {
0496 int err;
0497
0498 offset *= 2;
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
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
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
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
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;
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
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
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
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
0788
0789 ssb_pcmcia_switch_segment(bus, 0);
0790
0791 err = ssb_pcmcia_cor_setup(bus, CISREG_COR);
0792 if (err)
0793 return err;
0794
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 }