aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-09-02 13:00:34 +0200
committerJohn W. Linville <linville@tuxdriver.com>2008-09-05 16:17:49 -0400
commitfb11137af83b7b66c7aab8dbc5f09d2c95684fed (patch)
tree08251ad486eb4c115f56ee4ddfb56a80c2d7c287 /drivers/net/wireless/b43/main.c
parent7cb770729ba895f73253dfcd46c3fcba45d896f9 (diff)
b43: Split PHY alloc and init
This splits the PHY allocation from the PHY init. This is needed in order to properly support Analog handling. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index fda9492d588..156e8f3151d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1091,8 +1091,12 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
ssb_read32(dev->dev, SSB_TMSLOW); /* flush */
msleep(1);
- /* Turn Analog ON */
- b43_switch_analog(dev, 1);
+ /* Turn Analog ON, but only if we already know the PHY-type.
+ * This protects against very early setup where we don't know the
+ * PHY-type, yet. wireless_core_reset will be called once again later,
+ * when we know the PHY-type. */
+ if (dev->phy.ops)
+ b43_switch_analog(dev, 1);
macctl = b43_read32(dev, B43_MMIO_MACCTL);
macctl &= ~B43_MACCTL_GMODE;
@@ -2694,6 +2698,7 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
/* This is the opposite of b43_chip_init() */
static void b43_chip_exit(struct b43_wldev *dev)
{
+ b43_phy_exit(dev);
b43_gpio_cleanup(dev);
/* firmware is released later */
}
@@ -3952,7 +3957,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
dev_kfree_skb_any(dev->wl->current_beacon);
dev->wl->current_beacon = NULL;
}
- b43_phy_exit(dev);
ssb_device_disable(dev->dev, 0);
ssb_bus_may_powerdown(dev->dev->bus);
@@ -3979,24 +3983,23 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
b43_wireless_core_reset(dev, tmp);
}
+ /* Reset all data structures. */
setup_struct_wldev_for_init(dev);
- err = b43_phy_operations_setup(dev);
- if (err)
- goto err_busdown;
+ phy->ops->prepare_structs(dev);
/* Enable IRQ routing to this device. */
ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
b43_imcfglo_timeouts_workaround(dev);
b43_bluetooth_coext_disable(dev);
- if (phy->ops->prepare) {
- err = phy->ops->prepare(dev);
+ if (phy->ops->prepare_hardware) {
+ err = phy->ops->prepare_hardware(dev);
if (err)
- goto err_phy_exit;
+ goto err_busdown;
}
err = b43_chip_init(dev);
if (err)
- goto err_phy_exit;
+ goto err_busdown;
b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_WLCOREREV, dev->dev->id.revision);
hf = b43_hf_read(dev);
@@ -4064,8 +4067,6 @@ out:
err_chip_exit:
b43_chip_exit(dev);
-err_phy_exit:
- b43_phy_exit(dev);
err_busdown:
ssb_bus_may_powerdown(bus);
B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
@@ -4342,6 +4343,7 @@ static void b43_wireless_core_detach(struct b43_wldev *dev)
/* We release firmware that late to not be required to re-request
* is all the time when we reinit the core. */
b43_release_firmware(dev);
+ b43_phy_free(dev);
}
static int b43_wireless_core_attach(struct b43_wldev *dev)
@@ -4415,16 +4417,20 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
}
}
+ err = b43_phy_allocate(dev);
+ if (err)
+ goto err_powerdown;
+
dev->phy.gmode = have_2ghz_phy;
tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
b43_wireless_core_reset(dev, tmp);
err = b43_validate_chipaccess(dev);
if (err)
- goto err_powerdown;
+ goto err_phy_free;
err = b43_setup_bands(dev, have_2ghz_phy, have_5ghz_phy);
if (err)
- goto err_powerdown;
+ goto err_phy_free;
/* Now set some default "current_dev" */
if (!wl->current_dev)
@@ -4438,6 +4444,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
out:
return err;
+err_phy_free:
+ b43_phy_free(dev);
err_powerdown:
ssb_bus_may_powerdown(bus);
return err;