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