|
@@ -5079,10 +5079,50 @@ static void b43_wireless_core_detach(struct b43_wldev *dev)
|
|
|
b43_phy_free(dev);
|
|
|
}
|
|
|
|
|
|
+static void b43_supported_bands(struct b43_wldev *dev, bool *have_2ghz_phy,
|
|
|
+ bool *have_5ghz_phy)
|
|
|
+{
|
|
|
+ u16 dev_id = 0;
|
|
|
+
|
|
|
+#ifdef CONFIG_B43_SSB
|
|
|
+ if (dev->dev->bus_type == B43_BUS_SSB &&
|
|
|
+ dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI)
|
|
|
+ dev_id = dev->dev->sdev->bus->host_pci->device;
|
|
|
+#endif
|
|
|
+
|
|
|
+ /* Note: below IDs can be "virtual" (not maching e.g. real PCI ID) */
|
|
|
+ switch (dev_id) {
|
|
|
+ case 0x4324: /* BCM4306 */
|
|
|
+ case 0x4312: /* BCM4311 */
|
|
|
+ case 0x4319: /* BCM4318 */
|
|
|
+ /* Dual band devices */
|
|
|
+ *have_2ghz_phy = true;
|
|
|
+ *have_5ghz_phy = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* As a fallback, try to guess using PHY type */
|
|
|
+ switch (dev->phy.type) {
|
|
|
+ case B43_PHYTYPE_A:
|
|
|
+ *have_2ghz_phy = false;
|
|
|
+ *have_5ghz_phy = true;
|
|
|
+ return;
|
|
|
+ case B43_PHYTYPE_G:
|
|
|
+ case B43_PHYTYPE_N:
|
|
|
+ case B43_PHYTYPE_LP:
|
|
|
+ case B43_PHYTYPE_HT:
|
|
|
+ case B43_PHYTYPE_LCN:
|
|
|
+ *have_2ghz_phy = true;
|
|
|
+ *have_5ghz_phy = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ B43_WARN_ON(1);
|
|
|
+}
|
|
|
+
|
|
|
static int b43_wireless_core_attach(struct b43_wldev *dev)
|
|
|
{
|
|
|
struct b43_wl *wl = dev->wl;
|
|
|
- struct pci_dev *pdev = NULL;
|
|
|
int err;
|
|
|
u32 tmp;
|
|
|
bool have_2ghz_phy = false, have_5ghz_phy = false;
|
|
@@ -5094,19 +5134,13 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
|
|
* that in core_init(), too.
|
|
|
*/
|
|
|
|
|
|
-#ifdef CONFIG_B43_SSB
|
|
|
- if (dev->dev->bus_type == B43_BUS_SSB &&
|
|
|
- dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI)
|
|
|
- pdev = dev->dev->sdev->bus->host_pci;
|
|
|
-#endif
|
|
|
-
|
|
|
err = b43_bus_powerup(dev, 0);
|
|
|
if (err) {
|
|
|
b43err(wl, "Bus powerup failed\n");
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- /* Get the PHY type. */
|
|
|
+ /* Try to guess supported bands for the first init needs */
|
|
|
switch (dev->dev->bus_type) {
|
|
|
#ifdef CONFIG_B43_BCMA
|
|
|
case B43_BUS_BCMA:
|
|
@@ -5130,48 +5164,28 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
|
|
dev->phy.gmode = have_2ghz_phy;
|
|
|
b43_wireless_core_reset(dev, dev->phy.gmode);
|
|
|
|
|
|
+ /* Get the PHY type. */
|
|
|
err = b43_phy_versioning(dev);
|
|
|
if (err)
|
|
|
goto err_powerdown;
|
|
|
- /* Check if this device supports multiband. */
|
|
|
- if (!pdev ||
|
|
|
- (pdev->device != 0x4312 &&
|
|
|
- pdev->device != 0x4319 && pdev->device != 0x4324)) {
|
|
|
- /* No multiband support. */
|
|
|
- have_2ghz_phy = false;
|
|
|
+
|
|
|
+ /* Get real info about supported bands */
|
|
|
+ b43_supported_bands(dev, &have_2ghz_phy, &have_5ghz_phy);
|
|
|
+
|
|
|
+ /* We don't support 5 GHz on some PHYs yet */
|
|
|
+ switch (dev->phy.type) {
|
|
|
+ case B43_PHYTYPE_A:
|
|
|
+ case B43_PHYTYPE_N:
|
|
|
+ case B43_PHYTYPE_LP:
|
|
|
+ b43warn(wl, "5 GHz band is unsupported on this PHY\n");
|
|
|
have_5ghz_phy = false;
|
|
|
- switch (dev->phy.type) {
|
|
|
- case B43_PHYTYPE_A:
|
|
|
- have_5ghz_phy = true;
|
|
|
- break;
|
|
|
- case B43_PHYTYPE_LP: //FIXME not always!
|
|
|
-#if 0 //FIXME enabling 5GHz causes a NULL pointer dereference
|
|
|
- have_5ghz_phy = 1;
|
|
|
-#endif
|
|
|
- case B43_PHYTYPE_G:
|
|
|
- case B43_PHYTYPE_N:
|
|
|
- case B43_PHYTYPE_HT:
|
|
|
- case B43_PHYTYPE_LCN:
|
|
|
- have_2ghz_phy = true;
|
|
|
- break;
|
|
|
- default:
|
|
|
- B43_WARN_ON(1);
|
|
|
- }
|
|
|
}
|
|
|
- if (dev->phy.type == B43_PHYTYPE_A) {
|
|
|
- /* FIXME */
|
|
|
- b43err(wl, "IEEE 802.11a devices are unsupported\n");
|
|
|
+
|
|
|
+ if (!have_2ghz_phy && !have_5ghz_phy) {
|
|
|
+ b43err(wl, "b43 can't support any band on this device\n");
|
|
|
err = -EOPNOTSUPP;
|
|
|
goto err_powerdown;
|
|
|
}
|
|
|
- if (1 /* disable A-PHY */) {
|
|
|
- /* FIXME: For now we disable the A-PHY on multi-PHY devices. */
|
|
|
- if (dev->phy.type != B43_PHYTYPE_N &&
|
|
|
- dev->phy.type != B43_PHYTYPE_LP) {
|
|
|
- have_2ghz_phy = true;
|
|
|
- have_5ghz_phy = false;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
err = b43_phy_allocate(dev);
|
|
|
if (err)
|