diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 14:43:13 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 14:43:13 -0700 | 
| commit | 951cc93a7493a81a47e20231441bc6cf17c98a37 (patch) | |
| tree | f53934f0f225e0215a85c8c59af4c6513e89e3f1 /drivers/net/wireless/b43/main.c | |
| parent | a7e1aabb28e8154ce987b622fd78d80a1ca39361 (diff) | |
| parent | 415b3334a21aa67806c52d1acf4e72e14f7f402f (diff) | |
| download | olio-linux-3.10-951cc93a7493a81a47e20231441bc6cf17c98a37.tar.xz olio-linux-3.10-951cc93a7493a81a47e20231441bc6cf17c98a37.zip  | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1287 commits)
  icmp: Fix regression in nexthop resolution during replies.
  net: Fix ppc64 BPF JIT dependencies.
  acenic: include NET_SKB_PAD headroom to incoming skbs
  ixgbe: convert to ndo_fix_features
  ixgbe: only enable WoL for magic packet by default
  ixgbe: remove ifdef check for non-existent define
  ixgbe: Pass staterr instead of re-reading status and error bits from descriptor
  ixgbe: Move interrupt related values out of ring and into q_vector
  ixgbe: add structure for containing RX/TX rings to q_vector
  ixgbe: inline the ixgbe_maybe_stop_tx function
  ixgbe: Update ATR to use recorded TX queues instead of CPU for routing
  igb: Fix for DH89xxCC near end loopback test
  e1000: always call e1000_check_for_link() on e1000_ce4100 MACs.
  netxen: add fw version compatibility check
  be2net: request native mode each time the card is reset
  ipv4: Constrain UFO fragment sizes to multiples of 8 bytes
  virtio_net: Fix panic in virtnet_remove
  ipv6: make fragment identifications less predictable
  ipv6: unshare inetpeers
  can: make function can_get_bittiming static
  ...
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
| -rw-r--r-- | drivers/net/wireless/b43/main.c | 610 | 
1 files changed, 444 insertions, 166 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index eb415968698..092dd931886 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -113,6 +113,17 @@ static int b43_modparam_pio = B43_PIO_DEFAULT;  module_param_named(pio, b43_modparam_pio, int, 0644);  MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); +#ifdef CONFIG_B43_BCMA +static const struct bcma_device_id b43_bcma_tbl[] = { +	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), +	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), +	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), +	BCMA_CORETABLE_END +}; +MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); +#endif + +#ifdef CONFIG_B43_SSB  static const struct ssb_device_id b43_ssb_tbl[] = {  	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),  	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), @@ -126,8 +137,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = {  	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),  	SSB_DEVTABLE_END  }; -  MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); +#endif  /* Channel and ratetables are shared for all devices.   * They can't be const, because ieee80211 puts some precalculated @@ -548,7 +559,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)  {  	u32 low, high; -	B43_WARN_ON(dev->sdev->id.revision < 3); +	B43_WARN_ON(dev->dev->core_rev < 3);  	/* The hardware guarantees us an atomic read, if we  	 * read the low register first. */ @@ -586,7 +597,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf)  {  	u32 low, high; -	B43_WARN_ON(dev->sdev->id.revision < 3); +	B43_WARN_ON(dev->dev->core_rev < 3);  	low = tsf;  	high = (tsf >> 32); @@ -714,7 +725,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)  		b43_ram_write(dev, i * 4, buffer[i]);  	b43_write16(dev, 0x0568, 0x0000); -	if (dev->sdev->id.revision < 11) +	if (dev->dev->core_rev < 11)  		b43_write16(dev, 0x07C0, 0x0000);  	else  		b43_write16(dev, 0x07C0, 0x0100); @@ -1132,7 +1143,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)  	b43_write32(dev, B43_MMIO_MACCTL, macctl);  	/* Commit write */  	b43_read32(dev, B43_MMIO_MACCTL); -	if (awake && dev->sdev->id.revision >= 5) { +	if (awake && dev->dev->core_rev >= 5) {  		/* Wait for the microcode to wake up. */  		for (i = 0; i < 100; i++) {  			ucstat = b43_shm_read16(dev, B43_SHM_SHARED, @@ -1144,35 +1155,65 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)  	}  } -static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) +#ifdef CONFIG_B43_BCMA +static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode) +{ +	u32 flags = 0; + +	if (gmode) +		flags = B43_BCMA_IOCTL_GMODE; +	flags |= B43_BCMA_IOCTL_PHY_CLKEN; +	flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ; /* Make 20 MHz def */ +	b43_device_enable(dev, flags); + +	/* TODO: reset PHY */ +} +#endif + +static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode)  { +	struct ssb_device *sdev = dev->dev->sdev;  	u32 tmslow; +	u32 flags = 0; +	if (gmode) +		flags |= B43_TMSLOW_GMODE;  	flags |= B43_TMSLOW_PHYCLKEN;  	flags |= B43_TMSLOW_PHYRESET;  	if (dev->phy.type == B43_PHYTYPE_N)  		flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ -	ssb_device_enable(dev->sdev, flags); +	b43_device_enable(dev, flags);  	msleep(2);		/* Wait for the PLL to turn on. */  	/* Now take the PHY out of Reset again */ -	tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); +	tmslow = ssb_read32(sdev, SSB_TMSLOW);  	tmslow |= SSB_TMSLOW_FGC;  	tmslow &= ~B43_TMSLOW_PHYRESET; -	ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); -	ssb_read32(dev->sdev, SSB_TMSLOW);	/* flush */ +	ssb_write32(sdev, SSB_TMSLOW, tmslow); +	ssb_read32(sdev, SSB_TMSLOW);	/* flush */  	msleep(1);  	tmslow &= ~SSB_TMSLOW_FGC; -	ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); -	ssb_read32(dev->sdev, SSB_TMSLOW);	/* flush */ +	ssb_write32(sdev, SSB_TMSLOW, tmslow); +	ssb_read32(sdev, SSB_TMSLOW);	/* flush */  	msleep(1);  } -void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) +void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode)  {  	u32 macctl; -	b43_ssb_wireless_core_reset(dev, flags); +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		b43_bcma_wireless_core_reset(dev, gmode); +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		b43_ssb_wireless_core_reset(dev, gmode); +		break; +#endif +	}  	/* Turn Analog ON, but only if we already know the PHY-type.  	 * This protects against very early setup where we don't know the @@ -1183,7 +1224,7 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)  	macctl = b43_read32(dev, B43_MMIO_MACCTL);  	macctl &= ~B43_MACCTL_GMODE; -	if (flags & B43_TMSLOW_GMODE) +	if (gmode)  		macctl |= B43_MACCTL_GMODE;  	macctl |= B43_MACCTL_IHR_ENABLED;  	b43_write32(dev, B43_MMIO_MACCTL, macctl); @@ -1221,7 +1262,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev)  {  	u32 dummy; -	if (dev->sdev->id.revision < 5) +	if (dev->dev->core_rev < 5)  		return;  	/* Read all entries from the microcode TXstatus FIFO  	 * and throw them away. @@ -1427,9 +1468,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,  	/* Get the mask of available antennas. */  	if (dev->phy.gmode) -		antenna_mask = dev->sdev->bus->sprom.ant_available_bg; +		antenna_mask = dev->dev->bus_sprom->ant_available_bg;  	else -		antenna_mask = dev->sdev->bus->sprom.ant_available_a; +		antenna_mask = dev->dev->bus_sprom->ant_available_a;  	if (!(antenna_mask & (1 << (antenna_nr - 1)))) {  		/* This antenna is not available. Fall back to default. */ @@ -1644,7 +1685,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)  	mutex_lock(&wl->mutex);  	dev = wl->current_dev;  	if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { -		if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { +		if (b43_bus_host_is_sdio(dev->dev)) {  			/* wl->mutex is enough. */  			b43_do_beacon_update_trigger_work(dev);  			mmiowb(); @@ -1689,7 +1730,7 @@ static void b43_update_templates(struct b43_wl *wl)  static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)  {  	b43_time_lock(dev); -	if (dev->sdev->id.revision >= 3) { +	if (dev->dev->core_rev >= 3) {  		b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16));  		b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10));  	} else { @@ -1923,7 +1964,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev)  		return IRQ_NONE;  	reason &= dev->irq_mask;  	if (!reason) -		return IRQ_HANDLED; +		return IRQ_NONE;  	dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)  	    & 0x0001DC00; @@ -2063,7 +2104,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,  		B43_WARN_ON(1);  		return -ENOSYS;  	} -	err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev); +	err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);  	if (err == -ENOENT) {  		snprintf(ctx->errors[ctx->req_type],  			 sizeof(ctx->errors[ctx->req_type]), @@ -2113,26 +2154,48 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)  {  	struct b43_wldev *dev = ctx->dev;  	struct b43_firmware *fw = &ctx->dev->fw; -	const u8 rev = ctx->dev->sdev->id.revision; +	const u8 rev = ctx->dev->dev->core_rev;  	const char *filename;  	u32 tmshigh;  	int err; +	/* Files for HT and LCN were found by trying one by one */ +  	/* Get microcode */ -	if ((rev >= 5) && (rev <= 10)) +	if ((rev >= 5) && (rev <= 10)) {  		filename = "ucode5"; -	else if ((rev >= 11) && (rev <= 12)) +	} else if ((rev >= 11) && (rev <= 12)) {  		filename = "ucode11"; -	else if (rev == 13) +	} else if (rev == 13) {  		filename = "ucode13"; -	else if (rev == 14) +	} else if (rev == 14) {  		filename = "ucode14"; -	else if (rev == 15) +	} else if (rev == 15) {  		filename = "ucode15"; -	else if ((rev >= 16) && (rev <= 20)) -		filename = "ucode16_mimo"; -	else -		goto err_no_ucode; +	} else { +		switch (dev->phy.type) { +		case B43_PHYTYPE_N: +			if (rev >= 16) +				filename = "ucode16_mimo"; +			else +				goto err_no_ucode; +			break; +		case B43_PHYTYPE_HT: +			if (rev == 29) +				filename = "ucode29_mimo"; +			else +				goto err_no_ucode; +			break; +		case B43_PHYTYPE_LCN: +			if (rev == 24) +				filename = "ucode24_mimo"; +			else +				goto err_no_ucode; +			break; +		default: +			goto err_no_ucode; +		} +	}  	err = b43_do_request_fw(ctx, filename, &fw->ucode);  	if (err)  		goto err_load; @@ -2157,7 +2220,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)  	switch (dev->phy.type) {  	case B43_PHYTYPE_A:  		if ((rev >= 5) && (rev <= 10)) { -			tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); +			tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);  			if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)  				filename = "a0g1initvals5";  			else @@ -2191,6 +2254,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)  		else  			goto err_no_initvals;  		break; +	case B43_PHYTYPE_HT: +		if (rev == 29) +			filename = "ht0initvals29"; +		else +			goto err_no_initvals; +		break; +	case B43_PHYTYPE_LCN: +		if (rev == 24) +			filename = "lcn0initvals24"; +		else +			goto err_no_initvals; +		break;  	default:  		goto err_no_initvals;  	} @@ -2202,7 +2277,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)  	switch (dev->phy.type) {  	case B43_PHYTYPE_A:  		if ((rev >= 5) && (rev <= 10)) { -			tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); +			tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);  			if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)  				filename = "a0g1bsinitvals5";  			else @@ -2238,6 +2313,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)  		else  			goto err_no_initvals;  		break; +	case B43_PHYTYPE_HT: +		if (rev == 29) +			filename = "ht0bsinitvals29"; +		else +			goto err_no_initvals; +		break; +	case B43_PHYTYPE_LCN: +		if (rev == 24) +			filename = "lcn0bsinitvals24"; +		else +			goto err_no_initvals; +		break;  	default:  		goto err_no_initvals;  	} @@ -2448,7 +2535,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)  	snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",  			dev->fw.rev, dev->fw.patch); -	wiphy->hw_version = dev->sdev->id.coreid; +	wiphy->hw_version = dev->dev->core_id;  	if (b43_is_old_txhdr_format(dev)) {  		/* We're over the deadline, but we keep support for old fw @@ -2566,7 +2653,7 @@ out:   */  static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev)  { -	struct ssb_bus *bus = dev->sdev->bus; +	struct ssb_bus *bus = dev->dev->sdev->bus;  #ifdef CONFIG_SSB_DRIVER_PCICORE  	return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); @@ -2588,7 +2675,7 @@ static int b43_gpio_init(struct b43_wldev *dev)  	mask = 0x0000001F;  	set = 0x0000000F; -	if (dev->sdev->bus->chip_id == 0x4301) { +	if (dev->dev->chip_id == 0x4301) {  		mask |= 0x0060;  		set |= 0x0060;  	} @@ -2599,21 +2686,34 @@ static int b43_gpio_init(struct b43_wldev *dev)  		mask |= 0x0180;  		set |= 0x0180;  	} -	if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { +	if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) {  		b43_write16(dev, B43_MMIO_GPIO_MASK,  			    b43_read16(dev, B43_MMIO_GPIO_MASK)  			    | 0x0200);  		mask |= 0x0200;  		set |= 0x0200;  	} -	if (dev->sdev->id.revision >= 2) +	if (dev->dev->core_rev >= 2)  		mask |= 0x0010;	/* FIXME: This is redundant. */ -	gpiodev = b43_ssb_gpio_dev(dev); -	if (gpiodev) -		ssb_write32(gpiodev, B43_GPIO_CONTROL, -			    (ssb_read32(gpiodev, B43_GPIO_CONTROL) -			     & mask) | set); +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, +				(bcma_cc_read32(&dev->dev->bdev->bus->drv_cc, +					BCMA_CC_GPIOCTL) & mask) | set); +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		gpiodev = b43_ssb_gpio_dev(dev); +		if (gpiodev) +			ssb_write32(gpiodev, B43_GPIO_CONTROL, +				    (ssb_read32(gpiodev, B43_GPIO_CONTROL) +				    & mask) | set); +		break; +#endif +	}  	return 0;  } @@ -2623,9 +2723,21 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)  {  	struct ssb_device *gpiodev; -	gpiodev = b43_ssb_gpio_dev(dev); -	if (gpiodev) -		ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, +				0); +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		gpiodev = b43_ssb_gpio_dev(dev); +		if (gpiodev) +			ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); +		break; +#endif +	}  }  /* http://bcm-specs.sipsolutions.net/EnableMac */ @@ -2697,12 +2809,30 @@ out:  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */  void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)  { -	u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); -	if (on) -		tmslow |= B43_TMSLOW_MACPHYCLKEN; -	else -		tmslow &= ~B43_TMSLOW_MACPHYCLKEN; -	ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); +	u32 tmp; + +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL); +		if (on) +			tmp |= B43_BCMA_IOCTL_MACPHYCLKEN; +		else +			tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN; +		bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp); +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); +		if (on) +			tmp |= B43_TMSLOW_MACPHYCLKEN; +		else +			tmp &= ~B43_TMSLOW_MACPHYCLKEN; +		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); +		break; +#endif +	}  }  static void b43_adjust_opmode(struct b43_wldev *dev) @@ -2741,15 +2871,15 @@ static void b43_adjust_opmode(struct b43_wldev *dev)  	/* Workaround: On old hardware the HW-MAC-address-filter  	 * doesn't work properly, so always run promisc in filter  	 * it in software. */ -	if (dev->sdev->id.revision <= 4) +	if (dev->dev->core_rev <= 4)  		ctl |= B43_MACCTL_PROMISC;  	b43_write32(dev, B43_MMIO_MACCTL, ctl);  	cfp_pretbtt = 2;  	if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { -		if (dev->sdev->bus->chip_id == 0x4306 && -		    dev->sdev->bus->chip_rev == 3) +		if (dev->dev->chip_id == 0x4306 && +		    dev->dev->chip_rev == 3)  			cfp_pretbtt = 100;  		else  			cfp_pretbtt = 50; @@ -2907,7 +3037,7 @@ static int b43_chip_init(struct b43_wldev *dev)  		b43_write16(dev, 0x005E, value16);  	}  	b43_write32(dev, 0x0100, 0x01000000); -	if (dev->sdev->id.revision < 5) +	if (dev->dev->core_rev < 5)  		b43_write32(dev, 0x010C, 0x01000000);  	b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) @@ -2922,7 +3052,7 @@ static int b43_chip_init(struct b43_wldev *dev)  	/* Initially set the wireless operation mode. */  	b43_adjust_opmode(dev); -	if (dev->sdev->id.revision < 3) { +	if (dev->dev->core_rev < 3) {  		b43_write16(dev, 0x060E, 0x0000);  		b43_write16(dev, 0x0610, 0x8000);  		b43_write16(dev, 0x0604, 0x0000); @@ -2941,8 +3071,20 @@ static int b43_chip_init(struct b43_wldev *dev)  	b43_mac_phy_clock_set(dev, true); -	b43_write16(dev, B43_MMIO_POWERUP_DELAY, -		    dev->sdev->bus->chipco.fast_pwrup_delay); +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		/* FIXME: 0xE74 is quite common, but should be read from CC */ +		b43_write16(dev, B43_MMIO_POWERUP_DELAY, 0xE74); +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		b43_write16(dev, B43_MMIO_POWERUP_DELAY, +			    dev->dev->sdev->bus->chipco.fast_pwrup_delay); +		break; +#endif +	}  	err = 0;  	b43dbg(dev->wl, "Chip initialized\n"); @@ -3105,7 +3247,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev)  	b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0);  	b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); -	if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) { +	if ((dev->dev->core_rev >= 3) && (dev->dev->core_rev <= 10)) {  		/* The 32bit register shadows the two 16bit registers  		 * with update sideeffects. Validate this. */  		b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); @@ -3458,21 +3600,33 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)  static void b43_put_phy_into_reset(struct b43_wldev *dev)  { -	struct ssb_device *sdev = dev->sdev; -	u32 tmslow; +	u32 tmp; -	tmslow = ssb_read32(sdev, SSB_TMSLOW); -	tmslow &= ~B43_TMSLOW_GMODE; -	tmslow |= B43_TMSLOW_PHYRESET; -	tmslow |= SSB_TMSLOW_FGC; -	ssb_write32(sdev, SSB_TMSLOW, tmslow); -	msleep(1); +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		b43err(dev->wl, +		       "Putting PHY into reset not supported on BCMA\n"); +		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); +		msleep(1); -	tmslow = ssb_read32(sdev, SSB_TMSLOW); -	tmslow &= ~SSB_TMSLOW_FGC; -	tmslow |= B43_TMSLOW_PHYRESET; -	ssb_write32(sdev, SSB_TMSLOW, tmslow); -	msleep(1); +		tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); +		tmp &= ~SSB_TMSLOW_FGC; +		tmp |= B43_TMSLOW_PHYRESET; +		ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); +		msleep(1); + +		break; +#endif +	}  }  static const char *band_to_string(enum ieee80211_band band) @@ -3954,7 +4108,7 @@ redo:  	/* Disable interrupts on the device. */  	b43_set_status(dev, B43_STAT_INITIALIZED); -	if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { +	if (b43_bus_host_is_sdio(dev->dev)) {  		/* wl->mutex is locked. That is enough. */  		b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);  		b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);	/* Flush */ @@ -3967,11 +4121,11 @@ redo:  	/* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */  	orig_dev = dev;  	mutex_unlock(&wl->mutex); -	if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { +	if (b43_bus_host_is_sdio(dev->dev)) {  		b43_sdio_free_irq(dev);  	} else { -		synchronize_irq(dev->sdev->irq); -		free_irq(dev->sdev->irq, dev); +		synchronize_irq(dev->dev->irq); +		free_irq(dev->dev->irq, dev);  	}  	mutex_lock(&wl->mutex);  	dev = wl->current_dev; @@ -4004,19 +4158,19 @@ static int b43_wireless_core_start(struct b43_wldev *dev)  	B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);  	drain_txstatus_queue(dev); -	if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { +	if (b43_bus_host_is_sdio(dev->dev)) {  		err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);  		if (err) {  			b43err(dev->wl, "Cannot request SDIO IRQ\n");  			goto out;  		}  	} else { -		err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler, +		err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,  					   b43_interrupt_thread_handler,  					   IRQF_SHARED, KBUILD_MODNAME, dev);  		if (err) {  			b43err(dev->wl, "Cannot request IRQ-%d\n", -			       dev->sdev->irq); +			       dev->dev->irq);  			goto out;  		}  	} @@ -4083,9 +4237,21 @@ static int b43_phy_versioning(struct b43_wldev *dev)  			unsupported = 1;  		break;  #endif +#ifdef CONFIG_B43_PHY_HT +	case B43_PHYTYPE_HT: +		if (phy_rev > 1) +			unsupported = 1; +		break; +#endif +#ifdef CONFIG_B43_PHY_LCN +	case B43_PHYTYPE_LCN: +		if (phy_rev > 1) +			unsupported = 1; +		break; +#endif  	default:  		unsupported = 1; -	}; +	}  	if (unsupported) {  		b43err(dev->wl, "FOUND UNSUPPORTED PHY "  		       "(Analog %u, Type %u, Revision %u)\n", @@ -4096,22 +4262,42 @@ static int b43_phy_versioning(struct b43_wldev *dev)  	       analog_type, phy_type, phy_rev);  	/* Get RADIO versioning */ -	if (dev->sdev->bus->chip_id == 0x4317) { -		if (dev->sdev->bus->chip_rev == 0) -			tmp = 0x3205017F; -		else if (dev->sdev->bus->chip_rev == 1) -			tmp = 0x4205017F; -		else -			tmp = 0x5205017F; +	if (dev->dev->core_rev >= 24) { +		u16 radio24[3]; + +		for (tmp = 0; tmp < 3; tmp++) { +			b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp); +			radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA); +		} + +		/* Broadcom uses "id" for our "ver" and has separated "ver" */ +		/* radio_ver = (radio24[0] & 0xF0) >> 4; */ + +		radio_manuf = 0x17F; +		radio_ver = (radio24[2] << 8) | radio24[1]; +		radio_rev = (radio24[0] & 0xF);  	} else { -		b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); -		tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); -		b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); -		tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16; +		if (dev->dev->chip_id == 0x4317) { +			if (dev->dev->chip_rev == 0) +				tmp = 0x3205017F; +			else if (dev->dev->chip_rev == 1) +				tmp = 0x4205017F; +			else +				tmp = 0x5205017F; +		} else { +			b43_write16(dev, B43_MMIO_RADIO_CONTROL, +				    B43_RADIOCTL_ID); +			tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); +			b43_write16(dev, B43_MMIO_RADIO_CONTROL, +				    B43_RADIOCTL_ID); +			tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) +				<< 16; +		} +		radio_manuf = (tmp & 0x00000FFF); +		radio_ver = (tmp & 0x0FFFF000) >> 12; +		radio_rev = (tmp & 0xF0000000) >> 28;  	} -	radio_manuf = (tmp & 0x00000FFF); -	radio_ver = (tmp & 0x0FFFF000) >> 12; -	radio_rev = (tmp & 0xF0000000) >> 28; +  	if (radio_manuf != 0x17F /* Broadcom */)  		unsupported = 1;  	switch (phy_type) { @@ -4139,6 +4325,14 @@ static int b43_phy_versioning(struct b43_wldev *dev)  		if (radio_ver != 0x2062 && radio_ver != 0x2063)  			unsupported = 1;  		break; +	case B43_PHYTYPE_HT: +		if (radio_ver != 0x2059) +			unsupported = 1; +		break; +	case B43_PHYTYPE_LCN: +		if (radio_ver != 0x2064) +			unsupported = 1; +		break;  	default:  		B43_WARN_ON(1);  	} @@ -4204,7 +4398,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)  static void b43_bluetooth_coext_enable(struct b43_wldev *dev)  { -	struct ssb_sprom *sprom = &dev->sdev->bus->sprom; +	struct ssb_sprom *sprom = dev->dev->bus_sprom;  	u64 hf;  	if (!modparam_btcoex) @@ -4231,16 +4425,21 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev)  static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)  { -	struct ssb_bus *bus = dev->sdev->bus; +	struct ssb_bus *bus;  	u32 tmp; +	if (dev->dev->bus_type != B43_BUS_SSB) +		return; + +	bus = dev->dev->sdev->bus; +  	if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) ||  	    (bus->chip_id == 0x4312)) { -		tmp = ssb_read32(dev->sdev, SSB_IMCFGLO); +		tmp = ssb_read32(dev->dev->sdev, SSB_IMCFGLO);  		tmp &= ~SSB_IMCFGLO_REQTO;  		tmp &= ~SSB_IMCFGLO_SERTO;  		tmp |= 0x3; -		ssb_write32(dev->sdev, SSB_IMCFGLO, tmp); +		ssb_write32(dev->dev->sdev, SSB_IMCFGLO, tmp);  		ssb_commit_settings(bus);  	}  } @@ -4310,36 +4509,45 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)  		dev->wl->current_beacon = NULL;  	} -	ssb_device_disable(dev->sdev, 0); -	ssb_bus_may_powerdown(dev->sdev->bus); +	b43_device_disable(dev, 0); +	b43_bus_may_powerdown(dev);  }  /* Initialize a wireless core */  static int b43_wireless_core_init(struct b43_wldev *dev)  { -	struct ssb_bus *bus = dev->sdev->bus; -	struct ssb_sprom *sprom = &bus->sprom; +	struct ssb_sprom *sprom = dev->dev->bus_sprom;  	struct b43_phy *phy = &dev->phy;  	int err;  	u64 hf; -	u32 tmp;  	B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); -	err = ssb_bus_powerup(bus, 0); +	err = b43_bus_powerup(dev, 0);  	if (err)  		goto out; -	if (!ssb_device_is_enabled(dev->sdev)) { -		tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; -		b43_wireless_core_reset(dev, tmp); -	} +	if (!b43_device_is_enabled(dev)) +		b43_wireless_core_reset(dev, phy->gmode);  	/* Reset all data structures. */  	setup_struct_wldev_for_init(dev);  	phy->ops->prepare_structs(dev);  	/* Enable IRQ routing to this device. */ -	ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev); +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci, +				      dev->dev->bdev, true); +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		ssb_pcicore_dev_irqvecs_enable(&dev->dev->sdev->bus->pcicore, +					       dev->dev->sdev); +		break; +#endif +	}  	b43_imcfglo_timeouts_workaround(dev);  	b43_bluetooth_coext_disable(dev); @@ -4352,7 +4560,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)  	if (err)  		goto err_busdown;  	b43_shm_write16(dev, B43_SHM_SHARED, -			B43_SHM_SH_WLCOREREV, dev->sdev->id.revision); +			B43_SHM_SH_WLCOREREV, dev->dev->core_rev);  	hf = b43_hf_read(dev);  	if (phy->type == B43_PHYTYPE_G) {  		hf |= B43_HF_SYMW; @@ -4370,8 +4578,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)  	if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)  		hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */  #ifdef CONFIG_SSB_DRIVER_PCICORE -	if ((bus->bustype == SSB_BUSTYPE_PCI) && -	    (bus->pcicore.dev->id.revision <= 10)) +	if (dev->dev->bus_type == B43_BUS_SSB && +	    dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && +	    dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)  		hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */  #endif  	hf &= ~B43_HF_SKCFPUP; @@ -4399,8 +4608,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev)  	/* Maximum Contention Window */  	b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); -	if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) || -	    (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) || +	if (b43_bus_host_is_pcmcia(dev->dev) || +	    b43_bus_host_is_sdio(dev->dev) ||  	    dev->use_pio) {  		dev->__using_pio_transfers = 1;  		err = b43_pio_init(dev); @@ -4414,7 +4623,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)  	b43_set_synth_pu_delay(dev, 1);  	b43_bluetooth_coext_enable(dev); -	ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); +	b43_bus_powerup(dev, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));  	b43_upload_card_macaddress(dev);  	b43_security_init(dev); @@ -4431,7 +4640,7 @@ out:  err_chip_exit:  	b43_chip_exit(dev);  err_busdown: -	ssb_bus_may_powerdown(bus); +	b43_bus_may_powerdown(dev);  	B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);  	return err;  } @@ -4737,11 +4946,9 @@ static void b43_wireless_core_detach(struct b43_wldev *dev)  static int b43_wireless_core_attach(struct b43_wldev *dev)  {  	struct b43_wl *wl = dev->wl; -	struct ssb_bus *bus = dev->sdev->bus; -	struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; +	struct pci_dev *pdev = NULL;  	int err;  	bool have_2ghz_phy = 0, have_5ghz_phy = 0; -	u32 tmp;  	/* Do NOT do any device initialization here.  	 * Do it in wireless_core_init() instead. @@ -4750,25 +4957,42 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)  	 * that in core_init(), too.  	 */ -	err = ssb_bus_powerup(bus, 0); +#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. */ -	if (dev->sdev->id.revision >= 5) { -		u32 tmshigh; -		tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); -		have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); -		have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); -	} else -		B43_WARN_ON(1); +	/* Get the PHY type. */ +	switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA +	case B43_BUS_BCMA: +		/* FIXME */ +		have_2ghz_phy = 1; +		have_5ghz_phy = 0; +		break; +#endif +#ifdef CONFIG_B43_SSB +	case B43_BUS_SSB: +		if (dev->dev->core_rev >= 5) { +			u32 tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); +			have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); +			have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); +		} else +			B43_WARN_ON(1); +		break; +#endif +	}  	dev->phy.gmode = have_2ghz_phy;  	dev->phy.radio_on = 1; -	tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; -	b43_wireless_core_reset(dev, tmp); +	b43_wireless_core_reset(dev, dev->phy.gmode);  	err = b43_phy_versioning(dev);  	if (err) @@ -4790,6 +5014,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)  #endif  		case B43_PHYTYPE_G:  		case B43_PHYTYPE_N: +		case B43_PHYTYPE_HT: +		case B43_PHYTYPE_LCN:  			have_2ghz_phy = 1;  			break;  		default: @@ -4816,8 +5042,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)  		goto err_powerdown;  	dev->phy.gmode = have_2ghz_phy; -	tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; -	b43_wireless_core_reset(dev, tmp); +	b43_wireless_core_reset(dev, dev->phy.gmode);  	err = b43_validate_chipaccess(dev);  	if (err) @@ -4832,8 +5057,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)  	INIT_WORK(&dev->restart_work, b43_chip_reset);  	dev->phy.ops->switch_analog(dev, 0); -	ssb_device_disable(dev->sdev, 0); -	ssb_bus_may_powerdown(bus); +	b43_device_disable(dev, 0); +	b43_bus_may_powerdown(dev);  out:  	return err; @@ -4841,11 +5066,11 @@ out:  err_phy_free:  	b43_phy_free(dev);  err_powerdown: -	ssb_bus_may_powerdown(bus); +	b43_bus_may_powerdown(dev);  	return err;  } -static void b43_one_core_detach(struct ssb_device *dev) +static void b43_one_core_detach(struct b43_bus_dev *dev)  {  	struct b43_wldev *wldev;  	struct b43_wl *wl; @@ -4853,17 +5078,17 @@ static void b43_one_core_detach(struct ssb_device *dev)  	/* Do not cancel ieee80211-workqueue based work here.  	 * See comment in b43_remove(). */ -	wldev = ssb_get_drvdata(dev); +	wldev = b43_bus_get_wldev(dev);  	wl = wldev->wl;  	b43_debugfs_remove_device(wldev);  	b43_wireless_core_detach(wldev);  	list_del(&wldev->list);  	wl->nr_devs--; -	ssb_set_drvdata(dev, NULL); +	b43_bus_set_wldev(dev, NULL);  	kfree(wldev);  } -static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) +static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)  {  	struct b43_wldev *wldev;  	int err = -ENOMEM; @@ -4873,7 +5098,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)  		goto out;  	wldev->use_pio = b43_modparam_pio; -	wldev->sdev = dev; +	wldev->dev = dev;  	wldev->wl = wl;  	b43_set_status(wldev, B43_STAT_UNINIT);  	wldev->bad_frames_preempt = modparam_bad_frames_preempt; @@ -4885,7 +5110,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)  	list_add(&wldev->list, &wl->devlist);  	wl->nr_devs++; -	ssb_set_drvdata(dev, wldev); +	b43_bus_set_wldev(dev, wldev);  	b43_debugfs_add_device(wldev);        out: @@ -4926,17 +5151,17 @@ static void b43_sprom_fixup(struct ssb_bus *bus)  	}  } -static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl) +static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl)  {  	struct ieee80211_hw *hw = wl->hw; -	ssb_set_devtypedata(dev, NULL); +	ssb_set_devtypedata(dev->sdev, NULL);  	ieee80211_free_hw(hw);  } -static struct b43_wl *b43_wireless_init(struct ssb_device *dev) +static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)  { -	struct ssb_sprom *sprom = &dev->bus->sprom; +	struct ssb_sprom *sprom = dev->bus_sprom;  	struct ieee80211_hw *hw;  	struct b43_wl *wl; @@ -4978,28 +5203,62 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev)  	skb_queue_head_init(&wl->tx_queue);  	b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", -		dev->bus->chip_id, dev->id.revision); +		dev->chip_id, dev->core_rev);  	return wl;  } -static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) +#ifdef CONFIG_B43_BCMA +static int b43_bcma_probe(struct bcma_device *core) +{ +	struct b43_bus_dev *dev; + +	dev = b43_bus_dev_bcma_init(core); +	if (!dev) +		return -ENODEV; + +	b43err(NULL, "BCMA is not supported yet!"); +	kfree(dev); +	return -EOPNOTSUPP; +} + +static void b43_bcma_remove(struct bcma_device *core) +{ +	/* TODO */ +} + +static struct bcma_driver b43_bcma_driver = { +	.name		= KBUILD_MODNAME, +	.id_table	= b43_bcma_tbl, +	.probe		= b43_bcma_probe, +	.remove		= b43_bcma_remove, +}; +#endif + +#ifdef CONFIG_B43_SSB +static +int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)  { +	struct b43_bus_dev *dev;  	struct b43_wl *wl;  	int err;  	int first = 0; -	wl = ssb_get_devtypedata(dev); +	dev = b43_bus_dev_ssb_init(sdev); +	if (!dev) +		return -ENOMEM; + +	wl = ssb_get_devtypedata(sdev);  	if (!wl) {  		/* Probing the first core. Must setup common struct b43_wl */  		first = 1; -		b43_sprom_fixup(dev->bus); +		b43_sprom_fixup(sdev->bus);  		wl = b43_wireless_init(dev);  		if (IS_ERR(wl)) {  			err = PTR_ERR(wl);  			goto out;  		} -		ssb_set_devtypedata(dev, wl); -		B43_WARN_ON(ssb_get_devtypedata(dev) != wl); +		ssb_set_devtypedata(sdev, wl); +		B43_WARN_ON(ssb_get_devtypedata(sdev) != wl);  	}  	err = b43_one_core_attach(dev, wl);  	if (err) @@ -5023,10 +5282,10 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)  	return err;  } -static void b43_ssb_remove(struct ssb_device *dev) +static void b43_ssb_remove(struct ssb_device *sdev)  { -	struct b43_wl *wl = ssb_get_devtypedata(dev); -	struct b43_wldev *wldev = ssb_get_drvdata(dev); +	struct b43_wl *wl = ssb_get_devtypedata(sdev); +	struct b43_wldev *wldev = ssb_get_drvdata(sdev);  	/* We must cancel any work here before unregistering from ieee80211,  	 * as the ieee80211 unreg will destroy the workqueue. */ @@ -5042,17 +5301,25 @@ static void b43_ssb_remove(struct ssb_device *dev)  		ieee80211_unregister_hw(wl->hw);  	} -	b43_one_core_detach(dev); +	b43_one_core_detach(wldev->dev);  	if (list_empty(&wl->devlist)) {  		b43_leds_unregister(wl);  		/* Last core on the chip unregistered.  		 * We can destroy common struct b43_wl.  		 */ -		b43_wireless_exit(dev, wl); +		b43_wireless_exit(wldev->dev, wl);  	}  } +static struct ssb_driver b43_ssb_driver = { +	.name		= KBUILD_MODNAME, +	.id_table	= b43_ssb_tbl, +	.probe		= b43_ssb_probe, +	.remove		= b43_ssb_remove, +}; +#endif /* CONFIG_B43_SSB */ +  /* Perform a hardware reset. This can be called from any context. */  void b43_controller_restart(struct b43_wldev *dev, const char *reason)  { @@ -5063,13 +5330,6 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason)  	ieee80211_queue_work(dev->wl->hw, &dev->restart_work);  } -static struct ssb_driver b43_ssb_driver = { -	.name		= KBUILD_MODNAME, -	.id_table	= b43_ssb_tbl, -	.probe		= b43_ssb_probe, -	.remove		= b43_ssb_remove, -}; -  static void b43_print_driverinfo(void)  {  	const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", @@ -5108,14 +5368,27 @@ static int __init b43_init(void)  	err = b43_sdio_init();  	if (err)  		goto err_pcmcia_exit; -	err = ssb_driver_register(&b43_ssb_driver); +#ifdef CONFIG_B43_BCMA +	err = bcma_driver_register(&b43_bcma_driver);  	if (err)  		goto err_sdio_exit; +#endif +#ifdef CONFIG_B43_SSB +	err = ssb_driver_register(&b43_ssb_driver); +	if (err) +		goto err_bcma_driver_exit; +#endif  	b43_print_driverinfo();  	return err; +#ifdef CONFIG_B43_SSB +err_bcma_driver_exit: +#endif +#ifdef CONFIG_B43_BCMA +	bcma_driver_unregister(&b43_bcma_driver);  err_sdio_exit: +#endif  	b43_sdio_exit();  err_pcmcia_exit:  	b43_pcmcia_exit(); @@ -5126,7 +5399,12 @@ err_dfs_exit:  static void __exit b43_exit(void)  { +#ifdef CONFIG_B43_SSB  	ssb_driver_unregister(&b43_ssb_driver); +#endif +#ifdef CONFIG_B43_BCMA +	bcma_driver_unregister(&b43_bcma_driver); +#endif  	b43_sdio_exit();  	b43_pcmcia_exit();  	b43_debugfs_exit();  |