aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorSujith Manoharan <Sujith.Manoharan@atheros.com>2011-04-13 01:56:52 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-13 15:24:37 -0400
commit821f9414c0546fbc99a999e9dc613d1756e1de8a (patch)
treecef5c7efdd46a12e9de971b572ebba74a8eb6d84 /drivers/net/wireless/ath
parent2f80194c90caea3668d0e3739518bf100449a813 (diff)
ath9k_htc: Use helper routines for transmission
Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c227
1 files changed, 127 insertions, 100 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 86f5ce9b6e0e..723a3a9c5cd9 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -211,28 +211,140 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
211 return error; 211 return error;
212} 212}
213 213
214static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv,
215 struct ath9k_htc_vif *avp,
216 struct sk_buff *skb,
217 u8 sta_idx, u8 vif_idx, u8 slot)
218{
219 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
220 struct ieee80211_mgmt *mgmt;
221 struct ieee80211_hdr *hdr;
222 struct tx_mgmt_hdr mgmt_hdr;
223 struct ath9k_htc_tx_ctl *tx_ctl;
224 u8 *tx_fhdr;
225
226 tx_ctl = HTC_SKB_CB(skb);
227 hdr = (struct ieee80211_hdr *) skb->data;
228
229 memset(tx_ctl, 0, sizeof(*tx_ctl));
230 memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
231
232 /*
233 * Set the TSF adjust value for probe response
234 * frame also.
235 */
236 if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
237 mgmt = (struct ieee80211_mgmt *)skb->data;
238 mgmt->u.probe_resp.timestamp = avp->tsfadjust;
239 }
240
241 tx_ctl->type = ATH9K_HTC_MGMT;
242
243 mgmt_hdr.node_idx = sta_idx;
244 mgmt_hdr.vif_idx = vif_idx;
245 mgmt_hdr.tidno = 0;
246 mgmt_hdr.flags = 0;
247 mgmt_hdr.cookie = slot;
248
249 mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
250 if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
251 mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
252 else
253 mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
254
255 tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
256 memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
257 tx_ctl->epid = priv->mgmt_ep;
258}
259
260static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv,
261 struct ieee80211_vif *vif,
262 struct sk_buff *skb,
263 u8 sta_idx, u8 vif_idx, u8 slot,
264 bool is_cab)
265{
266 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
267 struct ieee80211_hdr *hdr;
268 struct ath9k_htc_tx_ctl *tx_ctl;
269 struct tx_frame_hdr tx_hdr;
270 u32 flags = 0;
271 u8 *qc, *tx_fhdr;
272 u16 qnum;
273
274 tx_ctl = HTC_SKB_CB(skb);
275 hdr = (struct ieee80211_hdr *) skb->data;
276
277 memset(tx_ctl, 0, sizeof(*tx_ctl));
278 memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
279
280 tx_hdr.node_idx = sta_idx;
281 tx_hdr.vif_idx = vif_idx;
282 tx_hdr.cookie = slot;
283
284 /*
285 * This is a bit redundant but it helps to get
286 * the per-packet index quickly when draining the
287 * TX queue in the HIF layer. Otherwise we would
288 * have to parse the packet contents ...
289 */
290 tx_ctl->sta_idx = sta_idx;
291
292 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
293 tx_ctl->type = ATH9K_HTC_AMPDU;
294 tx_hdr.data_type = ATH9K_HTC_AMPDU;
295 } else {
296 tx_ctl->type = ATH9K_HTC_NORMAL;
297 tx_hdr.data_type = ATH9K_HTC_NORMAL;
298 }
299
300 if (ieee80211_is_data_qos(hdr->frame_control)) {
301 qc = ieee80211_get_qos_ctl(hdr);
302 tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
303 }
304
305 /* Check for RTS protection */
306 if (priv->hw->wiphy->rts_threshold != (u32) -1)
307 if (skb->len > priv->hw->wiphy->rts_threshold)
308 flags |= ATH9K_HTC_TX_RTSCTS;
309
310 /* CTS-to-self */
311 if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
312 (vif && vif->bss_conf.use_cts_prot))
313 flags |= ATH9K_HTC_TX_CTSONLY;
314
315 tx_hdr.flags = cpu_to_be32(flags);
316 tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
317 if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
318 tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
319 else
320 tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
321
322 tx_fhdr = skb_push(skb, sizeof(tx_hdr));
323 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
324
325 if (is_cab) {
326 CAB_STAT_INC;
327 tx_ctl->epid = priv->cab_ep;
328 return;
329 }
330
331 qnum = skb_get_queue_mapping(skb);
332 tx_ctl->epid = get_htc_epid(priv, qnum);
333}
334
214int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, 335int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
215 struct sk_buff *skb, 336 struct sk_buff *skb,
216 u8 slot, bool is_cab) 337 u8 slot, bool is_cab)
217{ 338{
218 struct ieee80211_hdr *hdr; 339 struct ieee80211_hdr *hdr;
219 struct ieee80211_mgmt *mgmt;
220 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 340 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
221 struct ieee80211_sta *sta = tx_info->control.sta; 341 struct ieee80211_sta *sta = tx_info->control.sta;
222 struct ieee80211_vif *vif = tx_info->control.vif; 342 struct ieee80211_vif *vif = tx_info->control.vif;
223 struct ath9k_htc_sta *ista; 343 struct ath9k_htc_sta *ista;
224 struct ath9k_htc_vif *avp = NULL; 344 struct ath9k_htc_vif *avp = NULL;
225 struct ath9k_htc_tx_ctl *tx_ctl;
226 u16 qnum;
227 __le16 fc;
228 u8 *tx_fhdr;
229 u8 sta_idx, vif_idx; 345 u8 sta_idx, vif_idx;
230 346
231 tx_ctl = HTC_SKB_CB(skb);
232 memset(tx_ctl, 0, sizeof(*tx_ctl));
233
234 hdr = (struct ieee80211_hdr *) skb->data; 347 hdr = (struct ieee80211_hdr *) skb->data;
235 fc = hdr->frame_control;
236 348
237 /* 349 /*
238 * Find out on which interface this packet has to be 350 * Find out on which interface this packet has to be
@@ -261,99 +373,14 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
261 sta_idx = priv->vif_sta_pos[vif_idx]; 373 sta_idx = priv->vif_sta_pos[vif_idx];
262 } 374 }
263 375
264 if (ieee80211_is_data(fc)) { 376 if (ieee80211_is_data(hdr->frame_control))
265 struct tx_frame_hdr tx_hdr; 377 ath9k_htc_tx_data(priv, vif, skb,
266 u32 flags = 0; 378 sta_idx, vif_idx, slot, is_cab);
267 u8 *qc; 379 else
268 380 ath9k_htc_tx_mgmt(priv, avp, skb,
269 memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); 381 sta_idx, vif_idx, slot);
270
271 tx_hdr.node_idx = sta_idx;
272 tx_hdr.vif_idx = vif_idx;
273 tx_hdr.cookie = slot;
274
275 /*
276 * This is a bit redundant but it helps to get
277 * the per-packet index quickly when draining the
278 * TX queue in the HIF layer. Otherwise we would
279 * have to parse the packet contents ...
280 */
281 tx_ctl->sta_idx = sta_idx;
282
283 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
284 tx_ctl->type = ATH9K_HTC_AMPDU;
285 tx_hdr.data_type = ATH9K_HTC_AMPDU;
286 } else {
287 tx_ctl->type = ATH9K_HTC_NORMAL;
288 tx_hdr.data_type = ATH9K_HTC_NORMAL;
289 }
290
291 if (ieee80211_is_data_qos(fc)) {
292 qc = ieee80211_get_qos_ctl(hdr);
293 tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
294 }
295
296 /* Check for RTS protection */
297 if (priv->hw->wiphy->rts_threshold != (u32) -1)
298 if (skb->len > priv->hw->wiphy->rts_threshold)
299 flags |= ATH9K_HTC_TX_RTSCTS;
300
301 /* CTS-to-self */
302 if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
303 (vif && vif->bss_conf.use_cts_prot))
304 flags |= ATH9K_HTC_TX_CTSONLY;
305
306 tx_hdr.flags = cpu_to_be32(flags);
307 tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
308 if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
309 tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
310 else
311 tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
312
313 tx_fhdr = skb_push(skb, sizeof(tx_hdr));
314 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
315
316 if (is_cab) {
317 CAB_STAT_INC;
318 tx_ctl->epid = priv->cab_ep;
319 goto send;
320 }
321
322 qnum = skb_get_queue_mapping(skb);
323 tx_ctl->epid = get_htc_epid(priv, qnum);
324 } else {
325 struct tx_mgmt_hdr mgmt_hdr;
326
327 memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
328
329 /*
330 * Set the TSF adjust value for probe response
331 * frame also.
332 */
333 if (avp && unlikely(ieee80211_is_probe_resp(fc))) {
334 mgmt = (struct ieee80211_mgmt *)skb->data;
335 mgmt->u.probe_resp.timestamp = avp->tsfadjust;
336 }
337
338 tx_ctl->type = ATH9K_HTC_MGMT;
339
340 mgmt_hdr.node_idx = sta_idx;
341 mgmt_hdr.vif_idx = vif_idx;
342 mgmt_hdr.tidno = 0;
343 mgmt_hdr.flags = 0;
344 mgmt_hdr.cookie = slot;
345 382
346 mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
347 if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
348 mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
349 else
350 mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
351 383
352 tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
353 memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
354 tx_ctl->epid = priv->mgmt_ep;
355 }
356send:
357 return htc_send(priv->htc, skb); 384 return htc_send(priv->htc, skb);
358} 385}
359 386