1fb9987d0SSujith /*
2fb9987d0SSujith  * Copyright (c) 2010 Atheros Communications Inc.
3fb9987d0SSujith  *
4fb9987d0SSujith  * Permission to use, copy, modify, and/or distribute this software for any
5fb9987d0SSujith  * purpose with or without fee is hereby granted, provided that the above
6fb9987d0SSujith  * copyright notice and this permission notice appear in all copies.
7fb9987d0SSujith  *
8fb9987d0SSujith  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9fb9987d0SSujith  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10fb9987d0SSujith  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11fb9987d0SSujith  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12fb9987d0SSujith  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13fb9987d0SSujith  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14fb9987d0SSujith  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15fb9987d0SSujith  */
16fb9987d0SSujith 
17fb9987d0SSujith #include "htc.h"
18fb9987d0SSujith 
19fb9987d0SSujith MODULE_AUTHOR("Atheros Communications");
20fb9987d0SSujith MODULE_LICENSE("Dual BSD/GPL");
21fb9987d0SSujith MODULE_DESCRIPTION("Atheros driver 802.11n HTC based wireless devices");
22fb9987d0SSujith 
23fb9987d0SSujith static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
24fb9987d0SSujith module_param_named(debug, ath9k_debug, uint, 0);
25fb9987d0SSujith MODULE_PARM_DESC(debug, "Debugging mask");
26fb9987d0SSujith 
27e1572c5eSSujith int htc_modparam_nohwcrypt;
28e1572c5eSSujith module_param_named(nohwcrypt, htc_modparam_nohwcrypt, int, 0444);
29fb9987d0SSujith MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
30fb9987d0SSujith 
31fb9987d0SSujith #define CHAN2G(_freq, _idx)  { \
32fb9987d0SSujith 	.center_freq = (_freq), \
33fb9987d0SSujith 	.hw_value = (_idx), \
34fb9987d0SSujith 	.max_power = 20, \
35fb9987d0SSujith }
36fb9987d0SSujith 
37ea46e644SSujith #define CHAN5G(_freq, _idx) { \
38ea46e644SSujith 	.band = IEEE80211_BAND_5GHZ, \
39ea46e644SSujith 	.center_freq = (_freq), \
40ea46e644SSujith 	.hw_value = (_idx), \
41ea46e644SSujith 	.max_power = 20, \
42ea46e644SSujith }
43ea46e644SSujith 
44fb9987d0SSujith static struct ieee80211_channel ath9k_2ghz_channels[] = {
45fb9987d0SSujith 	CHAN2G(2412, 0), /* Channel 1 */
46fb9987d0SSujith 	CHAN2G(2417, 1), /* Channel 2 */
47fb9987d0SSujith 	CHAN2G(2422, 2), /* Channel 3 */
48fb9987d0SSujith 	CHAN2G(2427, 3), /* Channel 4 */
49fb9987d0SSujith 	CHAN2G(2432, 4), /* Channel 5 */
50fb9987d0SSujith 	CHAN2G(2437, 5), /* Channel 6 */
51fb9987d0SSujith 	CHAN2G(2442, 6), /* Channel 7 */
52fb9987d0SSujith 	CHAN2G(2447, 7), /* Channel 8 */
53fb9987d0SSujith 	CHAN2G(2452, 8), /* Channel 9 */
54fb9987d0SSujith 	CHAN2G(2457, 9), /* Channel 10 */
55fb9987d0SSujith 	CHAN2G(2462, 10), /* Channel 11 */
56fb9987d0SSujith 	CHAN2G(2467, 11), /* Channel 12 */
57fb9987d0SSujith 	CHAN2G(2472, 12), /* Channel 13 */
58fb9987d0SSujith 	CHAN2G(2484, 13), /* Channel 14 */
59fb9987d0SSujith };
60fb9987d0SSujith 
61ea46e644SSujith static struct ieee80211_channel ath9k_5ghz_channels[] = {
62ea46e644SSujith 	/* _We_ call this UNII 1 */
63ea46e644SSujith 	CHAN5G(5180, 14), /* Channel 36 */
64ea46e644SSujith 	CHAN5G(5200, 15), /* Channel 40 */
65ea46e644SSujith 	CHAN5G(5220, 16), /* Channel 44 */
66ea46e644SSujith 	CHAN5G(5240, 17), /* Channel 48 */
67ea46e644SSujith 	/* _We_ call this UNII 2 */
68ea46e644SSujith 	CHAN5G(5260, 18), /* Channel 52 */
69ea46e644SSujith 	CHAN5G(5280, 19), /* Channel 56 */
70ea46e644SSujith 	CHAN5G(5300, 20), /* Channel 60 */
71ea46e644SSujith 	CHAN5G(5320, 21), /* Channel 64 */
72ea46e644SSujith 	/* _We_ call this "Middle band" */
73ea46e644SSujith 	CHAN5G(5500, 22), /* Channel 100 */
74ea46e644SSujith 	CHAN5G(5520, 23), /* Channel 104 */
75ea46e644SSujith 	CHAN5G(5540, 24), /* Channel 108 */
76ea46e644SSujith 	CHAN5G(5560, 25), /* Channel 112 */
77ea46e644SSujith 	CHAN5G(5580, 26), /* Channel 116 */
78ea46e644SSujith 	CHAN5G(5600, 27), /* Channel 120 */
79ea46e644SSujith 	CHAN5G(5620, 28), /* Channel 124 */
80ea46e644SSujith 	CHAN5G(5640, 29), /* Channel 128 */
81ea46e644SSujith 	CHAN5G(5660, 30), /* Channel 132 */
82ea46e644SSujith 	CHAN5G(5680, 31), /* Channel 136 */
83ea46e644SSujith 	CHAN5G(5700, 32), /* Channel 140 */
84ea46e644SSujith 	/* _We_ call this UNII 3 */
85ea46e644SSujith 	CHAN5G(5745, 33), /* Channel 149 */
86ea46e644SSujith 	CHAN5G(5765, 34), /* Channel 153 */
87ea46e644SSujith 	CHAN5G(5785, 35), /* Channel 157 */
88ea46e644SSujith 	CHAN5G(5805, 36), /* Channel 161 */
89ea46e644SSujith 	CHAN5G(5825, 37), /* Channel 165 */
90ea46e644SSujith };
91ea46e644SSujith 
92fb9987d0SSujith /* Atheros hardware rate code addition for short premble */
93fb9987d0SSujith #define SHPCHECK(__hw_rate, __flags) \
94fb9987d0SSujith 	((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0)
95fb9987d0SSujith 
96fb9987d0SSujith #define RATE(_bitrate, _hw_rate, _flags) {		\
97fb9987d0SSujith 	.bitrate	= (_bitrate),			\
98fb9987d0SSujith 	.flags		= (_flags),			\
99fb9987d0SSujith 	.hw_value	= (_hw_rate),			\
100fb9987d0SSujith 	.hw_value_short = (SHPCHECK(_hw_rate, _flags))	\
101fb9987d0SSujith }
102fb9987d0SSujith 
103fb9987d0SSujith static struct ieee80211_rate ath9k_legacy_rates[] = {
104fb9987d0SSujith 	RATE(10, 0x1b, 0),
105fb9987d0SSujith 	RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */
106fb9987d0SSujith 	RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */
107fb9987d0SSujith 	RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */
108fb9987d0SSujith 	RATE(60, 0x0b, 0),
109fb9987d0SSujith 	RATE(90, 0x0f, 0),
110fb9987d0SSujith 	RATE(120, 0x0a, 0),
111fb9987d0SSujith 	RATE(180, 0x0e, 0),
112fb9987d0SSujith 	RATE(240, 0x09, 0),
113fb9987d0SSujith 	RATE(360, 0x0d, 0),
114fb9987d0SSujith 	RATE(480, 0x08, 0),
115fb9987d0SSujith 	RATE(540, 0x0c, 0),
116fb9987d0SSujith };
117fb9987d0SSujith 
118fb9987d0SSujith static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
119fb9987d0SSujith {
120fb9987d0SSujith 	int time_left;
121fb9987d0SSujith 
122d8c49ffbSSujith.Manoharan@atheros.com 	if (atomic_read(&priv->htc->tgt_ready) > 0) {
123d8c49ffbSSujith.Manoharan@atheros.com 		atomic_dec(&priv->htc->tgt_ready);
124d8c49ffbSSujith.Manoharan@atheros.com 		return 0;
125d8c49ffbSSujith.Manoharan@atheros.com 	}
126d8c49ffbSSujith.Manoharan@atheros.com 
127fb9987d0SSujith 	/* Firmware can take up to 50ms to get ready, to be safe use 1 second */
128fb9987d0SSujith 	time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ);
129fb9987d0SSujith 	if (!time_left) {
130fb9987d0SSujith 		dev_err(priv->dev, "ath9k_htc: Target is unresponsive\n");
131fb9987d0SSujith 		return -ETIMEDOUT;
132fb9987d0SSujith 	}
133fb9987d0SSujith 
134d8c49ffbSSujith.Manoharan@atheros.com 	atomic_dec(&priv->htc->tgt_ready);
135d8c49ffbSSujith.Manoharan@atheros.com 
136fb9987d0SSujith 	return 0;
137fb9987d0SSujith }
138fb9987d0SSujith 
139fb9987d0SSujith static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
140fb9987d0SSujith {
141e1572c5eSSujith 	ath9k_htc_exit_debug(priv->ah);
142fb9987d0SSujith 	ath9k_hw_deinit(priv->ah);
143fb9987d0SSujith 	tasklet_kill(&priv->wmi_tasklet);
144fb9987d0SSujith 	tasklet_kill(&priv->rx_tasklet);
145fb9987d0SSujith 	tasklet_kill(&priv->tx_tasklet);
146fb9987d0SSujith 	kfree(priv->ah);
147fb9987d0SSujith 	priv->ah = NULL;
148fb9987d0SSujith }
149fb9987d0SSujith 
150fb9987d0SSujith static void ath9k_deinit_device(struct ath9k_htc_priv *priv)
151fb9987d0SSujith {
152fb9987d0SSujith 	struct ieee80211_hw *hw = priv->hw;
153fb9987d0SSujith 
154fb9987d0SSujith 	wiphy_rfkill_stop_polling(hw->wiphy);
155fb9987d0SSujith 	ath9k_deinit_leds(priv);
156fb9987d0SSujith 	ieee80211_unregister_hw(hw);
157fb9987d0SSujith 	ath9k_rx_cleanup(priv);
158fb9987d0SSujith 	ath9k_tx_cleanup(priv);
159fb9987d0SSujith 	ath9k_deinit_priv(priv);
160fb9987d0SSujith }
161fb9987d0SSujith 
162fb9987d0SSujith static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv,
163fb9987d0SSujith 					u16 service_id,
164fb9987d0SSujith 					void (*tx) (void *,
165fb9987d0SSujith 						    struct sk_buff *,
166fb9987d0SSujith 						    enum htc_endpoint_id,
167fb9987d0SSujith 						    bool txok),
168fb9987d0SSujith 					enum htc_endpoint_id *ep_id)
169fb9987d0SSujith {
170fb9987d0SSujith 	struct htc_service_connreq req;
171fb9987d0SSujith 
172fb9987d0SSujith 	memset(&req, 0, sizeof(struct htc_service_connreq));
173fb9987d0SSujith 
174fb9987d0SSujith 	req.service_id = service_id;
175fb9987d0SSujith 	req.ep_callbacks.priv = priv;
176fb9987d0SSujith 	req.ep_callbacks.rx = ath9k_htc_rxep;
177fb9987d0SSujith 	req.ep_callbacks.tx = tx;
178fb9987d0SSujith 
179fb9987d0SSujith 	return htc_connect_service(priv->htc, &req, ep_id);
180fb9987d0SSujith }
181fb9987d0SSujith 
1826267dc70SSujith static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
183fb9987d0SSujith {
184fb9987d0SSujith 	int ret;
185fb9987d0SSujith 
186fb9987d0SSujith 	/* WMI CMD*/
187fb9987d0SSujith 	ret = ath9k_wmi_connect(priv->htc, priv->wmi, &priv->wmi_cmd_ep);
188fb9987d0SSujith 	if (ret)
189fb9987d0SSujith 		goto err;
190fb9987d0SSujith 
191fb9987d0SSujith 	/* Beacon */
1929c6dda4eSSujith 	ret = ath9k_htc_connect_svc(priv, WMI_BEACON_SVC, ath9k_htc_beaconep,
193fb9987d0SSujith 				    &priv->beacon_ep);
194fb9987d0SSujith 	if (ret)
195fb9987d0SSujith 		goto err;
196fb9987d0SSujith 
197fb9987d0SSujith 	/* CAB */
198fb9987d0SSujith 	ret = ath9k_htc_connect_svc(priv, WMI_CAB_SVC, ath9k_htc_txep,
199fb9987d0SSujith 				    &priv->cab_ep);
200fb9987d0SSujith 	if (ret)
201fb9987d0SSujith 		goto err;
202fb9987d0SSujith 
203fb9987d0SSujith 
204fb9987d0SSujith 	/* UAPSD */
205fb9987d0SSujith 	ret = ath9k_htc_connect_svc(priv, WMI_UAPSD_SVC, ath9k_htc_txep,
206fb9987d0SSujith 				    &priv->uapsd_ep);
207fb9987d0SSujith 	if (ret)
208fb9987d0SSujith 		goto err;
209fb9987d0SSujith 
210fb9987d0SSujith 	/* MGMT */
211fb9987d0SSujith 	ret = ath9k_htc_connect_svc(priv, WMI_MGMT_SVC, ath9k_htc_txep,
212fb9987d0SSujith 				    &priv->mgmt_ep);
213fb9987d0SSujith 	if (ret)
214fb9987d0SSujith 		goto err;
215fb9987d0SSujith 
216fb9987d0SSujith 	/* DATA BE */
217fb9987d0SSujith 	ret = ath9k_htc_connect_svc(priv, WMI_DATA_BE_SVC, ath9k_htc_txep,
218fb9987d0SSujith 				    &priv->data_be_ep);
219fb9987d0SSujith 	if (ret)
220fb9987d0SSujith 		goto err;
221fb9987d0SSujith 
222fb9987d0SSujith 	/* DATA BK */
223fb9987d0SSujith 	ret = ath9k_htc_connect_svc(priv, WMI_DATA_BK_SVC, ath9k_htc_txep,
224fb9987d0SSujith 				    &priv->data_bk_ep);
225fb9987d0SSujith 	if (ret)
226fb9987d0SSujith 		goto err;
227fb9987d0SSujith 
228fb9987d0SSujith 	/* DATA VI */
229fb9987d0SSujith 	ret = ath9k_htc_connect_svc(priv, WMI_DATA_VI_SVC, ath9k_htc_txep,
230fb9987d0SSujith 				    &priv->data_vi_ep);
231fb9987d0SSujith 	if (ret)
232fb9987d0SSujith 		goto err;
233fb9987d0SSujith 
234fb9987d0SSujith 	/* DATA VO */
235fb9987d0SSujith 	ret = ath9k_htc_connect_svc(priv, WMI_DATA_VO_SVC, ath9k_htc_txep,
236fb9987d0SSujith 				    &priv->data_vo_ep);
237fb9987d0SSujith 	if (ret)
238fb9987d0SSujith 		goto err;
239fb9987d0SSujith 
2406267dc70SSujith 	/*
2416267dc70SSujith 	 * Setup required credits before initializing HTC.
2426267dc70SSujith 	 * This is a bit hacky, but, since queuing is done in
2436267dc70SSujith 	 * the HIF layer, shouldn't matter much.
2446267dc70SSujith 	 */
2456267dc70SSujith 
2466267dc70SSujith 	switch(devid) {
2476267dc70SSujith 	case 0x9271:
2486267dc70SSujith 	case 0x1006:
2496267dc70SSujith 		priv->htc->credits = 33;
2506267dc70SSujith 		break;
2516267dc70SSujith 	case 0x7010:
2526267dc70SSujith 		priv->htc->credits = 45;
2536267dc70SSujith 		break;
2546267dc70SSujith 	default:
2556267dc70SSujith 		dev_err(priv->dev, "ath9k_htc: Unsupported device id: 0x%x\n",
2566267dc70SSujith 			devid);
2576267dc70SSujith 		goto err;
2586267dc70SSujith 	}
2596267dc70SSujith 
260fb9987d0SSujith 	ret = htc_init(priv->htc);
261fb9987d0SSujith 	if (ret)
262fb9987d0SSujith 		goto err;
263fb9987d0SSujith 
2646267dc70SSujith 	dev_info(priv->dev, "ath9k_htc: HTC initialized with %d credits\n",
2656267dc70SSujith 		 priv->htc->credits);
2666267dc70SSujith 
267fb9987d0SSujith 	return 0;
268fb9987d0SSujith 
269fb9987d0SSujith err:
270fb9987d0SSujith 	dev_err(priv->dev, "ath9k_htc: Unable to initialize HTC services\n");
271fb9987d0SSujith 	return ret;
272fb9987d0SSujith }
273fb9987d0SSujith 
274fb9987d0SSujith static int ath9k_reg_notifier(struct wiphy *wiphy,
275fb9987d0SSujith 			      struct regulatory_request *request)
276fb9987d0SSujith {
277fb9987d0SSujith 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
278fb9987d0SSujith 	struct ath9k_htc_priv *priv = hw->priv;
279fb9987d0SSujith 
280fb9987d0SSujith 	return ath_reg_notifier_apply(wiphy, request,
281fb9987d0SSujith 				      ath9k_hw_regulatory(priv->ah));
282fb9987d0SSujith }
283fb9987d0SSujith 
2844a22fe10SSujith static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset)
285fb9987d0SSujith {
286fb9987d0SSujith 	struct ath_hw *ah = (struct ath_hw *) hw_priv;
287fb9987d0SSujith 	struct ath_common *common = ath9k_hw_common(ah);
288fb9987d0SSujith 	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
289fb9987d0SSujith 	__be32 val, reg = cpu_to_be32(reg_offset);
290fb9987d0SSujith 	int r;
291fb9987d0SSujith 
292fb9987d0SSujith 	r = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID,
293fb9987d0SSujith 			  (u8 *) &reg, sizeof(reg),
294fb9987d0SSujith 			  (u8 *) &val, sizeof(val),
295fb9987d0SSujith 			  100);
296fb9987d0SSujith 	if (unlikely(r)) {
297fb9987d0SSujith 		ath_print(common, ATH_DBG_WMI,
298fb9987d0SSujith 			  "REGISTER READ FAILED: (0x%04x, %d)\n",
299fb9987d0SSujith 			   reg_offset, r);
300fb9987d0SSujith 		return -EIO;
301fb9987d0SSujith 	}
302fb9987d0SSujith 
303fb9987d0SSujith 	return be32_to_cpu(val);
304fb9987d0SSujith }
305fb9987d0SSujith 
3064a22fe10SSujith static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
307fb9987d0SSujith {
308fb9987d0SSujith 	struct ath_hw *ah = (struct ath_hw *) hw_priv;
309fb9987d0SSujith 	struct ath_common *common = ath9k_hw_common(ah);
310fb9987d0SSujith 	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
311fb9987d0SSujith 	__be32 buf[2] = {
312fb9987d0SSujith 		cpu_to_be32(reg_offset),
313fb9987d0SSujith 		cpu_to_be32(val),
314fb9987d0SSujith 	};
315fb9987d0SSujith 	int r;
316fb9987d0SSujith 
317fb9987d0SSujith 	r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
318fb9987d0SSujith 			  (u8 *) &buf, sizeof(buf),
319fb9987d0SSujith 			  (u8 *) &val, sizeof(val),
320fb9987d0SSujith 			  100);
321fb9987d0SSujith 	if (unlikely(r)) {
322fb9987d0SSujith 		ath_print(common, ATH_DBG_WMI,
323fb9987d0SSujith 			  "REGISTER WRITE FAILED:(0x%04x, %d)\n",
324fb9987d0SSujith 			  reg_offset, r);
325fb9987d0SSujith 	}
326fb9987d0SSujith }
327fb9987d0SSujith 
3284a22fe10SSujith static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset)
3294a22fe10SSujith {
3304a22fe10SSujith 	struct ath_hw *ah = (struct ath_hw *) hw_priv;
3314a22fe10SSujith 	struct ath_common *common = ath9k_hw_common(ah);
3324a22fe10SSujith 	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
3334a22fe10SSujith 	u32 rsp_status;
3344a22fe10SSujith 	int r;
3354a22fe10SSujith 
3364a22fe10SSujith 	mutex_lock(&priv->wmi->multi_write_mutex);
3374a22fe10SSujith 
3384a22fe10SSujith 	/* Store the register/value */
3394a22fe10SSujith 	priv->wmi->multi_write[priv->wmi->multi_write_idx].reg =
3404a22fe10SSujith 		cpu_to_be32(reg_offset);
3414a22fe10SSujith 	priv->wmi->multi_write[priv->wmi->multi_write_idx].val =
3424a22fe10SSujith 		cpu_to_be32(val);
3434a22fe10SSujith 
3444a22fe10SSujith 	priv->wmi->multi_write_idx++;
3454a22fe10SSujith 
3464a22fe10SSujith 	/* If the buffer is full, send it out. */
3474a22fe10SSujith 	if (priv->wmi->multi_write_idx == MAX_CMD_NUMBER) {
3484a22fe10SSujith 		r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
3494a22fe10SSujith 			  (u8 *) &priv->wmi->multi_write,
3504a22fe10SSujith 			  sizeof(struct register_write) * priv->wmi->multi_write_idx,
3514a22fe10SSujith 			  (u8 *) &rsp_status, sizeof(rsp_status),
3524a22fe10SSujith 			  100);
3534a22fe10SSujith 		if (unlikely(r)) {
3544a22fe10SSujith 			ath_print(common, ATH_DBG_WMI,
3554a22fe10SSujith 				  "REGISTER WRITE FAILED, multi len: %d\n",
3564a22fe10SSujith 				  priv->wmi->multi_write_idx);
3574a22fe10SSujith 		}
3584a22fe10SSujith 		priv->wmi->multi_write_idx = 0;
3594a22fe10SSujith 	}
3604a22fe10SSujith 
3614a22fe10SSujith 	mutex_unlock(&priv->wmi->multi_write_mutex);
3624a22fe10SSujith }
3634a22fe10SSujith 
3644a22fe10SSujith static void ath9k_regwrite(void *hw_priv, u32 val, u32 reg_offset)
3654a22fe10SSujith {
3664a22fe10SSujith 	struct ath_hw *ah = (struct ath_hw *) hw_priv;
3674a22fe10SSujith 	struct ath_common *common = ath9k_hw_common(ah);
3684a22fe10SSujith 	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
3694a22fe10SSujith 
3704a22fe10SSujith 	if (atomic_read(&priv->wmi->mwrite_cnt))
3714a22fe10SSujith 		ath9k_regwrite_buffer(hw_priv, val, reg_offset);
3724a22fe10SSujith 	else
3734a22fe10SSujith 		ath9k_regwrite_single(hw_priv, val, reg_offset);
3744a22fe10SSujith }
3754a22fe10SSujith 
3764a22fe10SSujith static void ath9k_enable_regwrite_buffer(void *hw_priv)
3774a22fe10SSujith {
3784a22fe10SSujith 	struct ath_hw *ah = (struct ath_hw *) hw_priv;
3794a22fe10SSujith 	struct ath_common *common = ath9k_hw_common(ah);
3804a22fe10SSujith 	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
3814a22fe10SSujith 
3824a22fe10SSujith 	atomic_inc(&priv->wmi->mwrite_cnt);
3834a22fe10SSujith }
3844a22fe10SSujith 
3854a22fe10SSujith static void ath9k_disable_regwrite_buffer(void *hw_priv)
3864a22fe10SSujith {
3874a22fe10SSujith 	struct ath_hw *ah = (struct ath_hw *) hw_priv;
3884a22fe10SSujith 	struct ath_common *common = ath9k_hw_common(ah);
3894a22fe10SSujith 	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
3904a22fe10SSujith 
3914a22fe10SSujith 	atomic_dec(&priv->wmi->mwrite_cnt);
3924a22fe10SSujith }
3934a22fe10SSujith 
3944a22fe10SSujith static void ath9k_regwrite_flush(void *hw_priv)
3954a22fe10SSujith {
3964a22fe10SSujith 	struct ath_hw *ah = (struct ath_hw *) hw_priv;
3974a22fe10SSujith 	struct ath_common *common = ath9k_hw_common(ah);
3984a22fe10SSujith 	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
3994a22fe10SSujith 	u32 rsp_status;
4004a22fe10SSujith 	int r;
4014a22fe10SSujith 
4024a22fe10SSujith 	mutex_lock(&priv->wmi->multi_write_mutex);
4034a22fe10SSujith 
4044a22fe10SSujith 	if (priv->wmi->multi_write_idx) {
4054a22fe10SSujith 		r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
4064a22fe10SSujith 			  (u8 *) &priv->wmi->multi_write,
4074a22fe10SSujith 			  sizeof(struct register_write) * priv->wmi->multi_write_idx,
4084a22fe10SSujith 			  (u8 *) &rsp_status, sizeof(rsp_status),
4094a22fe10SSujith 			  100);
4104a22fe10SSujith 		if (unlikely(r)) {
4114a22fe10SSujith 			ath_print(common, ATH_DBG_WMI,
4124a22fe10SSujith 				  "REGISTER WRITE FAILED, multi len: %d\n",
4134a22fe10SSujith 				  priv->wmi->multi_write_idx);
4144a22fe10SSujith 		}
4154a22fe10SSujith 		priv->wmi->multi_write_idx = 0;
4164a22fe10SSujith 	}
4174a22fe10SSujith 
4184a22fe10SSujith 	mutex_unlock(&priv->wmi->multi_write_mutex);
4194a22fe10SSujith }
4204a22fe10SSujith 
421fb9987d0SSujith static const struct ath_ops ath9k_common_ops = {
4224a22fe10SSujith 	.read = ath9k_regread,
4234a22fe10SSujith 	.write = ath9k_regwrite,
4244a22fe10SSujith 	.enable_write_buffer = ath9k_enable_regwrite_buffer,
4254a22fe10SSujith 	.disable_write_buffer = ath9k_disable_regwrite_buffer,
4264a22fe10SSujith 	.write_flush = ath9k_regwrite_flush,
427fb9987d0SSujith };
428fb9987d0SSujith 
429fb9987d0SSujith static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
430fb9987d0SSujith {
431fb9987d0SSujith 	*csz = L1_CACHE_BYTES >> 2;
432fb9987d0SSujith }
433fb9987d0SSujith 
434fb9987d0SSujith static bool ath_usb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
435fb9987d0SSujith {
436fb9987d0SSujith 	struct ath_hw *ah = (struct ath_hw *) common->ah;
437fb9987d0SSujith 
438fb9987d0SSujith 	(void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
439fb9987d0SSujith 
440fb9987d0SSujith 	if (!ath9k_hw_wait(ah,
441fb9987d0SSujith 			   AR_EEPROM_STATUS_DATA,
442fb9987d0SSujith 			   AR_EEPROM_STATUS_DATA_BUSY |
443fb9987d0SSujith 			   AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
444fb9987d0SSujith 			   AH_WAIT_TIMEOUT))
445fb9987d0SSujith 		return false;
446fb9987d0SSujith 
447fb9987d0SSujith 	*data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
448fb9987d0SSujith 		   AR_EEPROM_STATUS_DATA_VAL);
449fb9987d0SSujith 
450fb9987d0SSujith 	return true;
451fb9987d0SSujith }
452fb9987d0SSujith 
453fb9987d0SSujith static const struct ath_bus_ops ath9k_usb_bus_ops = {
454497ad9adSSujith 	.ath_bus_type = ATH_USB,
455fb9987d0SSujith 	.read_cachesize = ath_usb_read_cachesize,
456fb9987d0SSujith 	.eeprom_read = ath_usb_eeprom_read,
457fb9987d0SSujith };
458fb9987d0SSujith 
459fb9987d0SSujith static void setup_ht_cap(struct ath9k_htc_priv *priv,
460fb9987d0SSujith 			 struct ieee80211_sta_ht_cap *ht_info)
461fb9987d0SSujith {
4626debecadSSujith 	struct ath_common *common = ath9k_hw_common(priv->ah);
4636debecadSSujith 	u8 tx_streams, rx_streams;
4646debecadSSujith 	int i;
4656debecadSSujith 
466fb9987d0SSujith 	ht_info->ht_supported = true;
467fb9987d0SSujith 	ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
468fb9987d0SSujith 		       IEEE80211_HT_CAP_SM_PS |
469fb9987d0SSujith 		       IEEE80211_HT_CAP_SGI_40 |
470fb9987d0SSujith 		       IEEE80211_HT_CAP_DSSSCCK40;
471fb9987d0SSujith 
472b4dec5e8SSujith 	if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
473b4dec5e8SSujith 		ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
474b4dec5e8SSujith 
47517525f96SSujith 	ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
47617525f96SSujith 
477fb9987d0SSujith 	ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
478fb9987d0SSujith 	ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
479fb9987d0SSujith 
480fb9987d0SSujith 	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
4816debecadSSujith 
4826debecadSSujith 	/* ath9k_htc supports only 1 or 2 stream devices */
4836debecadSSujith 	tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, 2);
4846debecadSSujith 	rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, 2);
4856debecadSSujith 
4866debecadSSujith 	ath_print(common, ATH_DBG_CONFIG,
4876debecadSSujith 		  "TX streams %d, RX streams: %d\n",
4886debecadSSujith 		  tx_streams, rx_streams);
4896debecadSSujith 
4906debecadSSujith 	if (tx_streams != rx_streams) {
4916debecadSSujith 		ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
4926debecadSSujith 		ht_info->mcs.tx_params |= ((tx_streams - 1) <<
4936debecadSSujith 					   IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
4946debecadSSujith 	}
4956debecadSSujith 
4966debecadSSujith 	for (i = 0; i < rx_streams; i++)
4976debecadSSujith 		ht_info->mcs.rx_mask[i] = 0xff;
4986debecadSSujith 
499fb9987d0SSujith 	ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
500fb9987d0SSujith }
501fb9987d0SSujith 
502fb9987d0SSujith static int ath9k_init_queues(struct ath9k_htc_priv *priv)
503fb9987d0SSujith {
504fb9987d0SSujith 	struct ath_common *common = ath9k_hw_common(priv->ah);
505fb9987d0SSujith 	int i;
506fb9987d0SSujith 
507fb9987d0SSujith 	for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++)
508fb9987d0SSujith 		priv->hwq_map[i] = -1;
509fb9987d0SSujith 
510ca74b83bSSujith 	priv->beaconq = ath9k_hw_beaconq_setup(priv->ah);
511ca74b83bSSujith 	if (priv->beaconq == -1) {
512ca74b83bSSujith 		ath_print(common, ATH_DBG_FATAL,
513ca74b83bSSujith 			  "Unable to setup BEACON xmit queue\n");
514ca74b83bSSujith 		goto err;
515ca74b83bSSujith 	}
516ca74b83bSSujith 
517ca74b83bSSujith 	priv->cabq = ath9k_htc_cabq_setup(priv);
518ca74b83bSSujith 	if (priv->cabq == -1) {
519ca74b83bSSujith 		ath_print(common, ATH_DBG_FATAL,
520ca74b83bSSujith 			  "Unable to setup CAB xmit queue\n");
521ca74b83bSSujith 		goto err;
522ca74b83bSSujith 	}
523ca74b83bSSujith 
524fb9987d0SSujith 	if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) {
525fb9987d0SSujith 		ath_print(common, ATH_DBG_FATAL,
526fb9987d0SSujith 			  "Unable to setup xmit queue for BE traffic\n");
527fb9987d0SSujith 		goto err;
528fb9987d0SSujith 	}
529fb9987d0SSujith 
530fb9987d0SSujith 	if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) {
531fb9987d0SSujith 		ath_print(common, ATH_DBG_FATAL,
532fb9987d0SSujith 			  "Unable to setup xmit queue for BK traffic\n");
533fb9987d0SSujith 		goto err;
534fb9987d0SSujith 	}
535fb9987d0SSujith 	if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) {
536fb9987d0SSujith 		ath_print(common, ATH_DBG_FATAL,
537fb9987d0SSujith 			  "Unable to setup xmit queue for VI traffic\n");
538fb9987d0SSujith 		goto err;
539fb9987d0SSujith 	}
540fb9987d0SSujith 	if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) {
541fb9987d0SSujith 		ath_print(common, ATH_DBG_FATAL,
542fb9987d0SSujith 			  "Unable to setup xmit queue for VO traffic\n");
543fb9987d0SSujith 		goto err;
544fb9987d0SSujith 	}
545fb9987d0SSujith 
546fb9987d0SSujith 	return 0;
547fb9987d0SSujith 
548fb9987d0SSujith err:
549fb9987d0SSujith 	return -EINVAL;
550fb9987d0SSujith }
551fb9987d0SSujith 
552fb9987d0SSujith static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
553fb9987d0SSujith {
554fb9987d0SSujith 	struct ath_common *common = ath9k_hw_common(priv->ah);
555fb9987d0SSujith 	int i = 0;
556fb9987d0SSujith 
557fb9987d0SSujith 	/* Get the hardware key cache size. */
558fb9987d0SSujith 	common->keymax = priv->ah->caps.keycache_size;
559fb9987d0SSujith 	if (common->keymax > ATH_KEYMAX) {
560fb9987d0SSujith 		ath_print(common, ATH_DBG_ANY,
561fb9987d0SSujith 			  "Warning, using only %u entries in %u key cache\n",
562fb9987d0SSujith 			  ATH_KEYMAX, common->keymax);
563fb9987d0SSujith 		common->keymax = ATH_KEYMAX;
564fb9987d0SSujith 	}
565fb9987d0SSujith 
566fb9987d0SSujith 	/*
567fb9987d0SSujith 	 * Reset the key cache since some parts do not
568fb9987d0SSujith 	 * reset the contents on initial power up.
569fb9987d0SSujith 	 */
570fb9987d0SSujith 	for (i = 0; i < common->keymax; i++)
571fb9987d0SSujith 		ath9k_hw_keyreset(priv->ah, (u16) i);
572fb9987d0SSujith 
573fb9987d0SSujith 	if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
574fb9987d0SSujith 				   ATH9K_CIPHER_TKIP, NULL)) {
575fb9987d0SSujith 		/*
576fb9987d0SSujith 		 * Whether we should enable h/w TKIP MIC.
577fb9987d0SSujith 		 * XXX: if we don't support WME TKIP MIC, then we wouldn't
578fb9987d0SSujith 		 * report WMM capable, so it's always safe to turn on
579fb9987d0SSujith 		 * TKIP MIC in this case.
580fb9987d0SSujith 		 */
581fb9987d0SSujith 		ath9k_hw_setcapability(priv->ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
582fb9987d0SSujith 	}
583fb9987d0SSujith 
584fb9987d0SSujith 	/*
585fb9987d0SSujith 	 * Check whether the separate key cache entries
586fb9987d0SSujith 	 * are required to handle both tx+rx MIC keys.
587fb9987d0SSujith 	 * With split mic keys the number of stations is limited
588fb9987d0SSujith 	 * to 27 otherwise 59.
589fb9987d0SSujith 	 */
590fb9987d0SSujith 	if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
591fb9987d0SSujith 				   ATH9K_CIPHER_TKIP, NULL)
592fb9987d0SSujith 	    && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
593fb9987d0SSujith 				      ATH9K_CIPHER_MIC, NULL)
594fb9987d0SSujith 	    && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_TKIP_SPLIT,
595fb9987d0SSujith 				      0, NULL))
596fb9987d0SSujith 		common->splitmic = 1;
597fb9987d0SSujith 
598fb9987d0SSujith 	/* turn on mcast key search if possible */
599fb9987d0SSujith 	if (!ath9k_hw_getcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
600fb9987d0SSujith 		(void)ath9k_hw_setcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH,
601fb9987d0SSujith 					     1, 1, NULL);
602fb9987d0SSujith }
603fb9987d0SSujith 
604fb9987d0SSujith static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
605fb9987d0SSujith {
606fb9987d0SSujith 	if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
607fb9987d0SSujith 		priv->sbands[IEEE80211_BAND_2GHZ].channels =
608fb9987d0SSujith 			ath9k_2ghz_channels;
609fb9987d0SSujith 		priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
610fb9987d0SSujith 		priv->sbands[IEEE80211_BAND_2GHZ].n_channels =
611fb9987d0SSujith 			ARRAY_SIZE(ath9k_2ghz_channels);
612fb9987d0SSujith 		priv->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
613fb9987d0SSujith 		priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
614fb9987d0SSujith 			ARRAY_SIZE(ath9k_legacy_rates);
615fb9987d0SSujith 	}
616ea46e644SSujith 
617ea46e644SSujith 	if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) {
618ea46e644SSujith 		priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels;
619ea46e644SSujith 		priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
620ea46e644SSujith 		priv->sbands[IEEE80211_BAND_5GHZ].n_channels =
621ea46e644SSujith 			ARRAY_SIZE(ath9k_5ghz_channels);
622ea46e644SSujith 		priv->sbands[IEEE80211_BAND_5GHZ].bitrates =
623ea46e644SSujith 			ath9k_legacy_rates + 4;
624ea46e644SSujith 		priv->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
625ea46e644SSujith 			ARRAY_SIZE(ath9k_legacy_rates) - 4;
626ea46e644SSujith 	}
627fb9987d0SSujith }
628fb9987d0SSujith 
629fb9987d0SSujith static void ath9k_init_misc(struct ath9k_htc_priv *priv)
630fb9987d0SSujith {
631fb9987d0SSujith 	struct ath_common *common = ath9k_hw_common(priv->ah);
632fb9987d0SSujith 
633fb9987d0SSujith 	common->tx_chainmask = priv->ah->caps.tx_chainmask;
634fb9987d0SSujith 	common->rx_chainmask = priv->ah->caps.rx_chainmask;
635fb9987d0SSujith 
636fb9987d0SSujith 	if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
637fb9987d0SSujith 		memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
638fb9987d0SSujith 
639fb9987d0SSujith 	priv->op_flags |= OP_TXAGGR;
6409f01a84eSSujith 	priv->ah->opmode = NL80211_IFTYPE_STATION;
641fb9987d0SSujith }
642fb9987d0SSujith 
643fb9987d0SSujith static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
644fb9987d0SSujith {
645fb9987d0SSujith 	struct ath_hw *ah = NULL;
646fb9987d0SSujith 	struct ath_common *common;
647fb9987d0SSujith 	int ret = 0, csz = 0;
648fb9987d0SSujith 
649fb9987d0SSujith 	priv->op_flags |= OP_INVALID;
650fb9987d0SSujith 
651fb9987d0SSujith 	ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
652fb9987d0SSujith 	if (!ah)
653fb9987d0SSujith 		return -ENOMEM;
654fb9987d0SSujith 
655fb9987d0SSujith 	ah->hw_version.devid = devid;
656fb9987d0SSujith 	ah->hw_version.subsysid = 0; /* FIXME */
657fb9987d0SSujith 	priv->ah = ah;
658fb9987d0SSujith 
659fb9987d0SSujith 	common = ath9k_hw_common(ah);
660fb9987d0SSujith 	common->ops = &ath9k_common_ops;
661fb9987d0SSujith 	common->bus_ops = &ath9k_usb_bus_ops;
662fb9987d0SSujith 	common->ah = ah;
663fb9987d0SSujith 	common->hw = priv->hw;
664fb9987d0SSujith 	common->priv = priv;
665fb9987d0SSujith 	common->debug_mask = ath9k_debug;
666fb9987d0SSujith 
667fb9987d0SSujith 	spin_lock_init(&priv->wmi->wmi_lock);
668fb9987d0SSujith 	spin_lock_init(&priv->beacon_lock);
6697757dfedSSujith 	spin_lock_init(&priv->tx_lock);
670fb9987d0SSujith 	mutex_init(&priv->mutex);
671fb9987d0SSujith 	mutex_init(&priv->aggr_work.mutex);
672bde748a4SVivek Natarajan 	mutex_init(&priv->htc_pm_lock);
673fb9987d0SSujith 	tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet,
674fb9987d0SSujith 		     (unsigned long)priv);
675fb9987d0SSujith 	tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
676fb9987d0SSujith 		     (unsigned long)priv);
677fb9987d0SSujith 	tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv);
678fb9987d0SSujith 	INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work);
679fb9987d0SSujith 	INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
680bde748a4SVivek Natarajan 	INIT_WORK(&priv->ps_work, ath9k_ps_work);
681fb9987d0SSujith 
682fb9987d0SSujith 	/*
683fb9987d0SSujith 	 * Cache line size is used to size and align various
684fb9987d0SSujith 	 * structures used to communicate with the hardware.
685fb9987d0SSujith 	 */
686fb9987d0SSujith 	ath_read_cachesize(common, &csz);
687fb9987d0SSujith 	common->cachelsz = csz << 2; /* convert to bytes */
688fb9987d0SSujith 
689fb9987d0SSujith 	ret = ath9k_hw_init(ah);
690fb9987d0SSujith 	if (ret) {
691fb9987d0SSujith 		ath_print(common, ATH_DBG_FATAL,
692fb9987d0SSujith 			  "Unable to initialize hardware; "
693fb9987d0SSujith 			  "initialization status: %d\n", ret);
694fb9987d0SSujith 		goto err_hw;
695fb9987d0SSujith 	}
696fb9987d0SSujith 
697e1572c5eSSujith 	ret = ath9k_htc_init_debug(ah);
698fb9987d0SSujith 	if (ret) {
699fb9987d0SSujith 		ath_print(common, ATH_DBG_FATAL,
700fb9987d0SSujith 			  "Unable to create debugfs files\n");
701fb9987d0SSujith 		goto err_debug;
702fb9987d0SSujith 	}
703fb9987d0SSujith 
704fb9987d0SSujith 	ret = ath9k_init_queues(priv);
705fb9987d0SSujith 	if (ret)
706fb9987d0SSujith 		goto err_queues;
707fb9987d0SSujith 
708fb9987d0SSujith 	ath9k_init_crypto(priv);
709fb9987d0SSujith 	ath9k_init_channels_rates(priv);
710fb9987d0SSujith 	ath9k_init_misc(priv);
711fb9987d0SSujith 
712fb9987d0SSujith 	return 0;
713fb9987d0SSujith 
714fb9987d0SSujith err_queues:
715e1572c5eSSujith 	ath9k_htc_exit_debug(ah);
716fb9987d0SSujith err_debug:
717fb9987d0SSujith 	ath9k_hw_deinit(ah);
718fb9987d0SSujith err_hw:
719fb9987d0SSujith 
720fb9987d0SSujith 	kfree(ah);
721fb9987d0SSujith 	priv->ah = NULL;
722fb9987d0SSujith 
723fb9987d0SSujith 	return ret;
724fb9987d0SSujith }
725fb9987d0SSujith 
726fb9987d0SSujith static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
727fb9987d0SSujith 			       struct ieee80211_hw *hw)
728fb9987d0SSujith {
729fb9987d0SSujith 	struct ath_common *common = ath9k_hw_common(priv->ah);
730fb9987d0SSujith 
731fb9987d0SSujith 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
732fb9987d0SSujith 		IEEE80211_HW_AMPDU_AGGREGATION |
733fb9987d0SSujith 		IEEE80211_HW_SPECTRUM_MGMT |
73432fbccafSSujith 		IEEE80211_HW_HAS_RATE_CONTROL |
735bde748a4SVivek Natarajan 		IEEE80211_HW_RX_INCLUDES_FCS |
736bde748a4SVivek Natarajan 		IEEE80211_HW_SUPPORTS_PS |
737bde748a4SVivek Natarajan 		IEEE80211_HW_PS_NULLFUNC_STACK;
738fb9987d0SSujith 
739fb9987d0SSujith 	hw->wiphy->interface_modes =
740fb9987d0SSujith 		BIT(NL80211_IFTYPE_STATION) |
741fb9987d0SSujith 		BIT(NL80211_IFTYPE_ADHOC);
742fb9987d0SSujith 
743bde748a4SVivek Natarajan 	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
744bde748a4SVivek Natarajan 
745fb9987d0SSujith 	hw->queues = 4;
746fb9987d0SSujith 	hw->channel_change_time = 5000;
747fb9987d0SSujith 	hw->max_listen_interval = 10;
748fb9987d0SSujith 	hw->vif_data_size = sizeof(struct ath9k_htc_vif);
749fb9987d0SSujith 	hw->sta_data_size = sizeof(struct ath9k_htc_sta);
750fb9987d0SSujith 
751fb9987d0SSujith 	/* tx_frame_hdr is larger than tx_mgmt_hdr anyway */
752fb9987d0SSujith 	hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
753fb9987d0SSujith 		sizeof(struct htc_frame_hdr) + 4;
754fb9987d0SSujith 
755fb9987d0SSujith 	if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
756fb9987d0SSujith 		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
757fb9987d0SSujith 			&priv->sbands[IEEE80211_BAND_2GHZ];
758ea46e644SSujith 	if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
759ea46e644SSujith 		hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
760ea46e644SSujith 			&priv->sbands[IEEE80211_BAND_5GHZ];
761fb9987d0SSujith 
762fb9987d0SSujith 	if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
763fb9987d0SSujith 		if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
764fb9987d0SSujith 			setup_ht_cap(priv,
765fb9987d0SSujith 				     &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
766ea46e644SSujith 		if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
767ea46e644SSujith 			setup_ht_cap(priv,
768ea46e644SSujith 				     &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
769fb9987d0SSujith 	}
770fb9987d0SSujith 
771fb9987d0SSujith 	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
772fb9987d0SSujith }
773fb9987d0SSujith 
774fb9987d0SSujith static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
775fb9987d0SSujith {
776fb9987d0SSujith 	struct ieee80211_hw *hw = priv->hw;
777fb9987d0SSujith 	struct ath_common *common;
778fb9987d0SSujith 	struct ath_hw *ah;
779fb9987d0SSujith 	int error = 0;
780fb9987d0SSujith 	struct ath_regulatory *reg;
781fb9987d0SSujith 
782fb9987d0SSujith 	/* Bring up device */
783fb9987d0SSujith 	error = ath9k_init_priv(priv, devid);
784fb9987d0SSujith 	if (error != 0)
785fb9987d0SSujith 		goto err_init;
786fb9987d0SSujith 
787fb9987d0SSujith 	ah = priv->ah;
788fb9987d0SSujith 	common = ath9k_hw_common(ah);
789fb9987d0SSujith 	ath9k_set_hw_capab(priv, hw);
790fb9987d0SSujith 
791fb9987d0SSujith 	/* Initialize regulatory */
792fb9987d0SSujith 	error = ath_regd_init(&common->regulatory, priv->hw->wiphy,
793fb9987d0SSujith 			      ath9k_reg_notifier);
794fb9987d0SSujith 	if (error)
795fb9987d0SSujith 		goto err_regd;
796fb9987d0SSujith 
797fb9987d0SSujith 	reg = &common->regulatory;
798fb9987d0SSujith 
799fb9987d0SSujith 	/* Setup TX */
800fb9987d0SSujith 	error = ath9k_tx_init(priv);
801fb9987d0SSujith 	if (error != 0)
802fb9987d0SSujith 		goto err_tx;
803fb9987d0SSujith 
804fb9987d0SSujith 	/* Setup RX */
805fb9987d0SSujith 	error = ath9k_rx_init(priv);
806fb9987d0SSujith 	if (error != 0)
807fb9987d0SSujith 		goto err_rx;
808fb9987d0SSujith 
809fb9987d0SSujith 	/* Register with mac80211 */
810fb9987d0SSujith 	error = ieee80211_register_hw(hw);
811fb9987d0SSujith 	if (error)
812fb9987d0SSujith 		goto err_register;
813fb9987d0SSujith 
814fb9987d0SSujith 	/* Handle world regulatory */
815fb9987d0SSujith 	if (!ath_is_world_regd(reg)) {
816fb9987d0SSujith 		error = regulatory_hint(hw->wiphy, reg->alpha2);
817fb9987d0SSujith 		if (error)
818fb9987d0SSujith 			goto err_world;
819fb9987d0SSujith 	}
820fb9987d0SSujith 
821fb9987d0SSujith 	ath9k_init_leds(priv);
822fb9987d0SSujith 	ath9k_start_rfkill_poll(priv);
823fb9987d0SSujith 
824fb9987d0SSujith 	return 0;
825fb9987d0SSujith 
826fb9987d0SSujith err_world:
827fb9987d0SSujith 	ieee80211_unregister_hw(hw);
828fb9987d0SSujith err_register:
829fb9987d0SSujith 	ath9k_rx_cleanup(priv);
830fb9987d0SSujith err_rx:
831fb9987d0SSujith 	ath9k_tx_cleanup(priv);
832fb9987d0SSujith err_tx:
833fb9987d0SSujith 	/* Nothing */
834fb9987d0SSujith err_regd:
835fb9987d0SSujith 	ath9k_deinit_priv(priv);
836fb9987d0SSujith err_init:
837fb9987d0SSujith 	return error;
838fb9987d0SSujith }
839fb9987d0SSujith 
840fb9987d0SSujith int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
841fb9987d0SSujith 			   u16 devid)
842fb9987d0SSujith {
843fb9987d0SSujith 	struct ieee80211_hw *hw;
844fb9987d0SSujith 	struct ath9k_htc_priv *priv;
845fb9987d0SSujith 	int ret;
846fb9987d0SSujith 
847fb9987d0SSujith 	hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
848fb9987d0SSujith 	if (!hw)
849fb9987d0SSujith 		return -ENOMEM;
850fb9987d0SSujith 
851fb9987d0SSujith 	priv = hw->priv;
852fb9987d0SSujith 	priv->hw = hw;
853fb9987d0SSujith 	priv->htc = htc_handle;
854fb9987d0SSujith 	priv->dev = dev;
855fb9987d0SSujith 	htc_handle->drv_priv = priv;
856fb9987d0SSujith 	SET_IEEE80211_DEV(hw, priv->dev);
857fb9987d0SSujith 
858fb9987d0SSujith 	ret = ath9k_htc_wait_for_target(priv);
859fb9987d0SSujith 	if (ret)
860fb9987d0SSujith 		goto err_free;
861fb9987d0SSujith 
862fb9987d0SSujith 	priv->wmi = ath9k_init_wmi(priv);
863fb9987d0SSujith 	if (!priv->wmi) {
864fb9987d0SSujith 		ret = -EINVAL;
865fb9987d0SSujith 		goto err_free;
866fb9987d0SSujith 	}
867fb9987d0SSujith 
8686267dc70SSujith 	ret = ath9k_init_htc_services(priv, devid);
869fb9987d0SSujith 	if (ret)
870fb9987d0SSujith 		goto err_init;
871fb9987d0SSujith 
872a3be14b7SSujith 	/* The device may have been unplugged earlier. */
873a3be14b7SSujith 	priv->op_flags &= ~OP_UNPLUGGED;
874a3be14b7SSujith 
875fb9987d0SSujith 	ret = ath9k_init_device(priv, devid);
876fb9987d0SSujith 	if (ret)
877fb9987d0SSujith 		goto err_init;
878fb9987d0SSujith 
879fb9987d0SSujith 	return 0;
880fb9987d0SSujith 
881fb9987d0SSujith err_init:
882fb9987d0SSujith 	ath9k_deinit_wmi(priv);
883fb9987d0SSujith err_free:
884fb9987d0SSujith 	ieee80211_free_hw(hw);
885fb9987d0SSujith 	return ret;
886fb9987d0SSujith }
887fb9987d0SSujith 
888fb9987d0SSujith void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
889fb9987d0SSujith {
890fb9987d0SSujith 	if (htc_handle->drv_priv) {
891a3be14b7SSujith 
892a3be14b7SSujith 		/* Check if the device has been yanked out. */
893a3be14b7SSujith 		if (hotunplug)
894a3be14b7SSujith 			htc_handle->drv_priv->op_flags |= OP_UNPLUGGED;
895a3be14b7SSujith 
896fb9987d0SSujith 		ath9k_deinit_device(htc_handle->drv_priv);
897fb9987d0SSujith 		ath9k_deinit_wmi(htc_handle->drv_priv);
898fb9987d0SSujith 		ieee80211_free_hw(htc_handle->drv_priv->hw);
899fb9987d0SSujith 	}
900fb9987d0SSujith }
901fb9987d0SSujith 
902fb9987d0SSujith #ifdef CONFIG_PM
903fb9987d0SSujith int ath9k_htc_resume(struct htc_target *htc_handle)
904fb9987d0SSujith {
905fb9987d0SSujith 	int ret;
906fb9987d0SSujith 
907fb9987d0SSujith 	ret = ath9k_htc_wait_for_target(htc_handle->drv_priv);
908fb9987d0SSujith 	if (ret)
909fb9987d0SSujith 		return ret;
910fb9987d0SSujith 
9116267dc70SSujith 	ret = ath9k_init_htc_services(htc_handle->drv_priv,
9126267dc70SSujith 			      htc_handle->drv_priv->ah->hw_version.devid);
913fb9987d0SSujith 	return ret;
914fb9987d0SSujith }
915fb9987d0SSujith #endif
916fb9987d0SSujith 
917fb9987d0SSujith static int __init ath9k_htc_init(void)
918fb9987d0SSujith {
919fb9987d0SSujith 	int error;
920fb9987d0SSujith 
921e1572c5eSSujith 	error = ath9k_htc_debug_create_root();
922fb9987d0SSujith 	if (error < 0) {
923fb9987d0SSujith 		printk(KERN_ERR
924fb9987d0SSujith 			"ath9k_htc: Unable to create debugfs root: %d\n",
925fb9987d0SSujith 			error);
926fb9987d0SSujith 		goto err_dbg;
927fb9987d0SSujith 	}
928fb9987d0SSujith 
929fb9987d0SSujith 	error = ath9k_hif_usb_init();
930fb9987d0SSujith 	if (error < 0) {
931fb9987d0SSujith 		printk(KERN_ERR
932fb9987d0SSujith 			"ath9k_htc: No USB devices found,"
933fb9987d0SSujith 			" driver not installed.\n");
934fb9987d0SSujith 		error = -ENODEV;
935fb9987d0SSujith 		goto err_usb;
936fb9987d0SSujith 	}
937fb9987d0SSujith 
938fb9987d0SSujith 	return 0;
939fb9987d0SSujith 
940fb9987d0SSujith err_usb:
941e1572c5eSSujith 	ath9k_htc_debug_remove_root();
942fb9987d0SSujith err_dbg:
943fb9987d0SSujith 	return error;
944fb9987d0SSujith }
945fb9987d0SSujith module_init(ath9k_htc_init);
946fb9987d0SSujith 
947fb9987d0SSujith static void __exit ath9k_htc_exit(void)
948fb9987d0SSujith {
949fb9987d0SSujith 	ath9k_hif_usb_exit();
950e1572c5eSSujith 	ath9k_htc_debug_remove_root();
951fb9987d0SSujith 	printk(KERN_INFO "ath9k_htc: Driver unloaded\n");
952fb9987d0SSujith }
953fb9987d0SSujith module_exit(ath9k_htc_exit);
954