|
@@ -130,6 +130,10 @@ MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging.");
|
|
|
{ PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
|
|
/* Broadcom 4307 802.11b */
|
|
|
{ PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
|
|
+ /* Broadcom 4311 802.11(a)/b/g */
|
|
|
+ { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
|
|
+ /* Broadcom 4312 802.11a/b/g */
|
|
|
+ { PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
|
|
/* Broadcom 4318 802.11b/g */
|
|
|
{ PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
|
|
/* Broadcom 4319 802.11a/b/g */
|
|
@@ -2600,8 +2604,9 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
|
|
|
/* fetch sb_id_hi from core information registers */
|
|
|
sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
|
|
|
|
|
|
- core_id = (sb_id_hi & 0xFFF0) >> 4;
|
|
|
- core_rev = (sb_id_hi & 0xF);
|
|
|
+ core_id = (sb_id_hi & 0x8FF0) >> 4;
|
|
|
+ core_rev = (sb_id_hi & 0x7000) >> 8;
|
|
|
+ core_rev |= (sb_id_hi & 0xF);
|
|
|
core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
|
|
|
|
|
|
/* if present, chipcommon is always core 0; read the chipid from it */
|
|
@@ -2711,6 +2716,7 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
|
|
|
core = NULL;
|
|
|
switch (core_id) {
|
|
|
case BCM43xx_COREID_PCI:
|
|
|
+ case BCM43xx_COREID_PCIE:
|
|
|
core = &bcm->core_pci;
|
|
|
if (core->available) {
|
|
|
printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
|
|
@@ -2749,12 +2755,12 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
|
|
|
case 6:
|
|
|
case 7:
|
|
|
case 9:
|
|
|
+ case 10:
|
|
|
break;
|
|
|
default:
|
|
|
- printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n",
|
|
|
+ printk(KERN_WARNING PFX
|
|
|
+ "Unsupported 80211 core revision %u\n",
|
|
|
core_rev);
|
|
|
- err = -ENODEV;
|
|
|
- goto out;
|
|
|
}
|
|
|
bcm->nr_80211_available++;
|
|
|
core->priv = ext_80211;
|
|
@@ -2868,16 +2874,11 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
|
|
|
u32 sbimconfiglow;
|
|
|
u8 limit;
|
|
|
|
|
|
- if (bcm->chip_rev < 5) {
|
|
|
+ if (bcm->core_pci.rev <= 5 && bcm->core_pci.id != BCM43xx_COREID_PCIE) {
|
|
|
sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
|
|
|
sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
|
|
|
sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
|
|
|
- if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
|
|
|
- sbimconfiglow |= 0x32;
|
|
|
- else if (bcm->bustype == BCM43xx_BUSTYPE_SB)
|
|
|
- sbimconfiglow |= 0x53;
|
|
|
- else
|
|
|
- assert(0);
|
|
|
+ sbimconfiglow |= 0x32;
|
|
|
bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
|
|
|
}
|
|
|
|
|
@@ -3004,22 +3005,64 @@ static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm,
|
|
|
|
|
|
static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
|
|
|
{
|
|
|
- int err;
|
|
|
- struct bcm43xx_coreinfo *old_core;
|
|
|
+ int err = 0;
|
|
|
|
|
|
- old_core = bcm->current_core;
|
|
|
- err = bcm43xx_switch_core(bcm, &bcm->core_pci);
|
|
|
- if (err)
|
|
|
- goto out;
|
|
|
+ bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
|
|
|
|
|
|
- bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
|
|
|
+ if (bcm->core_chipcommon.available) {
|
|
|
+ err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
|
|
|
+
|
|
|
+ /* this function is always called when a PCI core is mapped */
|
|
|
+ err = bcm43xx_switch_core(bcm, &bcm->core_pci);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+ } else
|
|
|
+ bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
|
|
|
+
|
|
|
+ bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
|
|
|
|
|
|
- bcm43xx_switch_core(bcm, old_core);
|
|
|
- assert(err == 0);
|
|
|
out:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+static u32 bcm43xx_pcie_reg_read(struct bcm43xx_private *bcm, u32 address)
|
|
|
+{
|
|
|
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
|
|
|
+ return bcm43xx_read32(bcm, BCM43xx_PCIECORE_REG_DATA);
|
|
|
+}
|
|
|
+
|
|
|
+static void bcm43xx_pcie_reg_write(struct bcm43xx_private *bcm, u32 address,
|
|
|
+ u32 data)
|
|
|
+{
|
|
|
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
|
|
|
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_DATA, data);
|
|
|
+}
|
|
|
+
|
|
|
+static void bcm43xx_pcie_mdio_write(struct bcm43xx_private *bcm, u8 dev, u8 reg,
|
|
|
+ u16 data)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0x0082);
|
|
|
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_DATA, BCM43xx_PCIE_MDIO_ST |
|
|
|
+ BCM43xx_PCIE_MDIO_WT | (dev << BCM43xx_PCIE_MDIO_DEV) |
|
|
|
+ (reg << BCM43xx_PCIE_MDIO_REG) | BCM43xx_PCIE_MDIO_TA |
|
|
|
+ data);
|
|
|
+ udelay(10);
|
|
|
+
|
|
|
+ for (i = 0; i < 10; i++) {
|
|
|
+ if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) &
|
|
|
+ BCM43xx_PCIE_MDIO_TC)
|
|
|
+ break;
|
|
|
+ msleep(1);
|
|
|
+ }
|
|
|
+ bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0);
|
|
|
+}
|
|
|
+
|
|
|
/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
|
|
|
* To enable core 0, pass a core_mask of 1<<0
|
|
|
*/
|
|
@@ -3039,7 +3082,8 @@ static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
|
|
|
if (err)
|
|
|
goto out;
|
|
|
|
|
|
- if (bcm->core_pci.rev < 6) {
|
|
|
+ if (bcm->current_core->rev < 6 ||
|
|
|
+ bcm->current_core->id == BCM43xx_COREID_PCI) {
|
|
|
value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
|
|
|
value |= (1 << backplane_flag_nr);
|
|
|
bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
|
|
@@ -3057,21 +3101,46 @@ static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
|
|
|
- value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
|
|
|
- bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
|
|
|
-
|
|
|
- if (bcm->core_pci.rev < 5) {
|
|
|
- value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
|
|
|
- value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
|
|
|
- & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
|
|
|
- value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
|
|
|
- & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
|
|
|
- bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
|
|
|
- err = bcm43xx_pcicore_commit_settings(bcm);
|
|
|
- assert(err == 0);
|
|
|
+ if (bcm->current_core->id == BCM43xx_COREID_PCI) {
|
|
|
+ value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
|
|
|
+ value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
|
|
|
+ bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
|
|
|
+
|
|
|
+ if (bcm->current_core->rev < 5) {
|
|
|
+ value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
|
|
|
+ value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
|
|
|
+ & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
|
|
|
+ value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
|
|
|
+ & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
|
|
|
+ bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
|
|
|
+ err = bcm43xx_pcicore_commit_settings(bcm);
|
|
|
+ assert(err == 0);
|
|
|
+ } else if (bcm->current_core->rev >= 11) {
|
|
|
+ value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
|
|
|
+ value |= BCM43xx_SBTOPCI2_MEMREAD_MULTI;
|
|
|
+ bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (bcm->current_core->rev == 0 || bcm->current_core->rev == 1) {
|
|
|
+ value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_TLP_WORKAROUND);
|
|
|
+ value |= 0x8;
|
|
|
+ bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_TLP_WORKAROUND,
|
|
|
+ value);
|
|
|
+ }
|
|
|
+ if (bcm->current_core->rev == 0) {
|
|
|
+ bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
|
|
|
+ BCM43xx_SERDES_RXTIMER, 0x8128);
|
|
|
+ bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
|
|
|
+ BCM43xx_SERDES_CDR, 0x0100);
|
|
|
+ bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
|
|
|
+ BCM43xx_SERDES_CDR_BW, 0x1466);
|
|
|
+ } else if (bcm->current_core->rev == 1) {
|
|
|
+ value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_DLLP_LINKCTL);
|
|
|
+ value |= 0x40;
|
|
|
+ bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_DLLP_LINKCTL,
|
|
|
+ value);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
out_switch_back:
|
|
|
err = bcm43xx_switch_core(bcm, old_core);
|
|
|
out:
|
|
@@ -3676,7 +3745,7 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
|
|
|
bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
|
|
|
break;
|
|
|
case BCM43xx_PHYTYPE_G:
|
|
|
- if (phy_rev > 7)
|
|
|
+ if (phy_rev > 8)
|
|
|
phy_rev_ok = 0;
|
|
|
bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
|
|
|
IEEE80211_CCK_MODULATION;
|