diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/init.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 515 | 
1 files changed, 193 insertions, 322 deletions
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 9a1f349f926..0246b990fe8 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -57,112 +57,15 @@ static int ath9k_bt_ant_diversity;  module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444);  MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); -bool is_ath9k_unloaded; -/* We use the hw_value as an index into our private channel structure */ - -#define CHAN2G(_freq, _idx)  { \ -	.band = IEEE80211_BAND_2GHZ, \ -	.center_freq = (_freq), \ -	.hw_value = (_idx), \ -	.max_power = 20, \ -} - -#define CHAN5G(_freq, _idx) { \ -	.band = IEEE80211_BAND_5GHZ, \ -	.center_freq = (_freq), \ -	.hw_value = (_idx), \ -	.max_power = 20, \ -} - -/* Some 2 GHz radios are actually tunable on 2312-2732 - * on 5 MHz steps, we support the channels which we know - * we have calibration data for all cards though to make - * this static */ -static const struct ieee80211_channel ath9k_2ghz_chantable[] = { -	CHAN2G(2412, 0), /* Channel 1 */ -	CHAN2G(2417, 1), /* Channel 2 */ -	CHAN2G(2422, 2), /* Channel 3 */ -	CHAN2G(2427, 3), /* Channel 4 */ -	CHAN2G(2432, 4), /* Channel 5 */ -	CHAN2G(2437, 5), /* Channel 6 */ -	CHAN2G(2442, 6), /* Channel 7 */ -	CHAN2G(2447, 7), /* Channel 8 */ -	CHAN2G(2452, 8), /* Channel 9 */ -	CHAN2G(2457, 9), /* Channel 10 */ -	CHAN2G(2462, 10), /* Channel 11 */ -	CHAN2G(2467, 11), /* Channel 12 */ -	CHAN2G(2472, 12), /* Channel 13 */ -	CHAN2G(2484, 13), /* Channel 14 */ -}; +static int ath9k_ps_enable; +module_param_named(ps_enable, ath9k_ps_enable, int, 0444); +MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); -/* Some 5 GHz radios are actually tunable on XXXX-YYYY - * on 5 MHz steps, we support the channels which we know - * we have calibration data for all cards though to make - * this static */ -static const struct ieee80211_channel ath9k_5ghz_chantable[] = { -	/* _We_ call this UNII 1 */ -	CHAN5G(5180, 14), /* Channel 36 */ -	CHAN5G(5200, 15), /* Channel 40 */ -	CHAN5G(5220, 16), /* Channel 44 */ -	CHAN5G(5240, 17), /* Channel 48 */ -	/* _We_ call this UNII 2 */ -	CHAN5G(5260, 18), /* Channel 52 */ -	CHAN5G(5280, 19), /* Channel 56 */ -	CHAN5G(5300, 20), /* Channel 60 */ -	CHAN5G(5320, 21), /* Channel 64 */ -	/* _We_ call this "Middle band" */ -	CHAN5G(5500, 22), /* Channel 100 */ -	CHAN5G(5520, 23), /* Channel 104 */ -	CHAN5G(5540, 24), /* Channel 108 */ -	CHAN5G(5560, 25), /* Channel 112 */ -	CHAN5G(5580, 26), /* Channel 116 */ -	CHAN5G(5600, 27), /* Channel 120 */ -	CHAN5G(5620, 28), /* Channel 124 */ -	CHAN5G(5640, 29), /* Channel 128 */ -	CHAN5G(5660, 30), /* Channel 132 */ -	CHAN5G(5680, 31), /* Channel 136 */ -	CHAN5G(5700, 32), /* Channel 140 */ -	/* _We_ call this UNII 3 */ -	CHAN5G(5745, 33), /* Channel 149 */ -	CHAN5G(5765, 34), /* Channel 153 */ -	CHAN5G(5785, 35), /* Channel 157 */ -	CHAN5G(5805, 36), /* Channel 161 */ -	CHAN5G(5825, 37), /* Channel 165 */ -}; +static int ath9k_use_chanctx; +module_param_named(use_chanctx, ath9k_use_chanctx, int, 0444); +MODULE_PARM_DESC(use_chanctx, "Enable channel context for concurrency"); -/* Atheros hardware rate code addition for short premble */ -#define SHPCHECK(__hw_rate, __flags) \ -	((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) - -#define RATE(_bitrate, _hw_rate, _flags) {              \ -	.bitrate        = (_bitrate),                   \ -	.flags          = (_flags),                     \ -	.hw_value       = (_hw_rate),                   \ -	.hw_value_short = (SHPCHECK(_hw_rate, _flags))  \ -} - -static struct ieee80211_rate ath9k_legacy_rates[] = { -	RATE(10, 0x1b, 0), -	RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), -	RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), -	RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), -	RATE(60, 0x0b, (IEEE80211_RATE_SUPPORTS_5MHZ | -			IEEE80211_RATE_SUPPORTS_10MHZ)), -	RATE(90, 0x0f, (IEEE80211_RATE_SUPPORTS_5MHZ | -			IEEE80211_RATE_SUPPORTS_10MHZ)), -	RATE(120, 0x0a, (IEEE80211_RATE_SUPPORTS_5MHZ | -			 IEEE80211_RATE_SUPPORTS_10MHZ)), -	RATE(180, 0x0e, (IEEE80211_RATE_SUPPORTS_5MHZ | -			 IEEE80211_RATE_SUPPORTS_10MHZ)), -	RATE(240, 0x09, (IEEE80211_RATE_SUPPORTS_5MHZ | -			 IEEE80211_RATE_SUPPORTS_10MHZ)), -	RATE(360, 0x0d, (IEEE80211_RATE_SUPPORTS_5MHZ | -			 IEEE80211_RATE_SUPPORTS_10MHZ)), -	RATE(480, 0x08, (IEEE80211_RATE_SUPPORTS_5MHZ | -			 IEEE80211_RATE_SUPPORTS_10MHZ)), -	RATE(540, 0x0c, (IEEE80211_RATE_SUPPORTS_5MHZ | -			 IEEE80211_RATE_SUPPORTS_10MHZ)), -}; +bool is_ath9k_unloaded;  #ifdef CONFIG_MAC80211_LEDS  static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = { @@ -254,64 +157,6 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl  /*     Initialization     */  /**************************/ -static void setup_ht_cap(struct ath_softc *sc, -			 struct ieee80211_sta_ht_cap *ht_info) -{ -	struct ath_hw *ah = sc->sc_ah; -	struct ath_common *common = ath9k_hw_common(ah); -	u8 tx_streams, rx_streams; -	int i, max_streams; - -	ht_info->ht_supported = true; -	ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | -		       IEEE80211_HT_CAP_SM_PS | -		       IEEE80211_HT_CAP_SGI_40 | -		       IEEE80211_HT_CAP_DSSSCCK40; - -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC) -		ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; - -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) -		ht_info->cap |= IEEE80211_HT_CAP_SGI_20; - -	ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; -	ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; - -	if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) -		max_streams = 1; -	else if (AR_SREV_9462(ah)) -		max_streams = 2; -	else if (AR_SREV_9300_20_OR_LATER(ah)) -		max_streams = 3; -	else -		max_streams = 2; - -	if (AR_SREV_9280_20_OR_LATER(ah)) { -		if (max_streams >= 2) -			ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; -		ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); -	} - -	/* set up supported mcs set */ -	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); -	tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams); -	rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams); - -	ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n", -		tx_streams, rx_streams); - -	if (tx_streams != rx_streams) { -		ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; -		ht_info->mcs.tx_params |= ((tx_streams - 1) << -				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); -	} - -	for (i = 0; i < rx_streams; i++) -		ht_info->mcs.rx_mask[i] = 0xff; - -	ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; -} -  static void ath9k_reg_notifier(struct wiphy *wiphy,  			       struct regulatory_request *request)  { @@ -347,7 +192,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,  {  	struct ath_common *common = ath9k_hw_common(sc->sc_ah);  	u8 *ds; -	struct ath_buf *bf;  	int i, bsize, desc_len;  	ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n", @@ -399,33 +243,68 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,  		ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);  	/* allocate buffers */ -	bsize = sizeof(struct ath_buf) * nbuf; -	bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL); -	if (!bf) -		return -ENOMEM; +	if (is_tx) { +		struct ath_buf *bf; + +		bsize = sizeof(struct ath_buf) * nbuf; +		bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL); +		if (!bf) +			return -ENOMEM; + +		for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { +			bf->bf_desc = ds; +			bf->bf_daddr = DS2PHYS(dd, ds); + +			if (!(sc->sc_ah->caps.hw_caps & +				  ATH9K_HW_CAP_4KB_SPLITTRANS)) { +				/* +				 * Skip descriptor addresses which can cause 4KB +				 * boundary crossing (addr + length) with a 32 dword +				 * descriptor fetch. +				 */ +				while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { +					BUG_ON((caddr_t) bf->bf_desc >= +						   ((caddr_t) dd->dd_desc + +						dd->dd_desc_len)); + +					ds += (desc_len * ndesc); +					bf->bf_desc = ds; +					bf->bf_daddr = DS2PHYS(dd, ds); +				} +			} +			list_add_tail(&bf->list, head); +		} +	} else { +		struct ath_rxbuf *bf; + +		bsize = sizeof(struct ath_rxbuf) * nbuf; +		bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL); +		if (!bf) +			return -ENOMEM; -	for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { -		bf->bf_desc = ds; -		bf->bf_daddr = DS2PHYS(dd, ds); - -		if (!(sc->sc_ah->caps.hw_caps & -		      ATH9K_HW_CAP_4KB_SPLITTRANS)) { -			/* -			 * Skip descriptor addresses which can cause 4KB -			 * boundary crossing (addr + length) with a 32 dword -			 * descriptor fetch. -			 */ -			while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { -				BUG_ON((caddr_t) bf->bf_desc >= -				       ((caddr_t) dd->dd_desc + -					dd->dd_desc_len)); - -				ds += (desc_len * ndesc); -				bf->bf_desc = ds; -				bf->bf_daddr = DS2PHYS(dd, ds); +		for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { +			bf->bf_desc = ds; +			bf->bf_daddr = DS2PHYS(dd, ds); + +			if (!(sc->sc_ah->caps.hw_caps & +				  ATH9K_HW_CAP_4KB_SPLITTRANS)) { +				/* +				 * Skip descriptor addresses which can cause 4KB +				 * boundary crossing (addr + length) with a 32 dword +				 * descriptor fetch. +				 */ +				while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { +					BUG_ON((caddr_t) bf->bf_desc >= +						   ((caddr_t) dd->dd_desc + +						dd->dd_desc_len)); + +					ds += (desc_len * ndesc); +					bf->bf_desc = ds; +					bf->bf_daddr = DS2PHYS(dd, ds); +				}  			} +			list_add_tail(&bf->list, head);  		} -		list_add_tail(&bf->list, head);  	}  	return 0;  } @@ -436,8 +315,6 @@ static int ath9k_init_queues(struct ath_softc *sc)  	sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);  	sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); - -	sc->config.cabqReadytime = ATH_CABQ_READY_TIME;  	ath_cabq_update(sc);  	sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0); @@ -450,51 +327,6 @@ static int ath9k_init_queues(struct ath_softc *sc)  	return 0;  } -static int ath9k_init_channels_rates(struct ath_softc *sc) -{ -	void *channels; - -	BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) + -		     ARRAY_SIZE(ath9k_5ghz_chantable) != -		     ATH9K_NUM_CHANNELS); - -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { -		channels = devm_kzalloc(sc->dev, -			sizeof(ath9k_2ghz_chantable), GFP_KERNEL); -		if (!channels) -		    return -ENOMEM; - -		memcpy(channels, ath9k_2ghz_chantable, -		       sizeof(ath9k_2ghz_chantable)); -		sc->sbands[IEEE80211_BAND_2GHZ].channels = channels; -		sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; -		sc->sbands[IEEE80211_BAND_2GHZ].n_channels = -			ARRAY_SIZE(ath9k_2ghz_chantable); -		sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; -		sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates = -			ARRAY_SIZE(ath9k_legacy_rates); -	} - -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { -		channels = devm_kzalloc(sc->dev, -			sizeof(ath9k_5ghz_chantable), GFP_KERNEL); -		if (!channels) -			return -ENOMEM; - -		memcpy(channels, ath9k_5ghz_chantable, -		       sizeof(ath9k_5ghz_chantable)); -		sc->sbands[IEEE80211_BAND_5GHZ].channels = channels; -		sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; -		sc->sbands[IEEE80211_BAND_5GHZ].n_channels = -			ARRAY_SIZE(ath9k_5ghz_chantable); -		sc->sbands[IEEE80211_BAND_5GHZ].bitrates = -			ath9k_legacy_rates + 4; -		sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = -			ARRAY_SIZE(ath9k_legacy_rates) - 4; -	} -	return 0; -} -  static void ath9k_init_misc(struct ath_softc *sc)  {  	struct ath_common *common = ath9k_hw_common(sc->sc_ah); @@ -502,7 +334,7 @@ static void ath9k_init_misc(struct ath_softc *sc)  	setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); -	sc->last_rssi = ATH_RSSI_DUMMY_MARKER; +	common->last_rssi = ATH_RSSI_DUMMY_MARKER;  	sc->config.txpowlimit = ATH_TXPOWER_MAX;  	memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);  	sc->beacon.slottime = ATH9K_SLOT_TIME_9; @@ -521,7 +353,7 @@ static void ath9k_init_misc(struct ath_softc *sc)  	sc->spec_config.fft_period = 0xF;  } -static void ath9k_init_platform(struct ath_softc *sc) +static void ath9k_init_pcoem_platform(struct ath_softc *sc)  {  	struct ath_hw *ah = sc->sc_ah;  	struct ath9k_hw_capabilities *pCap = &ah->caps; @@ -547,6 +379,29 @@ static void ath9k_init_platform(struct ath_softc *sc)  	if (sc->driver_data & ATH9K_PCI_CUS217)  		ath_info(common, "CUS217 card detected\n"); +	if (sc->driver_data & ATH9K_PCI_CUS252) +		ath_info(common, "CUS252 card detected\n"); + +	if (sc->driver_data & ATH9K_PCI_AR9565_1ANT) +		ath_info(common, "WB335 1-ANT card detected\n"); + +	if (sc->driver_data & ATH9K_PCI_AR9565_2ANT) +		ath_info(common, "WB335 2-ANT card detected\n"); + +	if (sc->driver_data & ATH9K_PCI_KILLER) +		ath_info(common, "Killer Wireless card detected\n"); + +	/* +	 * Some WB335 cards do not support antenna diversity. Since +	 * we use a hardcoded value for AR9565 instead of using the +	 * EEPROM/OTP data, remove the combining feature from +	 * the HW capabilities bitmap. +	 */ +	if (sc->driver_data & (ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_AR9565_2ANT)) { +		if (!(sc->driver_data & ATH9K_PCI_BT_ANT_DIV)) +			pCap->hw_caps &= ~ATH9K_HW_CAP_ANT_DIV_COMB; +	} +  	if (sc->driver_data & ATH9K_PCI_BT_ANT_DIV) {  		pCap->hw_caps |= ATH9K_HW_CAP_BT_ANT_DIV;  		ath_info(common, "Set BT/WLAN RX diversity capability\n"); @@ -556,6 +411,11 @@ static void ath9k_init_platform(struct ath_softc *sc)  		ah->config.pcie_waen = 0x0040473b;  		ath_info(common, "Enable WAR for ASPM D3/L1\n");  	} + +	if (sc->driver_data & ATH9K_PCI_NO_PLL_PWRSAVE) { +		ah->config.no_pll_pwrsave = true; +		ath_info(common, "Disable PLL PowerSave\n"); +	}  }  static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob, @@ -603,6 +463,27 @@ static void ath9k_eeprom_release(struct ath_softc *sc)  	release_firmware(sc->sc_ah->eeprom_blob);  } +static int ath9k_init_soc_platform(struct ath_softc *sc) +{ +	struct ath9k_platform_data *pdata = sc->dev->platform_data; +	struct ath_hw *ah = sc->sc_ah; +	int ret = 0; + +	if (!pdata) +		return 0; + +	if (pdata->eeprom_name) { +		ret = ath9k_eeprom_request(sc, pdata->eeprom_name); +		if (ret) +			return ret; +	} + +	if (pdata->tx_gain_buffalo) +		ah->config.tx_gain_buffalo = true; + +	return ret; +} +  static int ath9k_init_softc(u16 devid, struct ath_softc *sc,  			    const struct ath_bus_ops *bus_ops)  { @@ -623,13 +504,15 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,  	ah->reg_ops.read = ath9k_ioread32;  	ah->reg_ops.write = ath9k_iowrite32;  	ah->reg_ops.rmw = ath9k_reg_rmw; -	atomic_set(&ah->intr_ref_cnt, -1);  	sc->sc_ah = ah;  	pCap = &ah->caps; -	sc->dfs_detector = dfs_pattern_detector_init(ah, NL80211_DFS_UNSET); +	common = ath9k_hw_common(ah); +	sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); +	sc->tx99_power = MAX_RATE_POWER + 1; +	init_waitqueue_head(&sc->tx_wait); -	if (!pdata) { +	if (!pdata || pdata->use_eeprom) {  		ah->ah_flags |= AH_USE_EEPROM;  		sc->sc_ah->led_pin = -1;  	} else { @@ -641,7 +524,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,  		ah->external_reset = pdata->external_reset;  	} -	common = ath9k_hw_common(ah);  	common->ops = &ah->reg_ops;  	common->bus_ops = bus_ops;  	common->ah = ah; @@ -654,7 +536,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,  	/*  	 * Platform quirks.  	 */ -	ath9k_init_platform(sc); +	ath9k_init_pcoem_platform(sc); + +	ret = ath9k_init_soc_platform(sc); +	if (ret) +		return ret;  	/*  	 * Enable WLAN/BT RX Antenna diversity only when: @@ -668,7 +554,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,  		common->bt_ant_diversity = 1;  	spin_lock_init(&common->cc_lock); -  	spin_lock_init(&sc->sc_serial_rw);  	spin_lock_init(&sc->sc_pm_lock);  	mutex_init(&sc->mutex); @@ -676,11 +561,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,  	tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,  		     (unsigned long)sc); +	setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc);  	INIT_WORK(&sc->hw_reset_work, ath_reset_work); -	INIT_WORK(&sc->hw_check_work, ath_hw_check);  	INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);  	INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); -	setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc);  	/*  	 * Cache line size is used to size and align various @@ -689,12 +573,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,  	ath_read_cachesize(common, &csz);  	common->cachelsz = csz << 2; /* convert to bytes */ -	if (pdata && pdata->eeprom_name) { -		ret = ath9k_eeprom_request(sc, pdata->eeprom_name); -		if (ret) -			return ret; -	} -  	/* Initializes the hardware for all supported chipsets */  	ret = ath9k_hw_init(ah);  	if (ret) @@ -711,10 +589,13 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,  	if (ret)  		goto err_btcoex; -	ret = ath9k_init_channels_rates(sc); +	ret = ath9k_cmn_init_channels_rates(common);  	if (ret)  		goto err_btcoex; +	sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer, +		NULL, sc, AR_FIRST_NDP_TIMER); +  	ath9k_cmn_init_crypto(sc->sc_ah);  	ath9k_init_misc(sc);  	ath_fill_led_pin(sc); @@ -732,6 +613,7 @@ err_queues:  	ath9k_hw_deinit(ah);  err_hw:  	ath9k_eeprom_release(sc); +	dev_kfree_skb_any(sc->tx99_skb);  	return ret;  } @@ -740,15 +622,16 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)  	struct ieee80211_supported_band *sband;  	struct ieee80211_channel *chan;  	struct ath_hw *ah = sc->sc_ah; +	struct ath_common *common = ath9k_hw_common(ah);  	struct cfg80211_chan_def chandef;  	int i; -	sband = &sc->sbands[band]; +	sband = &common->sbands[band];  	for (i = 0; i < sband->n_channels; i++) {  		chan = &sband->channels[i];  		ah->curchan = &ah->channels[chan->hw_value];  		cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20); -		ath9k_cmn_update_ichannel(ah->curchan, &chandef); +		ath9k_cmn_get_channel(sc->hw, ah, &chandef);  		ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);  	}  } @@ -766,32 +649,27 @@ static void ath9k_init_txpower_limits(struct ath_softc *sc)  	ah->curchan = curchan;  } -void ath9k_reload_chainmask_settings(struct ath_softc *sc) -{ -	if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)) -		return; - -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) -		setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); -	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) -		setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); -} -  static const struct ieee80211_iface_limit if_limits[] = { -	{ .max = 2048,	.types = BIT(NL80211_IFTYPE_STATION) | -				 BIT(NL80211_IFTYPE_P2P_CLIENT) | -				 BIT(NL80211_IFTYPE_WDS) }, +	{ .max = 2048,	.types = BIT(NL80211_IFTYPE_STATION) },  	{ .max = 8,	.types =  #ifdef CONFIG_MAC80211_MESH  				 BIT(NL80211_IFTYPE_MESH_POINT) |  #endif -				 BIT(NL80211_IFTYPE_AP) | +				 BIT(NL80211_IFTYPE_AP) }, +	{ .max = 1,	.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |  				 BIT(NL80211_IFTYPE_P2P_GO) },  }; +static const struct ieee80211_iface_limit wds_limits[] = { +	{ .max = 2048,	.types = BIT(NL80211_IFTYPE_WDS) }, +};  static const struct ieee80211_iface_limit if_dfs_limits[] = { -	{ .max = 1,	.types = BIT(NL80211_IFTYPE_AP) }, +	{ .max = 1,	.types = BIT(NL80211_IFTYPE_AP) | +#ifdef CONFIG_MAC80211_MESH +				 BIT(NL80211_IFTYPE_MESH_POINT) | +#endif +				 BIT(NL80211_IFTYPE_ADHOC) },  };  static const struct ieee80211_iface_combination if_comb[] = { @@ -803,26 +681,26 @@ static const struct ieee80211_iface_combination if_comb[] = {  		.beacon_int_infra_match = true,  	},  	{ +		.limits = wds_limits, +		.n_limits = ARRAY_SIZE(wds_limits), +		.max_interfaces = 2048, +		.num_different_channels = 1, +		.beacon_int_infra_match = true, +	}, +#ifdef CONFIG_ATH9K_DFS_CERTIFIED +	{  		.limits = if_dfs_limits,  		.n_limits = ARRAY_SIZE(if_dfs_limits),  		.max_interfaces = 1,  		.num_different_channels = 1,  		.beacon_int_infra_match = true, -		.radar_detect_widths =	BIT(NL80211_CHAN_NO_HT) | -					BIT(NL80211_CHAN_HT20), +		.radar_detect_widths =	BIT(NL80211_CHAN_WIDTH_20_NOHT) | +					BIT(NL80211_CHAN_WIDTH_20),  	} -}; - -#ifdef CONFIG_PM -static const struct wiphy_wowlan_support ath9k_wowlan_support = { -	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, -	.n_patterns = MAX_NUM_USER_PATTERN, -	.pattern_min_len = 1, -	.pattern_max_len = MAX_PATTERN_SIZE, -};  #endif +}; -void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) +static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)  {  	struct ath_hw *ah = sc->sc_ah;  	struct ath_common *common = ath9k_hw_common(ah); @@ -830,13 +708,15 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)  	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |  		IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |  		IEEE80211_HW_SIGNAL_DBM | -		IEEE80211_HW_SUPPORTS_PS |  		IEEE80211_HW_PS_NULLFUNC_STACK |  		IEEE80211_HW_SPECTRUM_MGMT |  		IEEE80211_HW_REPORTS_TX_ACK_STATUS |  		IEEE80211_HW_SUPPORTS_RC_TABLE |  		IEEE80211_HW_SUPPORTS_HT_CCK_RATES; +	if (ath9k_ps_enable) +		hw->flags |= IEEE80211_HW_SUPPORTS_PS; +  	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {  		hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; @@ -848,19 +728,24 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)  	if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)  		hw->flags |= IEEE80211_HW_MFP_CAPABLE; -	hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; - -	hw->wiphy->interface_modes = -		BIT(NL80211_IFTYPE_P2P_GO) | -		BIT(NL80211_IFTYPE_P2P_CLIENT) | -		BIT(NL80211_IFTYPE_AP) | -		BIT(NL80211_IFTYPE_WDS) | -		BIT(NL80211_IFTYPE_STATION) | -		BIT(NL80211_IFTYPE_ADHOC) | -		BIT(NL80211_IFTYPE_MESH_POINT); - -	hw->wiphy->iface_combinations = if_comb; -	hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); +	hw->wiphy->features |= (NL80211_FEATURE_ACTIVE_MONITOR | +				NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE); + +	if (!config_enabled(CONFIG_ATH9K_TX99)) { +		hw->wiphy->interface_modes = +			BIT(NL80211_IFTYPE_P2P_GO) | +			BIT(NL80211_IFTYPE_P2P_CLIENT) | +			BIT(NL80211_IFTYPE_AP) | +			BIT(NL80211_IFTYPE_STATION) | +			BIT(NL80211_IFTYPE_ADHOC) | +			BIT(NL80211_IFTYPE_MESH_POINT); +		hw->wiphy->iface_combinations = if_comb; +		if (!ath9k_use_chanctx) { +			hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); +			hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_WDS); +		} else +			hw->wiphy->n_iface_combinations = 1; +	}  	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; @@ -869,20 +754,10 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)  	hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;  	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;  	hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; - -#ifdef CONFIG_PM_SLEEP -	if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && -	    (sc->driver_data & ATH9K_PCI_WOW) && -	    device_can_wakeup(sc->dev)) -		hw->wiphy->wowlan = &ath9k_wowlan_support; - -	atomic_set(&sc->wow_sleep_proc_intr, -1); -	atomic_set(&sc->wow_got_bmiss_intr, -1); -#endif +	hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;  	hw->queues = 4;  	hw->max_rates = 4; -	hw->channel_change_time = 5000;  	hw->max_listen_interval = 1;  	hw->max_rate_tries = 10;  	hw->sta_data_size = sizeof(struct ath_node); @@ -900,12 +775,13 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)  	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)  		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = -			&sc->sbands[IEEE80211_BAND_2GHZ]; +			&common->sbands[IEEE80211_BAND_2GHZ];  	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)  		hw->wiphy->bands[IEEE80211_BAND_5GHZ] = -			&sc->sbands[IEEE80211_BAND_5GHZ]; +			&common->sbands[IEEE80211_BAND_5GHZ]; -	ath9k_reload_chainmask_settings(sc); +	ath9k_init_wow(hw); +	ath9k_cmn_reload_chainmask(ah);  	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);  } @@ -928,6 +804,9 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,  	common = ath9k_hw_common(ah);  	ath9k_set_hw_capab(sc, hw); +	/* Will be cleared in ath9k_start() */ +	set_bit(ATH_OP_INVALID, &common->op_flags); +  	/* Initialize regulatory */  	error = ath_regd_init(&common->regulatory, sc->hw->wiphy,  			      ath9k_reg_notifier); @@ -997,12 +876,16 @@ static void ath9k_deinit_softc(struct ath_softc *sc)  {  	int i = 0; +	if (sc->p2p_ps_timer) +		ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer); +  	ath9k_deinit_btcoex(sc);  	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)  		if (ATH_TXQ_SETUP(sc, i))  			ath_tx_cleanupq(sc, &sc->tx.txq[i]); +	del_timer_sync(&sc->sleep_timer);  	ath9k_hw_deinit(sc->sc_ah);  	if (sc->dfs_detector != NULL)  		sc->dfs_detector->exit(sc->dfs_detector); @@ -1035,19 +918,11 @@ static int __init ath9k_init(void)  {  	int error; -	/* Register rate control algorithm */ -	error = ath_rate_control_register(); -	if (error != 0) { -		pr_err("Unable to register rate control algorithm: %d\n", -		       error); -		goto err_out; -	} -  	error = ath_pci_init();  	if (error < 0) {  		pr_err("No PCI devices found, driver not installed\n");  		error = -ENODEV; -		goto err_rate_unregister; +		goto err_out;  	}  	error = ath_ahb_init(); @@ -1060,9 +935,6 @@ static int __init ath9k_init(void)   err_pci_exit:  	ath_pci_exit(); - - err_rate_unregister: -	ath_rate_control_unregister();   err_out:  	return error;  } @@ -1073,7 +945,6 @@ static void __exit ath9k_exit(void)  	is_ath9k_unloaded = true;  	ath_ahb_exit();  	ath_pci_exit(); -	ath_rate_control_unregister();  	pr_info("%s: Driver unloaded\n", dev_info);  }  module_exit(ath9k_exit);  | 
