aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ssb/pci.c')
-rw-r--r--drivers/ssb/pci.c96
1 files changed, 68 insertions, 28 deletions
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 6e88d2b603b4..158449e55044 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -406,6 +406,46 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
406 out->antenna_gain.ghz5.a3 = gain; 406 out->antenna_gain.ghz5.a3 = gain;
407} 407}
408 408
409/* Revs 4 5 and 8 have partially shared layout */
410static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
411{
412 SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
413 SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
414 SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
415 SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
416 SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
417 SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
418 SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
419 SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
420
421 SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
422 SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
423 SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
424 SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
425 SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
426 SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
427 SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
428 SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
429
430 SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
431 SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
432 SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
433 SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
434 SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
435 SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
436 SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
437 SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
438
439 SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
440 SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
441 SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
442 SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
443 SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
444 SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
445 SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
446 SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
447}
448
409static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) 449static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
410{ 450{
411 int i; 451 int i;
@@ -471,6 +511,8 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
471 memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, 511 memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
472 sizeof(out->antenna_gain.ghz5)); 512 sizeof(out->antenna_gain.ghz5));
473 513
514 sprom_extract_r458(out, in);
515
474 /* TODO - get remaining rev 4 stuff needed */ 516 /* TODO - get remaining rev 4 stuff needed */
475} 517}
476 518
@@ -561,6 +603,8 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
561 memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, 603 memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
562 sizeof(out->antenna_gain.ghz5)); 604 sizeof(out->antenna_gain.ghz5));
563 605
606 sprom_extract_r458(out, in);
607
564 /* TODO - get remaining rev 8 stuff needed */ 608 /* TODO - get remaining rev 8 stuff needed */
565} 609}
566 610
@@ -573,37 +617,34 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
573 ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); 617 ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
574 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ 618 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
575 memset(out->et1mac, 0xFF, 6); 619 memset(out->et1mac, 0xFF, 6);
620
576 if ((bus->chip_id & 0xFF00) == 0x4400) { 621 if ((bus->chip_id & 0xFF00) == 0x4400) {
577 /* Workaround: The BCM44XX chip has a stupid revision 622 /* Workaround: The BCM44XX chip has a stupid revision
578 * number stored in the SPROM. 623 * number stored in the SPROM.
579 * Always extract r1. */ 624 * Always extract r1. */
580 out->revision = 1; 625 out->revision = 1;
626 ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision);
627 }
628
629 switch (out->revision) {
630 case 1:
631 case 2:
632 case 3:
581 sprom_extract_r123(out, in); 633 sprom_extract_r123(out, in);
582 } else if (bus->chip_id == 0x4321) { 634 break;
583 /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */ 635 case 4:
584 out->revision = 4; 636 case 5:
585 sprom_extract_r45(out, in); 637 sprom_extract_r45(out, in);
586 } else { 638 break;
587 switch (out->revision) { 639 case 8:
588 case 1: 640 sprom_extract_r8(out, in);
589 case 2: 641 break;
590 case 3: 642 default:
591 sprom_extract_r123(out, in); 643 ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
592 break; 644 " revision %d detected. Will extract"
593 case 4: 645 " v1\n", out->revision);
594 case 5: 646 out->revision = 1;
595 sprom_extract_r45(out, in); 647 sprom_extract_r123(out, in);
596 break;
597 case 8:
598 sprom_extract_r8(out, in);
599 break;
600 default:
601 ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
602 " revision %d detected. Will extract"
603 " v1\n", out->revision);
604 out->revision = 1;
605 sprom_extract_r123(out, in);
606 }
607 } 648 }
608 649
609 if (out->boardflags_lo == 0xFFFF) 650 if (out->boardflags_lo == 0xFFFF)
@@ -618,7 +659,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
618 struct ssb_sprom *sprom) 659 struct ssb_sprom *sprom)
619{ 660{
620 const struct ssb_sprom *fallback; 661 const struct ssb_sprom *fallback;
621 int err = -ENOMEM; 662 int err;
622 u16 *buf; 663 u16 *buf;
623 664
624 if (!ssb_is_sprom_available(bus)) { 665 if (!ssb_is_sprom_available(bus)) {
@@ -645,7 +686,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
645 686
646 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); 687 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
647 if (!buf) 688 if (!buf)
648 goto out; 689 return -ENOMEM;
649 bus->sprom_size = SSB_SPROMSIZE_WORDS_R123; 690 bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
650 sprom_do_read(bus, buf); 691 sprom_do_read(bus, buf);
651 err = sprom_check_crc(buf, bus->sprom_size); 692 err = sprom_check_crc(buf, bus->sprom_size);
@@ -655,7 +696,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
655 buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), 696 buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
656 GFP_KERNEL); 697 GFP_KERNEL);
657 if (!buf) 698 if (!buf)
658 goto out; 699 return -ENOMEM;
659 bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; 700 bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
660 sprom_do_read(bus, buf); 701 sprom_do_read(bus, buf);
661 err = sprom_check_crc(buf, bus->sprom_size); 702 err = sprom_check_crc(buf, bus->sprom_size);
@@ -677,7 +718,6 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
677 718
678out_free: 719out_free:
679 kfree(buf); 720 kfree(buf);
680out:
681 return err; 721 return err;
682} 722}
683 723