diff options
Diffstat (limited to 'drivers/net/wireless/b43/phy_common.c')
| -rw-r--r-- | drivers/net/wireless/b43/phy_common.c | 100 | 
1 files changed, 95 insertions, 5 deletions
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index f01676ac481..08244b3b327 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -96,12 +96,16 @@ int b43_phy_init(struct b43_wldev *dev)  	phy->channel = ops->get_default_chan(dev); -	ops->software_rfkill(dev, false); +	phy->ops->switch_analog(dev, true); +	b43_software_rfkill(dev, false); +  	err = ops->init(dev);  	if (err) {  		b43err(dev->wl, "PHY init failed\n");  		goto err_block_rf;  	} +	phy->do_full_init = false; +  	/* Make sure to switch hardware and firmware (SHM) to  	 * the default channel. */  	err = b43_switch_channel(dev, ops->get_default_chan(dev)); @@ -113,10 +117,11 @@ int b43_phy_init(struct b43_wldev *dev)  	return 0;  err_phy_exit: +	phy->do_full_init = true;  	if (ops->exit)  		ops->exit(dev);  err_block_rf: -	ops->software_rfkill(dev, true); +	b43_software_rfkill(dev, true);  	return err;  } @@ -125,7 +130,8 @@ void b43_phy_exit(struct b43_wldev *dev)  {  	const struct b43_phy_operations *ops = dev->phy.ops; -	ops->software_rfkill(dev, true); +	b43_software_rfkill(dev, true); +	dev->phy.do_full_init = true;  	if (ops->exit)  		ops->exit(dev);  } @@ -133,9 +139,9 @@ void b43_phy_exit(struct b43_wldev *dev)  bool b43_has_hardware_pctl(struct b43_wldev *dev)  {  	if (!dev->phy.hardware_power_control) -		return 0; +		return false;  	if (!dev->phy.ops->supports_hwpctl) -		return 0; +		return false;  	return dev->phy.ops->supports_hwpctl(dev);  } @@ -312,6 +318,90 @@ void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)  	}  } +void b43_phy_put_into_reset(struct b43_wldev *dev) +{ +	u32 tmp; + +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); +		tmp &= ~B43_BCMA_IOCTL_GMODE; +		tmp |= B43_BCMA_IOCTL_PHY_RESET; +		tmp |= BCMA_IOCTL_FGC; +		bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); +		udelay(1); + +		tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); +		tmp &= ~BCMA_IOCTL_FGC; +		bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); +		udelay(1); +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); +		tmp &= ~B43_TMSLOW_GMODE; +		tmp |= B43_TMSLOW_PHYRESET; +		tmp |= SSB_TMSLOW_FGC; +		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); +		usleep_range(1000, 2000); + +		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); +		tmp &= ~SSB_TMSLOW_FGC; +		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); +		usleep_range(1000, 2000); + +		break; +#endif +	} +} + +void b43_phy_take_out_of_reset(struct b43_wldev *dev) +{ +	u32 tmp; + +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		/* Unset reset bit (with forcing clock) */ +		tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); +		tmp &= ~B43_BCMA_IOCTL_PHY_RESET; +		tmp &= ~B43_BCMA_IOCTL_PHY_CLKEN; +		tmp |= BCMA_IOCTL_FGC; +		bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); +		udelay(1); + +		/* Do not force clock anymore */ +		tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); +		tmp &= ~BCMA_IOCTL_FGC; +		tmp |= B43_BCMA_IOCTL_PHY_CLKEN; +		bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); +		udelay(1); +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		/* Unset reset bit (with forcing clock) */ +		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); +		tmp &= ~B43_TMSLOW_PHYRESET; +		tmp &= ~B43_TMSLOW_PHYCLKEN; +		tmp |= SSB_TMSLOW_FGC; +		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); +		ssb_read32(dev->dev->sdev, SSB_TMSLOW); /* flush */ +		usleep_range(1000, 2000); + +		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); +		tmp &= ~SSB_TMSLOW_FGC; +		tmp |= B43_TMSLOW_PHYCLKEN; +		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); +		ssb_read32(dev->dev->sdev, SSB_TMSLOW); /* flush */ +		usleep_range(1000, 2000); +		break; +#endif +	} +} +  int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)  {  	struct b43_phy *phy = &(dev->phy);  | 
