brintos

brintos / linux-shallow public Read only

0
0
Text · 49.4 KiB · 8a03bcc Raw
1909 lines · c
1/*2 * Copyright (c) 2010-2011 Atheros Communications Inc.3 *4 * Permission to use, copy, modify, and/or distribute this software for any5 * purpose with or without fee is hereby granted, provided that the above6 * copyright notice and this permission notice appear in all copies.7 *8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.15 */16 17#include "htc.h"18 19/*************/20/* Utilities */21/*************/22 23/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */24static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,25					      struct ath9k_channel *ichan)26{27	if (IS_CHAN_5GHZ(ichan))28		return HTC_MODE_11NA;29 30	return HTC_MODE_11NG;31}32 33bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,34			enum ath9k_power_mode mode)35{36	bool ret;37 38	mutex_lock(&priv->htc_pm_lock);39	ret = ath9k_hw_setpower(priv->ah, mode);40	mutex_unlock(&priv->htc_pm_lock);41 42	return ret;43}44 45void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)46{47	mutex_lock(&priv->htc_pm_lock);48	if (++priv->ps_usecount != 1)49		goto unlock;50	ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE);51 52unlock:53	mutex_unlock(&priv->htc_pm_lock);54}55 56void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)57{58	bool reset;59 60	mutex_lock(&priv->htc_pm_lock);61	if (--priv->ps_usecount != 0)62		goto unlock;63 64	if (priv->ps_idle) {65		ath9k_hw_setrxabort(priv->ah, true);66		ath9k_hw_stopdmarecv(priv->ah, &reset);67		ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);68	} else if (priv->ps_enabled) {69		ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);70	}71 72unlock:73	mutex_unlock(&priv->htc_pm_lock);74}75 76void ath9k_ps_work(struct work_struct *work)77{78	struct ath9k_htc_priv *priv =79		container_of(work, struct ath9k_htc_priv,80			     ps_work);81	ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);82 83	/* The chip wakes up after receiving the first beacon84	   while network sleep is enabled. For the driver to85	   be in sync with the hw, set the chip to awake and86	   only then set it to sleep.87	 */88	ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);89}90 91static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)92{93	struct ath9k_htc_priv *priv = data;94	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;95 96	if ((vif->type == NL80211_IFTYPE_AP ||97	     vif->type == NL80211_IFTYPE_MESH_POINT) &&98	    bss_conf->enable_beacon) {99		priv->reconfig_beacon = true;100		priv->rearm_ani = true;101	}102 103	if (vif->cfg.assoc) {104		priv->rearm_ani = true;105		priv->reconfig_beacon = true;106	}107}108 109static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)110{111	priv->rearm_ani = false;112	priv->reconfig_beacon = false;113 114	ieee80211_iterate_active_interfaces_atomic(115		priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,116		ath9k_htc_vif_iter, priv);117	if (priv->rearm_ani)118		ath9k_htc_start_ani(priv);119 120	if (priv->reconfig_beacon) {121		ath9k_htc_ps_wakeup(priv);122		ath9k_htc_beacon_reconfig(priv);123		ath9k_htc_ps_restore(priv);124	}125}126 127static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif)128{129	struct ath9k_vif_iter_data *iter_data = data;130	int i;131 132	if (iter_data->hw_macaddr != NULL) {133		for (i = 0; i < ETH_ALEN; i++)134			iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);135	} else {136		iter_data->hw_macaddr = mac;137	}138}139 140static void ath9k_htc_set_mac_bssid_mask(struct ath9k_htc_priv *priv,141				     struct ieee80211_vif *vif)142{143	struct ath_common *common = ath9k_hw_common(priv->ah);144	struct ath9k_vif_iter_data iter_data;145 146	/*147	 * Pick the MAC address of the first interface as the new hardware148	 * MAC address. The hardware will use it together with the BSSID mask149	 * when matching addresses.150	 */151	iter_data.hw_macaddr = NULL;152	eth_broadcast_addr(iter_data.mask);153 154	if (vif)155		ath9k_htc_bssid_iter(&iter_data, vif->addr, vif);156 157	/* Get list of all active MAC addresses */158	ieee80211_iterate_active_interfaces_atomic(159		priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,160		ath9k_htc_bssid_iter, &iter_data);161 162	memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);163 164	if (iter_data.hw_macaddr)165		memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN);166 167	ath_hw_setbssidmask(common);168}169 170static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv)171{172	if (priv->num_ibss_vif)173		priv->ah->opmode = NL80211_IFTYPE_ADHOC;174	else if (priv->num_ap_vif)175		priv->ah->opmode = NL80211_IFTYPE_AP;176	else if (priv->num_mbss_vif)177		priv->ah->opmode = NL80211_IFTYPE_MESH_POINT;178	else179		priv->ah->opmode = NL80211_IFTYPE_STATION;180 181	ath9k_hw_setopmode(priv->ah);182}183 184void ath9k_htc_reset(struct ath9k_htc_priv *priv)185{186	struct ath_hw *ah = priv->ah;187	struct ath_common *common = ath9k_hw_common(ah);188	struct ieee80211_channel *channel = priv->hw->conf.chandef.chan;189	struct ath9k_hw_cal_data *caldata = NULL;190	enum htc_phymode mode;191	__be16 htc_mode;192	u8 cmd_rsp;193	int ret;194 195	mutex_lock(&priv->mutex);196	ath9k_htc_ps_wakeup(priv);197 198	ath9k_htc_stop_ani(priv);199	ieee80211_stop_queues(priv->hw);200 201	del_timer_sync(&priv->tx.cleanup_timer);202	ath9k_htc_tx_drain(priv);203 204	WMI_CMD(WMI_DISABLE_INTR_CMDID);205	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);206	WMI_CMD(WMI_STOP_RECV_CMDID);207 208	ath9k_wmi_event_drain(priv);209 210	caldata = &priv->caldata;211	ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);212	if (ret) {213		ath_err(common,214			"Unable to reset device (%u Mhz) reset status %d\n",215			channel->center_freq, ret);216	}217 218	ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,219			       &priv->curtxpow);220 221	WMI_CMD(WMI_START_RECV_CMDID);222	ath9k_host_rx_init(priv);223 224	mode = ath9k_htc_get_curmode(priv, ah->curchan);225	htc_mode = cpu_to_be16(mode);226	WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);227 228	WMI_CMD(WMI_ENABLE_INTR_CMDID);229	htc_start(priv->htc);230	ath9k_htc_vif_reconfig(priv);231	ieee80211_wake_queues(priv->hw);232 233	mod_timer(&priv->tx.cleanup_timer,234		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));235 236	ath9k_htc_ps_restore(priv);237	mutex_unlock(&priv->mutex);238}239 240static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,241				 struct ieee80211_hw *hw,242				 struct ath9k_channel *hchan)243{244	struct ath_hw *ah = priv->ah;245	struct ath_common *common = ath9k_hw_common(ah);246	struct ieee80211_conf *conf = &common->hw->conf;247	bool fastcc;248	struct ieee80211_channel *channel = hw->conf.chandef.chan;249	struct ath9k_hw_cal_data *caldata;250	enum htc_phymode mode;251	__be16 htc_mode;252	u8 cmd_rsp;253	int ret;254 255	if (test_bit(ATH_OP_INVALID, &common->op_flags))256		return -EIO;257 258	fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);259 260	ath9k_htc_ps_wakeup(priv);261 262	ath9k_htc_stop_ani(priv);263	del_timer_sync(&priv->tx.cleanup_timer);264	ath9k_htc_tx_drain(priv);265 266	WMI_CMD(WMI_DISABLE_INTR_CMDID);267	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);268	WMI_CMD(WMI_STOP_RECV_CMDID);269 270	ath9k_wmi_event_drain(priv);271 272	ath_dbg(common, CONFIG,273		"(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",274		priv->ah->curchan->channel,275		channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),276		fastcc);277	caldata = fastcc ? NULL : &priv->caldata;278	ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);279	if (ret) {280		ath_err(common,281			"Unable to reset channel (%u Mhz) reset status %d\n",282			channel->center_freq, ret);283		goto err;284	}285 286	ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,287			       &priv->curtxpow);288 289	WMI_CMD(WMI_START_RECV_CMDID);290	if (ret)291		goto err;292 293	ath9k_host_rx_init(priv);294 295	mode = ath9k_htc_get_curmode(priv, hchan);296	htc_mode = cpu_to_be16(mode);297	WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);298	if (ret)299		goto err;300 301	WMI_CMD(WMI_ENABLE_INTR_CMDID);302	if (ret)303		goto err;304 305	htc_start(priv->htc);306 307	if (!test_bit(ATH_OP_SCANNING, &common->op_flags) &&308	    !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))309		ath9k_htc_vif_reconfig(priv);310 311	mod_timer(&priv->tx.cleanup_timer,312		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));313 314	/* perform spectral scan if requested. */315	if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&316		     priv->spec_priv.spectral_mode == SPECTRAL_CHANSCAN)317		ath9k_cmn_spectral_scan_trigger(common, &priv->spec_priv);318err:319	ath9k_htc_ps_restore(priv);320	return ret;321}322 323/*324 * Monitor mode handling is a tad complicated because the firmware requires325 * an interface to be created exclusively, while mac80211 doesn't associate326 * an interface with the mode.327 *328 * So, for now, only one monitor interface can be configured.329 */330static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)331{332	struct ath_common *common = ath9k_hw_common(priv->ah);333	struct ath9k_htc_target_vif hvif;334	int ret = 0;335	u8 cmd_rsp;336 337	memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));338	memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);339	hvif.index = priv->mon_vif_idx;340	WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);341	if (ret) {342		ath_err(common, "Unable to remove monitor interface at idx: %d\n",343			priv->mon_vif_idx);344	}345 346	priv->nvifs--;347	priv->vif_slot &= ~(1 << priv->mon_vif_idx);348}349 350static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)351{352	struct ath_common *common = ath9k_hw_common(priv->ah);353	struct ath9k_htc_target_vif hvif;354	struct ath9k_htc_target_sta tsta;355	int ret = 0, sta_idx;356	u8 cmd_rsp;357 358	if ((priv->nvifs >= ATH9K_HTC_MAX_VIF) ||359	    (priv->nstations >= ATH9K_HTC_MAX_STA)) {360		ret = -ENOBUFS;361		goto err_vif;362	}363 364	sta_idx = ffz(priv->sta_slot);365	if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA)) {366		ret = -ENOBUFS;367		goto err_vif;368	}369 370	/*371	 * Add an interface.372	 */373	memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));374	memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);375 376	hvif.opmode = HTC_M_MONITOR;377	hvif.index = ffz(priv->vif_slot);378 379	WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);380	if (ret)381		goto err_vif;382 383	/*384	 * Assign the monitor interface index as a special case here.385	 * This is needed when the interface is brought down.386	 */387	priv->mon_vif_idx = hvif.index;388	priv->vif_slot |= (1 << hvif.index);389 390	/*391	 * Set the hardware mode to monitor only if there are no392	 * other interfaces.393	 */394	if (!priv->nvifs)395		priv->ah->opmode = NL80211_IFTYPE_MONITOR;396 397	priv->nvifs++;398 399	/*400	 * Associate a station with the interface for packet injection.401	 */402	memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));403 404	memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);405 406	tsta.is_vif_sta = 1;407	tsta.sta_index = sta_idx;408	tsta.vif_index = hvif.index;409	tsta.maxampdu = cpu_to_be16(0xffff);410 411	WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);412	if (ret) {413		ath_err(common, "Unable to add station entry for monitor mode\n");414		goto err_sta;415	}416 417	priv->sta_slot |= (1 << sta_idx);418	priv->nstations++;419	priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx;420	priv->ah->is_monitoring = true;421 422	ath_dbg(common, CONFIG,423		"Attached a monitor interface at idx: %d, sta idx: %d\n",424		priv->mon_vif_idx, sta_idx);425 426	return 0;427 428err_sta:429	/*430	 * Remove the interface from the target.431	 */432	__ath9k_htc_remove_monitor_interface(priv);433err_vif:434	ath_dbg(common, FATAL, "Unable to attach a monitor interface\n");435 436	return ret;437}438 439static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)440{441	struct ath_common *common = ath9k_hw_common(priv->ah);442	int ret = 0;443	u8 cmd_rsp, sta_idx;444 445	__ath9k_htc_remove_monitor_interface(priv);446 447	sta_idx = priv->vif_sta_pos[priv->mon_vif_idx];448 449	WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);450	if (ret) {451		ath_err(common, "Unable to remove station entry for monitor mode\n");452		return ret;453	}454 455	priv->sta_slot &= ~(1 << sta_idx);456	priv->nstations--;457	priv->ah->is_monitoring = false;458 459	ath_dbg(common, CONFIG,460		"Removed a monitor interface at idx: %d, sta idx: %d\n",461		priv->mon_vif_idx, sta_idx);462 463	return 0;464}465 466static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,467				 struct ieee80211_vif *vif,468				 struct ieee80211_sta *sta)469{470	struct ath_common *common = ath9k_hw_common(priv->ah);471	struct ath9k_htc_target_sta tsta;472	struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;473	struct ath9k_htc_sta *ista;474	int ret, sta_idx;475	u8 cmd_rsp;476	u16 maxampdu;477 478	if (priv->nstations >= ATH9K_HTC_MAX_STA)479		return -ENOBUFS;480 481	sta_idx = ffz(priv->sta_slot);482	if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA))483		return -ENOBUFS;484 485	memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));486 487	if (sta) {488		ista = (struct ath9k_htc_sta *) sta->drv_priv;489		memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);490		memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);491		ista->index = sta_idx;492		tsta.is_vif_sta = 0;493		maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +494				 sta->deflink.ht_cap.ampdu_factor);495		tsta.maxampdu = cpu_to_be16(maxampdu);496	} else {497		memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);498		tsta.is_vif_sta = 1;499		tsta.maxampdu = cpu_to_be16(0xffff);500	}501 502	tsta.sta_index = sta_idx;503	tsta.vif_index = avp->index;504 505	WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);506	if (ret) {507		if (sta)508			ath_err(common,509				"Unable to add station entry for: %pM\n",510				sta->addr);511		return ret;512	}513 514	if (sta) {515		ath_dbg(common, CONFIG,516			"Added a station entry for: %pM (idx: %d)\n",517			sta->addr, tsta.sta_index);518	} else {519		ath_dbg(common, CONFIG,520			"Added a station entry for VIF %d (idx: %d)\n",521			avp->index, tsta.sta_index);522	}523 524	priv->sta_slot |= (1 << sta_idx);525	priv->nstations++;526	if (!sta)527		priv->vif_sta_pos[avp->index] = sta_idx;528 529	return 0;530}531 532static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,533				    struct ieee80211_vif *vif,534				    struct ieee80211_sta *sta)535{536	struct ath_common *common = ath9k_hw_common(priv->ah);537	struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;538	struct ath9k_htc_sta *ista;539	int ret;540	u8 cmd_rsp, sta_idx;541 542	if (sta) {543		ista = (struct ath9k_htc_sta *) sta->drv_priv;544		sta_idx = ista->index;545	} else {546		sta_idx = priv->vif_sta_pos[avp->index];547	}548 549	WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);550	if (ret) {551		if (sta)552			ath_err(common,553				"Unable to remove station entry for: %pM\n",554				sta->addr);555		return ret;556	}557 558	if (sta) {559		ath_dbg(common, CONFIG,560			"Removed a station entry for: %pM (idx: %d)\n",561			sta->addr, sta_idx);562	} else {563		ath_dbg(common, CONFIG,564			"Removed a station entry for VIF %d (idx: %d)\n",565			avp->index, sta_idx);566	}567 568	priv->sta_slot &= ~(1 << sta_idx);569	priv->nstations--;570 571	return 0;572}573 574int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,575				u8 enable_coex)576{577	struct ath9k_htc_cap_target tcap;578	int ret;579	u8 cmd_rsp;580 581	memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));582 583	tcap.ampdu_limit = cpu_to_be32(0xffff);584	tcap.ampdu_subframes = 0xff;585	tcap.enable_coex = enable_coex;586	tcap.tx_chainmask = priv->ah->caps.tx_chainmask;587 588	WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);589 590	return ret;591}592 593static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,594				 struct ieee80211_sta *sta,595				 struct ath9k_htc_target_rate *trate)596{597	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;598	struct ieee80211_supported_band *sband;599	u32 caps = 0;600	int i, j;601 602	sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band];603 604	for (i = 0, j = 0; i < sband->n_bitrates; i++) {605		if (sta->deflink.supp_rates[sband->band] & BIT(i)) {606			trate->rates.legacy_rates.rs_rates[j]607				= (sband->bitrates[i].bitrate * 2) / 10;608			j++;609		}610	}611	trate->rates.legacy_rates.rs_nrates = j;612 613	if (sta->deflink.ht_cap.ht_supported) {614		for (i = 0, j = 0; i < 77; i++) {615			if (sta->deflink.ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))616				trate->rates.ht_rates.rs_rates[j++] = i;617			if (j == ATH_HTC_RATE_MAX)618				break;619		}620		trate->rates.ht_rates.rs_nrates = j;621 622		caps = WLAN_RC_HT_FLAG;623		if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)624			caps |= ATH_RC_TX_STBC_FLAG;625		if (sta->deflink.ht_cap.mcs.rx_mask[1])626			caps |= WLAN_RC_DS_FLAG;627		if ((sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&628		    (conf_is_ht40(&priv->hw->conf)))629			caps |= WLAN_RC_40_FLAG;630		if (conf_is_ht40(&priv->hw->conf) &&631		    (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40))632			caps |= WLAN_RC_SGI_FLAG;633		else if (conf_is_ht20(&priv->hw->conf) &&634			 (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20))635			caps |= WLAN_RC_SGI_FLAG;636	}637 638	trate->sta_index = ista->index;639	trate->isnew = 1;640	trate->capflags = cpu_to_be32(caps);641}642 643static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,644				    struct ath9k_htc_target_rate *trate)645{646	struct ath_common *common = ath9k_hw_common(priv->ah);647	int ret;648	u8 cmd_rsp;649 650	WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);651	if (ret) {652		ath_err(common,653			"Unable to initialize Rate information on target\n");654	}655 656	return ret;657}658 659static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,660				struct ieee80211_sta *sta)661{662	struct ath_common *common = ath9k_hw_common(priv->ah);663	struct ath9k_htc_target_rate trate;664	int ret;665 666	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));667	ath9k_htc_setup_rate(priv, sta, &trate);668	ret = ath9k_htc_send_rate_cmd(priv, &trate);669	if (!ret)670		ath_dbg(common, CONFIG,671			"Updated target sta: %pM, rate caps: 0x%X\n",672			sta->addr, be32_to_cpu(trate.capflags));673}674 675static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,676				  struct ieee80211_vif *vif,677				  struct ieee80211_bss_conf *bss_conf)678{679	struct ath_common *common = ath9k_hw_common(priv->ah);680	struct ath9k_htc_target_rate trate;681	struct ieee80211_sta *sta;682	int ret;683 684	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));685 686	rcu_read_lock();687	sta = ieee80211_find_sta(vif, bss_conf->bssid);688	if (!sta) {689		rcu_read_unlock();690		return;691	}692	ath9k_htc_setup_rate(priv, sta, &trate);693	rcu_read_unlock();694 695	ret = ath9k_htc_send_rate_cmd(priv, &trate);696	if (!ret)697		ath_dbg(common, CONFIG,698			"Updated target sta: %pM, rate caps: 0x%X\n",699			bss_conf->bssid, be32_to_cpu(trate.capflags));700}701 702static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,703				  struct ieee80211_vif *vif,704				  struct ieee80211_sta *sta,705				  enum ieee80211_ampdu_mlme_action action,706				  u16 tid)707{708	struct ath_common *common = ath9k_hw_common(priv->ah);709	struct ath9k_htc_target_aggr aggr;710	struct ath9k_htc_sta *ista;711	int ret = 0;712	u8 cmd_rsp;713 714	if (tid >= ATH9K_HTC_MAX_TID)715		return -EINVAL;716 717	memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));718	ista = (struct ath9k_htc_sta *) sta->drv_priv;719 720	aggr.sta_index = ista->index;721	aggr.tidno = tid & 0xf;722	aggr.aggr_enable = action == IEEE80211_AMPDU_TX_START;723 724	WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);725	if (ret)726		ath_dbg(common, CONFIG,727			"Unable to %s TX aggregation for (%pM, %d)\n",728			(aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);729	else730		ath_dbg(common, CONFIG,731			"%s TX aggregation for (%pM, %d)\n",732			(aggr.aggr_enable) ? "Starting" : "Stopping",733			sta->addr, tid);734 735	spin_lock_bh(&priv->tx.tx_lock);736	ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;737	spin_unlock_bh(&priv->tx.tx_lock);738 739	return ret;740}741 742/*******/743/* ANI */744/*******/745 746void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)747{748	struct ath_common *common = ath9k_hw_common(priv->ah);749	unsigned long timestamp = jiffies_to_msecs(jiffies);750 751	common->ani.longcal_timer = timestamp;752	common->ani.shortcal_timer = timestamp;753	common->ani.checkani_timer = timestamp;754 755	set_bit(ATH_OP_ANI_RUN, &common->op_flags);756 757	ieee80211_queue_delayed_work(common->hw, &priv->ani_work,758				     msecs_to_jiffies(ATH_ANI_POLLINTERVAL));759}760 761void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv)762{763	struct ath_common *common = ath9k_hw_common(priv->ah);764	cancel_delayed_work_sync(&priv->ani_work);765	clear_bit(ATH_OP_ANI_RUN, &common->op_flags);766}767 768void ath9k_htc_ani_work(struct work_struct *work)769{770	struct ath9k_htc_priv *priv =771		container_of(work, struct ath9k_htc_priv, ani_work.work);772	struct ath_hw *ah = priv->ah;773	struct ath_common *common = ath9k_hw_common(ah);774	bool longcal = false;775	bool shortcal = false;776	bool aniflag = false;777	unsigned int timestamp = jiffies_to_msecs(jiffies);778	u32 cal_interval, short_cal_interval;779 780	short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?781		ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;782 783	/* Only calibrate if awake */784	if (ah->power_mode != ATH9K_PM_AWAKE)785		goto set_timer;786 787	/* Long calibration runs independently of short calibration. */788	if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {789		longcal = true;790		ath_dbg(common, ANI, "longcal @%lu\n", jiffies);791		common->ani.longcal_timer = timestamp;792	}793 794	/*795	 * Short calibration applies only while caldone796	 * is false or -ETIMEDOUT797	 */798	if (common->ani.caldone <= 0) {799		if ((timestamp - common->ani.shortcal_timer) >=800		    short_cal_interval) {801			shortcal = true;802			ath_dbg(common, ANI, "shortcal @%lu\n", jiffies);803			common->ani.shortcal_timer = timestamp;804			common->ani.resetcal_timer = timestamp;805		}806	} else {807		if ((timestamp - common->ani.resetcal_timer) >=808		    ATH_RESTART_CALINTERVAL) {809			common->ani.caldone = ath9k_hw_reset_calvalid(ah);810			if (common->ani.caldone)811				common->ani.resetcal_timer = timestamp;812		}813	}814 815	/* Verify whether we must check ANI */816	if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {817		aniflag = true;818		common->ani.checkani_timer = timestamp;819	}820 821	/* Skip all processing if there's nothing to do. */822	if (longcal || shortcal || aniflag) {823 824		ath9k_htc_ps_wakeup(priv);825 826		/* Call ANI routine if necessary */827		if (aniflag)828			ath9k_hw_ani_monitor(ah, ah->curchan);829 830		/* Perform calibration if necessary */831		if (longcal || shortcal)832			common->ani.caldone =833				ath9k_hw_calibrate(ah, ah->curchan,834						ah->rxchainmask, longcal) > 0;835 836		ath9k_htc_ps_restore(priv);837	}838 839set_timer:840	/*841	* Set timer interval based on previous results.842	* The interval must be the shortest necessary to satisfy ANI,843	* short calibration and long calibration.844	*/845	cal_interval = ATH_LONG_CALINTERVAL;846	cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);847	/*848	 * Short calibration applies only while caldone849	 * is false or -ETIMEDOUT850	 */851	if (common->ani.caldone <= 0)852		cal_interval = min(cal_interval, (u32)short_cal_interval);853 854	ieee80211_queue_delayed_work(common->hw, &priv->ani_work,855				     msecs_to_jiffies(cal_interval));856}857 858/**********************/859/* mac80211 Callbacks */860/**********************/861 862static void ath9k_htc_tx(struct ieee80211_hw *hw,863			 struct ieee80211_tx_control *control,864			 struct sk_buff *skb)865{866	struct ieee80211_hdr *hdr;867	struct ath9k_htc_priv *priv = hw->priv;868	struct ath_common *common = ath9k_hw_common(priv->ah);869	int padpos, padsize, ret, slot;870 871	hdr = (struct ieee80211_hdr *) skb->data;872 873	/* Add the padding after the header if this is not already done */874	padpos = ieee80211_hdrlen(hdr->frame_control);875	padsize = padpos & 3;876	if (padsize && skb->len > padpos) {877		if (skb_headroom(skb) < padsize) {878			ath_dbg(common, XMIT, "No room for padding\n");879			goto fail_tx;880		}881		skb_push(skb, padsize);882		memmove(skb->data, skb->data + padsize, padpos);883	}884 885	slot = ath9k_htc_tx_get_slot(priv);886	if (slot < 0) {887		ath_dbg(common, XMIT, "No free TX slot\n");888		goto fail_tx;889	}890 891	ret = ath9k_htc_tx_start(priv, control->sta, skb, slot, false);892	if (ret != 0) {893		ath_dbg(common, XMIT, "Tx failed\n");894		goto clear_slot;895	}896 897	ath9k_htc_check_stop_queues(priv);898 899	return;900 901clear_slot:902	ath9k_htc_tx_clear_slot(priv, slot);903fail_tx:904	dev_kfree_skb_any(skb);905}906 907static int ath9k_htc_start(struct ieee80211_hw *hw)908{909	struct ath9k_htc_priv *priv = hw->priv;910	struct ath_hw *ah = priv->ah;911	struct ath_common *common = ath9k_hw_common(ah);912	struct ieee80211_channel *curchan = hw->conf.chandef.chan;913	struct ath9k_channel *init_channel;914	int ret = 0;915	enum htc_phymode mode;916	__be16 htc_mode;917	u8 cmd_rsp;918 919	mutex_lock(&priv->mutex);920 921	ath_dbg(common, CONFIG,922		"Starting driver with initial channel: %d MHz\n",923		curchan->center_freq);924 925	/* Ensure that HW is awake before flushing RX */926	ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);927	WMI_CMD(WMI_FLUSH_RECV_CMDID);928 929	/* setup initial channel */930	init_channel = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef);931 932	ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);933	if (ret) {934		ath_err(common,935			"Unable to reset hardware; reset status %d (freq %u MHz)\n",936			ret, curchan->center_freq);937		mutex_unlock(&priv->mutex);938		return ret;939	}940 941	ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,942			       &priv->curtxpow);943 944	mode = ath9k_htc_get_curmode(priv, init_channel);945	htc_mode = cpu_to_be16(mode);946	WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);947	WMI_CMD(WMI_ATH_INIT_CMDID);948	WMI_CMD(WMI_START_RECV_CMDID);949 950	ath9k_host_rx_init(priv);951 952	ret = ath9k_htc_update_cap_target(priv, 0);953	if (ret)954		ath_dbg(common, CONFIG,955			"Failed to update capability in target\n");956 957	clear_bit(ATH_OP_INVALID, &common->op_flags);958	htc_start(priv->htc);959 960	spin_lock_bh(&priv->tx.tx_lock);961	priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;962	spin_unlock_bh(&priv->tx.tx_lock);963 964	ieee80211_wake_queues(hw);965 966	mod_timer(&priv->tx.cleanup_timer,967		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));968 969	ath9k_htc_start_btcoex(priv);970 971	mutex_unlock(&priv->mutex);972 973	return ret;974}975 976static void ath9k_htc_stop(struct ieee80211_hw *hw, bool suspend)977{978	struct ath9k_htc_priv *priv = hw->priv;979	struct ath_hw *ah = priv->ah;980	struct ath_common *common = ath9k_hw_common(ah);981	int ret __attribute__ ((unused));982	u8 cmd_rsp;983 984	mutex_lock(&priv->mutex);985 986	if (test_bit(ATH_OP_INVALID, &common->op_flags)) {987		ath_dbg(common, ANY, "Device not present\n");988		mutex_unlock(&priv->mutex);989		return;990	}991 992	ath9k_htc_ps_wakeup(priv);993 994	WMI_CMD(WMI_DISABLE_INTR_CMDID);995	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);996	WMI_CMD(WMI_STOP_RECV_CMDID);997 998	tasklet_kill(&priv->rx_tasklet);999 1000	del_timer_sync(&priv->tx.cleanup_timer);1001	ath9k_htc_tx_drain(priv);1002	ath9k_wmi_event_drain(priv);1003 1004	mutex_unlock(&priv->mutex);1005 1006	/* Cancel all the running timers/work .. */1007	cancel_work_sync(&priv->fatal_work);1008	cancel_work_sync(&priv->ps_work);1009 1010#ifdef CONFIG_MAC80211_LEDS1011	cancel_work_sync(&priv->led_work);1012#endif1013	ath9k_htc_stop_ani(priv);1014 1015	mutex_lock(&priv->mutex);1016 1017	ath9k_htc_stop_btcoex(priv);1018 1019	/* Remove a monitor interface if it's present. */1020	if (priv->ah->is_monitoring)1021		ath9k_htc_remove_monitor_interface(priv);1022 1023	ath9k_hw_phy_disable(ah);1024	ath9k_hw_disable(ah);1025	ath9k_htc_ps_restore(priv);1026	ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);1027 1028	set_bit(ATH_OP_INVALID, &common->op_flags);1029 1030	ath_dbg(common, CONFIG, "Driver halt\n");1031	mutex_unlock(&priv->mutex);1032}1033 1034static int ath9k_htc_add_interface(struct ieee80211_hw *hw,1035				   struct ieee80211_vif *vif)1036{1037	struct ath9k_htc_priv *priv = hw->priv;1038	struct ath9k_htc_vif *avp = (void *)vif->drv_priv;1039	struct ath_common *common = ath9k_hw_common(priv->ah);1040	struct ath9k_htc_target_vif hvif;1041	int ret = 0;1042	u8 cmd_rsp;1043 1044	mutex_lock(&priv->mutex);1045 1046	ath9k_htc_ps_wakeup(priv);1047	memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));1048	memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);1049 1050	switch (vif->type) {1051	case NL80211_IFTYPE_STATION:1052		hvif.opmode = HTC_M_STA;1053		break;1054	case NL80211_IFTYPE_ADHOC:1055		hvif.opmode = HTC_M_IBSS;1056		break;1057	case NL80211_IFTYPE_AP:1058		hvif.opmode = HTC_M_HOSTAP;1059		break;1060	case NL80211_IFTYPE_MESH_POINT:1061		hvif.opmode = HTC_M_WDS;	/* close enough */1062		break;1063	default:1064		ath_err(common,1065			"Interface type %d not yet supported\n", vif->type);1066		ret = -EOPNOTSUPP;1067		goto out;1068	}1069 1070	/* Index starts from zero on the target */1071	avp->index = hvif.index = ffz(priv->vif_slot);1072	hvif.rtsthreshold = cpu_to_be16(2304);1073	WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);1074	if (ret)1075		goto out;1076 1077	/*1078	 * We need a node in target to tx mgmt frames1079	 * before association.1080	 */1081	ret = ath9k_htc_add_station(priv, vif, NULL);1082	if (ret) {1083		WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);1084		goto out;1085	}1086 1087	ath9k_htc_set_mac_bssid_mask(priv, vif);1088 1089	priv->vif_slot |= (1 << avp->index);1090	priv->nvifs++;1091 1092	INC_VIF(priv, vif->type);1093 1094	if ((vif->type == NL80211_IFTYPE_AP) ||1095	    (vif->type == NL80211_IFTYPE_MESH_POINT) ||1096	    (vif->type == NL80211_IFTYPE_ADHOC))1097		ath9k_htc_assign_bslot(priv, vif);1098 1099	ath9k_htc_set_opmode(priv);1100 1101	if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&1102	    !test_bit(ATH_OP_ANI_RUN, &common->op_flags)) {1103		ath9k_hw_set_tsfadjust(priv->ah, true);1104		ath9k_htc_start_ani(priv);1105	}1106 1107	ath_dbg(common, CONFIG, "Attach a VIF of type: %d at idx: %d\n",1108		vif->type, avp->index);1109 1110out:1111	ath9k_htc_ps_restore(priv);1112	mutex_unlock(&priv->mutex);1113 1114	return ret;1115}1116 1117static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,1118				       struct ieee80211_vif *vif)1119{1120	struct ath9k_htc_priv *priv = hw->priv;1121	struct ath_common *common = ath9k_hw_common(priv->ah);1122	struct ath9k_htc_vif *avp = (void *)vif->drv_priv;1123	struct ath9k_htc_target_vif hvif;1124	int ret = 0;1125	u8 cmd_rsp;1126 1127	mutex_lock(&priv->mutex);1128	ath9k_htc_ps_wakeup(priv);1129 1130	memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));1131	memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);1132	hvif.index = avp->index;1133	WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);1134	if (ret) {1135		ath_err(common, "Unable to remove interface at idx: %d\n",1136			avp->index);1137	}1138	priv->nvifs--;1139	priv->vif_slot &= ~(1 << avp->index);1140 1141	if (priv->csa_vif == vif)1142		priv->csa_vif = NULL;1143 1144	ath9k_htc_remove_station(priv, vif, NULL);1145 1146	DEC_VIF(priv, vif->type);1147 1148	if ((vif->type == NL80211_IFTYPE_AP) ||1149	     vif->type == NL80211_IFTYPE_MESH_POINT ||1150	    (vif->type == NL80211_IFTYPE_ADHOC))1151		ath9k_htc_remove_bslot(priv, vif);1152 1153	ath9k_htc_set_opmode(priv);1154 1155	ath9k_htc_set_mac_bssid_mask(priv, vif);1156 1157	/*1158	 * Stop ANI only if there are no associated station interfaces.1159	 */1160	if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {1161		priv->rearm_ani = false;1162		ieee80211_iterate_active_interfaces_atomic(1163			priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,1164			ath9k_htc_vif_iter, priv);1165		if (!priv->rearm_ani)1166			ath9k_htc_stop_ani(priv);1167	}1168 1169	ath_dbg(common, CONFIG, "Detach Interface at idx: %d\n", avp->index);1170 1171	ath9k_htc_ps_restore(priv);1172	mutex_unlock(&priv->mutex);1173}1174 1175static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)1176{1177	struct ath9k_htc_priv *priv = hw->priv;1178	struct ath_common *common = ath9k_hw_common(priv->ah);1179	struct ieee80211_conf *conf = &hw->conf;1180	bool chip_reset = false;1181	int ret = 0;1182 1183	mutex_lock(&priv->mutex);1184	ath9k_htc_ps_wakeup(priv);1185 1186	if (changed & IEEE80211_CONF_CHANGE_IDLE) {1187		mutex_lock(&priv->htc_pm_lock);1188 1189		priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);1190		if (!priv->ps_idle)1191			chip_reset = true;1192 1193		mutex_unlock(&priv->htc_pm_lock);1194	}1195 1196	/*1197	 * Monitor interface should be added before1198	 * IEEE80211_CONF_CHANGE_CHANNEL is handled.1199	 */1200	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {1201		if ((conf->flags & IEEE80211_CONF_MONITOR) &&1202		    !priv->ah->is_monitoring)1203			ath9k_htc_add_monitor_interface(priv);1204		else if (priv->ah->is_monitoring)1205			ath9k_htc_remove_monitor_interface(priv);1206	}1207 1208	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) {1209		struct ieee80211_channel *curchan = hw->conf.chandef.chan;1210		int pos = curchan->hw_value;1211 1212		ath_dbg(common, CONFIG, "Set channel: %d MHz\n",1213			curchan->center_freq);1214 1215		ath9k_cmn_get_channel(hw, priv->ah, &hw->conf.chandef);1216		if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {1217			ath_err(common, "Unable to set channel\n");1218			ret = -EINVAL;1219			goto out;1220		}1221 1222	}1223 1224	if (changed & IEEE80211_CONF_CHANGE_PS) {1225		if (conf->flags & IEEE80211_CONF_PS) {1226			ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);1227			priv->ps_enabled = true;1228		} else {1229			priv->ps_enabled = false;1230			cancel_work_sync(&priv->ps_work);1231			ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);1232		}1233	}1234 1235	if (changed & IEEE80211_CONF_CHANGE_POWER) {1236		priv->txpowlimit = 2 * conf->power_level;1237		ath9k_cmn_update_txpow(priv->ah, priv->curtxpow,1238				       priv->txpowlimit, &priv->curtxpow);1239	}1240 1241out:1242	ath9k_htc_ps_restore(priv);1243	mutex_unlock(&priv->mutex);1244	return ret;1245}1246 1247#define SUPPORTED_FILTERS			\1248	(FIF_ALLMULTI |				\1249	FIF_CONTROL |				\1250	FIF_PSPOLL |				\1251	FIF_OTHER_BSS |				\1252	FIF_BCN_PRBRESP_PROMISC |		\1253	FIF_PROBE_REQ |				\1254	FIF_MCAST_ACTION |			\1255	FIF_FCSFAIL)1256 1257static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,1258				       unsigned int changed_flags,1259				       unsigned int *total_flags,1260				       u64 multicast)1261{1262	struct ath9k_htc_priv *priv = hw->priv;1263	struct ath_common *common = ath9k_hw_common(priv->ah);1264	u32 rfilt;1265 1266	mutex_lock(&priv->mutex);1267	*total_flags &= SUPPORTED_FILTERS;1268 1269	if (test_bit(ATH_OP_INVALID, &common->op_flags)) {1270		ath_dbg(ath9k_hw_common(priv->ah), ANY,1271			"Unable to configure filter on invalid state\n");1272		mutex_unlock(&priv->mutex);1273		return;1274	}1275	ath9k_htc_ps_wakeup(priv);1276 1277	priv->rxfilter = *total_flags;1278	rfilt = ath9k_htc_calcrxfilter(priv);1279	ath9k_hw_setrxfilter(priv->ah, rfilt);1280 1281	ath_dbg(ath9k_hw_common(priv->ah), CONFIG, "Set HW RX filter: 0x%x\n",1282		rfilt);1283 1284	ath9k_htc_ps_restore(priv);1285	mutex_unlock(&priv->mutex);1286}1287 1288static void ath9k_htc_sta_rc_update_work(struct work_struct *work)1289{1290	struct ath9k_htc_sta *ista =1291	    container_of(work, struct ath9k_htc_sta, rc_update_work);1292	struct ieee80211_sta *sta =1293	    container_of((void *)ista, struct ieee80211_sta, drv_priv);1294	struct ath9k_htc_priv *priv = ista->htc_priv;1295	struct ath_common *common = ath9k_hw_common(priv->ah);1296	struct ath9k_htc_target_rate trate;1297 1298	mutex_lock(&priv->mutex);1299	ath9k_htc_ps_wakeup(priv);1300 1301	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));1302	ath9k_htc_setup_rate(priv, sta, &trate);1303	if (!ath9k_htc_send_rate_cmd(priv, &trate))1304		ath_dbg(common, CONFIG,1305			"Supported rates for sta: %pM updated, rate caps: 0x%X\n",1306			sta->addr, be32_to_cpu(trate.capflags));1307	else1308		ath_dbg(common, CONFIG,1309			"Unable to update supported rates for sta: %pM\n",1310			sta->addr);1311 1312	ath9k_htc_ps_restore(priv);1313	mutex_unlock(&priv->mutex);1314}1315 1316static int ath9k_htc_sta_add(struct ieee80211_hw *hw,1317			     struct ieee80211_vif *vif,1318			     struct ieee80211_sta *sta)1319{1320	struct ath9k_htc_priv *priv = hw->priv;1321	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;1322	int ret;1323 1324	mutex_lock(&priv->mutex);1325	ath9k_htc_ps_wakeup(priv);1326	ret = ath9k_htc_add_station(priv, vif, sta);1327	if (!ret) {1328		INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work);1329		ista->htc_priv = priv;1330		ath9k_htc_init_rate(priv, sta);1331	}1332	ath9k_htc_ps_restore(priv);1333	mutex_unlock(&priv->mutex);1334 1335	return ret;1336}1337 1338static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,1339				struct ieee80211_vif *vif,1340				struct ieee80211_sta *sta)1341{1342	struct ath9k_htc_priv *priv = hw->priv;1343	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;1344	int ret;1345 1346	cancel_work_sync(&ista->rc_update_work);1347 1348	mutex_lock(&priv->mutex);1349	ath9k_htc_ps_wakeup(priv);1350	htc_sta_drain(priv->htc, ista->index);1351	ret = ath9k_htc_remove_station(priv, vif, sta);1352	ath9k_htc_ps_restore(priv);1353	mutex_unlock(&priv->mutex);1354 1355	return ret;1356}1357 1358static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,1359				    struct ieee80211_vif *vif,1360				    struct ieee80211_sta *sta, u32 changed)1361{1362	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;1363 1364	if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))1365		return;1366 1367	schedule_work(&ista->rc_update_work);1368}1369 1370static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,1371			     struct ieee80211_vif *vif,1372			     unsigned int link_id, u16 queue,1373			     const struct ieee80211_tx_queue_params *params)1374{1375	struct ath9k_htc_priv *priv = hw->priv;1376	struct ath_common *common = ath9k_hw_common(priv->ah);1377	struct ath9k_tx_queue_info qi;1378	int ret = 0, qnum;1379 1380	if (queue >= IEEE80211_NUM_ACS)1381		return 0;1382 1383	mutex_lock(&priv->mutex);1384	ath9k_htc_ps_wakeup(priv);1385 1386	memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));1387 1388	qi.tqi_aifs = params->aifs;1389	qi.tqi_cwmin = params->cw_min;1390	qi.tqi_cwmax = params->cw_max;1391	qi.tqi_burstTime = params->txop * 32;1392 1393	qnum = get_hw_qnum(queue, priv->hwq_map);1394 1395	ath_dbg(common, CONFIG,1396		"Configure tx [queue/hwq] [%d/%d],  aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",1397		queue, qnum, params->aifs, params->cw_min,1398		params->cw_max, params->txop);1399 1400	ret = ath_htc_txq_update(priv, qnum, &qi);1401	if (ret) {1402		ath_err(common, "TXQ Update failed\n");1403		goto out;1404	}1405 1406	if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&1407	    (qnum == priv->hwq_map[IEEE80211_AC_BE]))1408		    ath9k_htc_beaconq_config(priv);1409out:1410	ath9k_htc_ps_restore(priv);1411	mutex_unlock(&priv->mutex);1412 1413	return ret;1414}1415 1416static int ath9k_htc_set_key(struct ieee80211_hw *hw,1417			     enum set_key_cmd cmd,1418			     struct ieee80211_vif *vif,1419			     struct ieee80211_sta *sta,1420			     struct ieee80211_key_conf *key)1421{1422	struct ath9k_htc_priv *priv = hw->priv;1423	struct ath_common *common = ath9k_hw_common(priv->ah);1424	int ret = 0;1425 1426	if (htc_modparam_nohwcrypt)1427		return -ENOSPC;1428 1429	if ((vif->type == NL80211_IFTYPE_ADHOC ||1430	     vif->type == NL80211_IFTYPE_MESH_POINT) &&1431	    (key->cipher == WLAN_CIPHER_SUITE_TKIP ||1432	     key->cipher == WLAN_CIPHER_SUITE_CCMP) &&1433	    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {1434		/*1435		 * For now, disable hw crypto for the RSN IBSS group keys. This1436		 * could be optimized in the future to use a modified key cache1437		 * design to support per-STA RX GTK, but until that gets1438		 * implemented, use of software crypto for group addressed1439		 * frames is a acceptable to allow RSN IBSS to be used.1440		 */1441		return -EOPNOTSUPP;1442	}1443 1444	mutex_lock(&priv->mutex);1445	ath_dbg(common, CONFIG, "Set HW Key\n");1446	ath9k_htc_ps_wakeup(priv);1447 1448	switch (cmd) {1449	case SET_KEY:1450		ret = ath_key_config(common, vif, sta, key);1451		if (ret >= 0) {1452			key->hw_key_idx = ret;1453			/* push IV and Michael MIC generation to stack */1454			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;1455			if (key->cipher == WLAN_CIPHER_SUITE_TKIP)1456				key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;1457			if (priv->ah->sw_mgmt_crypto_tx &&1458			    key->cipher == WLAN_CIPHER_SUITE_CCMP)1459				key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;1460			ret = 0;1461		}1462		break;1463	case DISABLE_KEY:1464		ath_key_delete(common, key->hw_key_idx);1465		break;1466	default:1467		ret = -EINVAL;1468	}1469 1470	ath9k_htc_ps_restore(priv);1471	mutex_unlock(&priv->mutex);1472 1473	return ret;1474}1475 1476static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv)1477{1478	struct ath_common *common = ath9k_hw_common(priv->ah);1479 1480	ath9k_hw_write_associd(priv->ah);1481	ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n",1482		common->curbssid, common->curaid);1483}1484 1485static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)1486{1487	struct ath9k_htc_priv *priv = data;1488	struct ath_common *common = ath9k_hw_common(priv->ah);1489	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;1490 1491	if ((vif->type == NL80211_IFTYPE_STATION) && vif->cfg.assoc) {1492		common->curaid = vif->cfg.aid;1493		common->last_rssi = ATH_RSSI_DUMMY_MARKER;1494		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);1495		set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);1496	}1497}1498 1499static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)1500{1501	if (priv->num_sta_assoc_vif == 1) {1502		ieee80211_iterate_active_interfaces_atomic(1503			priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,1504			ath9k_htc_bss_iter, priv);1505		ath9k_htc_set_bssid(priv);1506	}1507}1508 1509static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,1510				       struct ieee80211_vif *vif,1511				       struct ieee80211_bss_conf *bss_conf,1512				       u64 changed)1513{1514	struct ath9k_htc_priv *priv = hw->priv;1515	struct ath_hw *ah = priv->ah;1516	struct ath_common *common = ath9k_hw_common(ah);1517	int slottime;1518 1519	mutex_lock(&priv->mutex);1520	ath9k_htc_ps_wakeup(priv);1521 1522	if (changed & BSS_CHANGED_ASSOC) {1523		ath_dbg(common, CONFIG, "BSS Changed ASSOC %d\n",1524			vif->cfg.assoc);1525 1526		vif->cfg.assoc ?1527			priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--;1528 1529		if (!vif->cfg.assoc)1530			clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);1531 1532		if (priv->ah->opmode == NL80211_IFTYPE_STATION) {1533			ath9k_htc_choose_set_bssid(priv);1534			if (vif->cfg.assoc && (priv->num_sta_assoc_vif == 1))1535				ath9k_htc_start_ani(priv);1536			else if (priv->num_sta_assoc_vif == 0)1537				ath9k_htc_stop_ani(priv);1538		}1539	}1540 1541	if (changed & BSS_CHANGED_IBSS) {1542		if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {1543			common->curaid = vif->cfg.aid;1544			memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);1545			ath9k_htc_set_bssid(priv);1546		}1547	}1548 1549	if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {1550		ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n",1551			bss_conf->bssid);1552		ath9k_htc_set_tsfadjust(priv, vif);1553		priv->cur_beacon_conf.enable_beacon = 1;1554		ath9k_htc_beacon_config(priv, vif);1555	}1556 1557	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {1558		/*1559		 * Disable SWBA interrupt only if there are no1560		 * concurrent AP/mesh or IBSS interfaces.1561		 */1562		if ((priv->num_ap_vif + priv->num_mbss_vif <= 1) ||1563		     priv->num_ibss_vif) {1564			ath_dbg(common, CONFIG,1565				"Beacon disabled for BSS: %pM\n",1566				bss_conf->bssid);1567			priv->cur_beacon_conf.enable_beacon = 0;1568			ath9k_htc_beacon_config(priv, vif);1569		}1570	}1571 1572	if (changed & BSS_CHANGED_BEACON_INT) {1573		/*1574		 * Reset the HW TSF for the first AP or mesh interface.1575		 */1576		if (priv->nvifs == 1 &&1577		    ((priv->ah->opmode == NL80211_IFTYPE_AP &&1578		      vif->type == NL80211_IFTYPE_AP &&1579		      priv->num_ap_vif == 1) ||1580		    (priv->ah->opmode == NL80211_IFTYPE_MESH_POINT &&1581		      vif->type == NL80211_IFTYPE_MESH_POINT &&1582		      priv->num_mbss_vif == 1))) {1583			set_bit(OP_TSF_RESET, &priv->op_flags);1584		}1585		ath_dbg(common, CONFIG,1586			"Beacon interval changed for BSS: %pM\n",1587			bss_conf->bssid);1588		ath9k_htc_beacon_config(priv, vif);1589	}1590 1591	if (changed & BSS_CHANGED_ERP_SLOT) {1592		if (bss_conf->use_short_slot)1593			slottime = 9;1594		else1595			slottime = 20;1596		if (vif->type == NL80211_IFTYPE_AP) {1597			/*1598			 * Defer update, so that connected stations can adjust1599			 * their settings at the same time.1600			 * See beacon.c for more details1601			 */1602			priv->beacon.slottime = slottime;1603			priv->beacon.updateslot = UPDATE;1604		} else {1605			ah->slottime = slottime;1606			ath9k_hw_init_global_settings(ah);1607		}1608	}1609 1610	if (changed & BSS_CHANGED_HT)1611		ath9k_htc_update_rate(priv, vif, bss_conf);1612 1613	ath9k_htc_ps_restore(priv);1614	mutex_unlock(&priv->mutex);1615}1616 1617static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw,1618			     struct ieee80211_vif *vif)1619{1620	struct ath9k_htc_priv *priv = hw->priv;1621	u64 tsf;1622 1623	mutex_lock(&priv->mutex);1624	ath9k_htc_ps_wakeup(priv);1625	tsf = ath9k_hw_gettsf64(priv->ah);1626	ath9k_htc_ps_restore(priv);1627	mutex_unlock(&priv->mutex);1628 1629	return tsf;1630}1631 1632static void ath9k_htc_set_tsf(struct ieee80211_hw *hw,1633			      struct ieee80211_vif *vif, u64 tsf)1634{1635	struct ath9k_htc_priv *priv = hw->priv;1636 1637	mutex_lock(&priv->mutex);1638	ath9k_htc_ps_wakeup(priv);1639	ath9k_hw_settsf64(priv->ah, tsf);1640	ath9k_htc_ps_restore(priv);1641	mutex_unlock(&priv->mutex);1642}1643 1644static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw,1645				struct ieee80211_vif *vif)1646{1647	struct ath9k_htc_priv *priv = hw->priv;1648 1649	mutex_lock(&priv->mutex);1650	ath9k_htc_ps_wakeup(priv);1651	ath9k_hw_reset_tsf(priv->ah);1652	ath9k_htc_ps_restore(priv);1653	mutex_unlock(&priv->mutex);1654}1655 1656static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,1657				  struct ieee80211_vif *vif,1658				  struct ieee80211_ampdu_params *params)1659{1660	struct ath9k_htc_priv *priv = hw->priv;1661	struct ath9k_htc_sta *ista;1662	int ret = 0;1663	struct ieee80211_sta *sta = params->sta;1664	enum ieee80211_ampdu_mlme_action action = params->action;1665	u16 tid = params->tid;1666 1667	mutex_lock(&priv->mutex);1668	ath9k_htc_ps_wakeup(priv);1669 1670	switch (action) {1671	case IEEE80211_AMPDU_RX_START:1672		break;1673	case IEEE80211_AMPDU_RX_STOP:1674		break;1675	case IEEE80211_AMPDU_TX_START:1676		ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);1677		if (!ret)1678			ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;1679		break;1680	case IEEE80211_AMPDU_TX_STOP_CONT:1681	case IEEE80211_AMPDU_TX_STOP_FLUSH:1682	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:1683		ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);1684		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);1685		break;1686	case IEEE80211_AMPDU_TX_OPERATIONAL:1687		if (tid >= ATH9K_HTC_MAX_TID) {1688			ret = -EINVAL;1689			break;1690		}1691		ista = (struct ath9k_htc_sta *) sta->drv_priv;1692		spin_lock_bh(&priv->tx.tx_lock);1693		ista->tid_state[tid] = AGGR_OPERATIONAL;1694		spin_unlock_bh(&priv->tx.tx_lock);1695		break;1696	default:1697		ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");1698	}1699 1700	ath9k_htc_ps_restore(priv);1701	mutex_unlock(&priv->mutex);1702 1703	return ret;1704}1705 1706static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw,1707				    struct ieee80211_vif *vif,1708				    const u8 *mac_addr)1709{1710	struct ath9k_htc_priv *priv = hw->priv;1711	struct ath_common *common = ath9k_hw_common(priv->ah);1712 1713	mutex_lock(&priv->mutex);1714	spin_lock_bh(&priv->beacon_lock);1715	set_bit(ATH_OP_SCANNING, &common->op_flags);1716	spin_unlock_bh(&priv->beacon_lock);1717	cancel_work_sync(&priv->ps_work);1718	ath9k_htc_stop_ani(priv);1719	mutex_unlock(&priv->mutex);1720}1721 1722static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw,1723				       struct ieee80211_vif *vif)1724{1725	struct ath9k_htc_priv *priv = hw->priv;1726	struct ath_common *common = ath9k_hw_common(priv->ah);1727 1728	mutex_lock(&priv->mutex);1729	spin_lock_bh(&priv->beacon_lock);1730	clear_bit(ATH_OP_SCANNING, &common->op_flags);1731	spin_unlock_bh(&priv->beacon_lock);1732	ath9k_htc_ps_wakeup(priv);1733	ath9k_htc_vif_reconfig(priv);1734	ath9k_htc_ps_restore(priv);1735	mutex_unlock(&priv->mutex);1736}1737 1738static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)1739{1740	return 0;1741}1742 1743static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,1744					 s16 coverage_class)1745{1746	struct ath9k_htc_priv *priv = hw->priv;1747 1748	mutex_lock(&priv->mutex);1749	ath9k_htc_ps_wakeup(priv);1750	priv->ah->coverage_class = coverage_class;1751	ath9k_hw_init_global_settings(priv->ah);1752	ath9k_htc_ps_restore(priv);1753	mutex_unlock(&priv->mutex);1754}1755 1756/*1757 * Currently, this is used only for selecting the minimum rate1758 * for management frames, rate selection for data frames remain1759 * unaffected.1760 */1761static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,1762				      struct ieee80211_vif *vif,1763				      const struct cfg80211_bitrate_mask *mask)1764{1765	struct ath9k_htc_priv *priv = hw->priv;1766	struct ath_common *common = ath9k_hw_common(priv->ah);1767	struct ath9k_htc_target_rate_mask tmask;1768	struct ath9k_htc_vif *avp = (void *)vif->drv_priv;1769	int ret = 0;1770	u8 cmd_rsp;1771 1772	memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));1773 1774	tmask.vif_index = avp->index;1775	tmask.band = NL80211_BAND_2GHZ;1776	tmask.mask = cpu_to_be32(mask->control[NL80211_BAND_2GHZ].legacy);1777 1778	WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);1779	if (ret) {1780		ath_err(common,1781			"Unable to set 2G rate mask for "1782			"interface at idx: %d\n", avp->index);1783		goto out;1784	}1785 1786	tmask.band = NL80211_BAND_5GHZ;1787	tmask.mask = cpu_to_be32(mask->control[NL80211_BAND_5GHZ].legacy);1788 1789	WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);1790	if (ret) {1791		ath_err(common,1792			"Unable to set 5G rate mask for "1793			"interface at idx: %d\n", avp->index);1794		goto out;1795	}1796 1797	ath_dbg(common, CONFIG, "Set bitrate masks: 0x%x, 0x%x\n",1798		mask->control[NL80211_BAND_2GHZ].legacy,1799		mask->control[NL80211_BAND_5GHZ].legacy);1800out:1801	return ret;1802}1803 1804 1805static int ath9k_htc_get_stats(struct ieee80211_hw *hw,1806			       struct ieee80211_low_level_stats *stats)1807{1808	struct ath9k_htc_priv *priv = hw->priv;1809	struct ath_hw *ah = priv->ah;1810	struct ath9k_mib_stats *mib_stats = &ah->ah_mibStats;1811 1812	stats->dot11ACKFailureCount = mib_stats->ackrcv_bad;1813	stats->dot11RTSFailureCount = mib_stats->rts_bad;1814	stats->dot11FCSErrorCount = mib_stats->fcs_bad;1815	stats->dot11RTSSuccessCount = mib_stats->rts_good;1816 1817	return 0;1818}1819 1820struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv)1821{1822	struct base_eep_header *pBase = NULL;1823	/*1824	 * This can be done since all the 3 EEPROM families have the1825	 * same base header upto a certain point, and we are interested in1826	 * the data only upto that point.1827	 */1828 1829	if (AR_SREV_9271(priv->ah))1830		pBase = (struct base_eep_header *)1831			&priv->ah->eeprom.map4k.baseEepHeader;1832	else if (priv->ah->hw_version.usbdev == AR9280_USB)1833		pBase = (struct base_eep_header *)1834			&priv->ah->eeprom.def.baseEepHeader;1835	else if (priv->ah->hw_version.usbdev == AR9287_USB)1836		pBase = (struct base_eep_header *)1837			&priv->ah->eeprom.map9287.baseEepHeader;1838	return pBase;1839}1840 1841 1842static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,1843				 u32 *rx_ant)1844{1845	struct ath9k_htc_priv *priv = hw->priv;1846	struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv);1847	if (pBase) {1848		*tx_ant = pBase->txMask;1849		*rx_ant = pBase->rxMask;1850	} else {1851		*tx_ant = 0;1852		*rx_ant = 0;1853	}1854	return 0;1855}1856 1857static void ath9k_htc_channel_switch_beacon(struct ieee80211_hw *hw,1858					    struct ieee80211_vif *vif,1859					    struct cfg80211_chan_def *chandef)1860{1861	struct ath9k_htc_priv *priv = hw->priv;1862 1863	/* mac80211 does not support CSA in multi-if cases (yet) */1864	if (WARN_ON(priv->csa_vif))1865		return;1866 1867	priv->csa_vif = vif;1868}1869 1870struct ieee80211_ops ath9k_htc_ops = {1871	.add_chanctx = ieee80211_emulate_add_chanctx,1872	.remove_chanctx = ieee80211_emulate_remove_chanctx,1873	.change_chanctx = ieee80211_emulate_change_chanctx,1874	.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,1875	.tx                 = ath9k_htc_tx,1876	.wake_tx_queue      = ieee80211_handle_wake_tx_queue,1877	.start              = ath9k_htc_start,1878	.stop               = ath9k_htc_stop,1879	.add_interface      = ath9k_htc_add_interface,1880	.remove_interface   = ath9k_htc_remove_interface,1881	.config             = ath9k_htc_config,1882	.configure_filter   = ath9k_htc_configure_filter,1883	.sta_add            = ath9k_htc_sta_add,1884	.sta_remove         = ath9k_htc_sta_remove,1885	.conf_tx            = ath9k_htc_conf_tx,1886	.sta_rc_update      = ath9k_htc_sta_rc_update,1887	.bss_info_changed   = ath9k_htc_bss_info_changed,1888	.set_key            = ath9k_htc_set_key,1889	.get_tsf            = ath9k_htc_get_tsf,1890	.set_tsf            = ath9k_htc_set_tsf,1891	.reset_tsf          = ath9k_htc_reset_tsf,1892	.ampdu_action       = ath9k_htc_ampdu_action,1893	.sw_scan_start      = ath9k_htc_sw_scan_start,1894	.sw_scan_complete   = ath9k_htc_sw_scan_complete,1895	.set_rts_threshold  = ath9k_htc_set_rts_threshold,1896	.rfkill_poll        = ath9k_htc_rfkill_poll_state,1897	.set_coverage_class = ath9k_htc_set_coverage_class,1898	.set_bitrate_mask   = ath9k_htc_set_bitrate_mask,1899	.get_stats	    = ath9k_htc_get_stats,1900	.get_antenna	    = ath9k_htc_get_antenna,1901	.channel_switch_beacon	= ath9k_htc_channel_switch_beacon,1902 1903#ifdef CONFIG_ATH9K_HTC_DEBUGFS1904	.get_et_sset_count  = ath9k_htc_get_et_sset_count,1905	.get_et_stats       = ath9k_htc_get_et_stats,1906	.get_et_strings     = ath9k_htc_get_et_strings,1907#endif1908};1909