aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/main.c30
-rw-r--r--drivers/ssb/pci.c96
-rw-r--r--drivers/ssb/pcihost_wrapper.c7
-rw-r--r--drivers/ssb/scan.c4
4 files changed, 107 insertions, 30 deletions
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index c68b3dc19e11..3918d2cc5856 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -383,6 +383,35 @@ static int ssb_device_uevent(struct device *dev, struct kobj_uevent_env *env)
383 ssb_dev->id.revision); 383 ssb_dev->id.revision);
384} 384}
385 385
386#define ssb_config_attr(attrib, field, format_string) \
387static ssize_t \
388attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \
389{ \
390 return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \
391}
392
393ssb_config_attr(core_num, core_index, "%u\n")
394ssb_config_attr(coreid, id.coreid, "0x%04x\n")
395ssb_config_attr(vendor, id.vendor, "0x%04x\n")
396ssb_config_attr(revision, id.revision, "%u\n")
397ssb_config_attr(irq, irq, "%u\n")
398static ssize_t
399name_show(struct device *dev, struct device_attribute *attr, char *buf)
400{
401 return sprintf(buf, "%s\n",
402 ssb_core_name(dev_to_ssb_dev(dev)->id.coreid));
403}
404
405static struct device_attribute ssb_device_attrs[] = {
406 __ATTR_RO(name),
407 __ATTR_RO(core_num),
408 __ATTR_RO(coreid),
409 __ATTR_RO(vendor),
410 __ATTR_RO(revision),
411 __ATTR_RO(irq),
412 __ATTR_NULL,
413};
414
386static struct bus_type ssb_bustype = { 415static struct bus_type ssb_bustype = {
387 .name = "ssb", 416 .name = "ssb",
388 .match = ssb_bus_match, 417 .match = ssb_bus_match,
@@ -392,6 +421,7 @@ static struct bus_type ssb_bustype = {
392 .suspend = ssb_device_suspend, 421 .suspend = ssb_device_suspend,
393 .resume = ssb_device_resume, 422 .resume = ssb_device_resume,
394 .uevent = ssb_device_uevent, 423 .uevent = ssb_device_uevent,
424 .dev_attrs = ssb_device_attrs,
395}; 425};
396 426
397static void ssb_buses_lock(void) 427static void ssb_buses_lock(void)
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
diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c
index 6536a041d90d..f6c8c81a0025 100644
--- a/drivers/ssb/pcihost_wrapper.c
+++ b/drivers/ssb/pcihost_wrapper.c
@@ -59,6 +59,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
59 struct ssb_bus *ssb; 59 struct ssb_bus *ssb;
60 int err = -ENOMEM; 60 int err = -ENOMEM;
61 const char *name; 61 const char *name;
62 u32 val;
62 63
63 ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); 64 ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
64 if (!ssb) 65 if (!ssb)
@@ -74,6 +75,12 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
74 goto err_pci_disable; 75 goto err_pci_disable;
75 pci_set_master(dev); 76 pci_set_master(dev);
76 77
78 /* Disable the RETRY_TIMEOUT register (0x41) to keep
79 * PCI Tx retries from interfering with C3 CPU state */
80 pci_read_config_dword(dev, 0x40, &val);
81 if ((val & 0x0000ff00) != 0)
82 pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
83
77 err = ssb_bus_pcibus_register(ssb, dev); 84 err = ssb_bus_pcibus_register(ssb, dev);
78 if (err) 85 if (err)
79 goto err_pci_release_regions; 86 goto err_pci_release_regions;
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index ee079ab9fb28..5a0985d4ce15 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -405,10 +405,10 @@ int ssb_bus_scan(struct ssb_bus *bus,
405 /* Ignore PCI cores on PCI-E cards. 405 /* Ignore PCI cores on PCI-E cards.
406 * Ignore PCI-E cores on PCI cards. */ 406 * Ignore PCI-E cores on PCI cards. */
407 if (dev->id.coreid == SSB_DEV_PCI) { 407 if (dev->id.coreid == SSB_DEV_PCI) {
408 if (bus->host_pci->is_pcie) 408 if (pci_is_pcie(bus->host_pci))
409 continue; 409 continue;
410 } else { 410 } else {
411 if (!bus->host_pci->is_pcie) 411 if (!pci_is_pcie(bus->host_pci))
412 continue; 412 continue;
413 } 413 }
414 } 414 }