aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorSujith Manoharan <Sujith.Manoharan@atheros.com>2011-04-13 01:54:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-13 15:22:53 -0400
commit40dc9e4b86963b77918f1b8fa02b98c1e420a7e1 (patch)
tree6ea7c12df61b0e0c96a502aabbb9441443637229 /drivers/net/wireless/ath
parente723f3900c3b23feb427672c6ccfe5d4243d2c2d (diff)
ath9k_htc: Use SKB's private area for TX parameters
For all packets sent through the USB_WLAN_TX_PIPE endpoint, the private area of the SKB's tx_info can be used to store driver-specific information. For packets sent through USB_REG_OUT_PIPE, this will not make a difference since they are routed through a separate routine that doesn't access the private region. This would help in situations where TX information is required in the URB callback. 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/hif_usb.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c2
7 files changed, 49 insertions, 33 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 23094b70d6eb..e252576760d1 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -284,9 +284,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev)
284 return ret; 284 return ret;
285} 285}
286 286
287static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, 287static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb)
288 struct ath9k_htc_tx_ctl *tx_ctl)
289{ 288{
289 struct ath9k_htc_tx_ctl *tx_ctl;
290 unsigned long flags; 290 unsigned long flags;
291 291
292 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); 292 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
@@ -305,12 +305,14 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
305 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); 305 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
306 hif_dev->tx.tx_skb_cnt++; 306 hif_dev->tx.tx_skb_cnt++;
307 307
308 /* Send normal frames immediately */ 308 tx_ctl = HTC_SKB_CB(skb);
309 if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL))) 309
310 /* Send normal/mgmt/beacon frames immediately */
311 if (tx_ctl->type != ATH9K_HTC_AMPDU)
310 __hif_usb_tx(hif_dev); 312 __hif_usb_tx(hif_dev);
311 313
312 /* Check if AMPDUs have to be sent immediately */ 314 /* Check if AMPDUs have to be sent immediately */
313 if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) && 315 if ((tx_ctl->type == ATH9K_HTC_AMPDU) &&
314 (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && 316 (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
315 (hif_dev->tx.tx_skb_cnt < 2)) { 317 (hif_dev->tx.tx_skb_cnt < 2)) {
316 __hif_usb_tx(hif_dev); 318 __hif_usb_tx(hif_dev);
@@ -352,15 +354,14 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id)
352 } 354 }
353} 355}
354 356
355static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, 357static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb)
356 struct ath9k_htc_tx_ctl *tx_ctl)
357{ 358{
358 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; 359 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
359 int ret = 0; 360 int ret = 0;
360 361
361 switch (pipe_id) { 362 switch (pipe_id) {
362 case USB_WLAN_TX_PIPE: 363 case USB_WLAN_TX_PIPE:
363 ret = hif_usb_send_tx(hif_dev, skb, tx_ctl); 364 ret = hif_usb_send_tx(hif_dev, skb);
364 break; 365 break;
365 case USB_REG_OUT_PIPE: 366 case USB_REG_OUT_PIPE:
366 ret = hif_usb_send_regout(hif_dev, skb); 367 ret = hif_usb_send_regout(hif_dev, skb);
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 0e48fa0efa77..2eabfe4ad268 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -67,8 +67,11 @@ enum htc_opmode {
67}; 67};
68 68
69#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) 69#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
70#define ATH9K_HTC_AMPDU 1 70
71#define ATH9K_HTC_AMPDU 1
71#define ATH9K_HTC_NORMAL 2 72#define ATH9K_HTC_NORMAL 2
73#define ATH9K_HTC_BEACON 3
74#define ATH9K_HTC_MGMT 4
72 75
73#define ATH9K_HTC_TX_CTSONLY 0x1 76#define ATH9K_HTC_TX_CTSONLY 0x1
74#define ATH9K_HTC_TX_RTSCTS 0x2 77#define ATH9K_HTC_TX_RTSCTS 0x2
@@ -288,6 +291,15 @@ struct ath9k_htc_tx_ctl {
288 u8 type; /* ATH9K_HTC_* */ 291 u8 type; /* ATH9K_HTC_* */
289}; 292};
290 293
294static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
295{
296 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
297
298 BUILD_BUG_ON(sizeof(struct ath9k_htc_tx_ctl) >
299 IEEE80211_TX_INFO_DRIVER_DATA_SIZE);
300 return (struct ath9k_htc_tx_ctl *) &tx_info->driver_data;
301}
302
291#ifdef CONFIG_ATH9K_HTC_DEBUGFS 303#ifdef CONFIG_ATH9K_HTC_DEBUGFS
292 304
293#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) 305#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 2180a9da3801..713def184519 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -341,7 +341,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
341 struct ieee80211_vif *vif; 341 struct ieee80211_vif *vif;
342 struct ath9k_htc_vif *avp; 342 struct ath9k_htc_vif *avp;
343 struct tx_beacon_header beacon_hdr; 343 struct tx_beacon_header beacon_hdr;
344 struct ath9k_htc_tx_ctl tx_ctl; 344 struct ath9k_htc_tx_ctl *tx_ctl;
345 struct ieee80211_tx_info *info; 345 struct ieee80211_tx_info *info;
346 struct ieee80211_mgmt *mgmt; 346 struct ieee80211_mgmt *mgmt;
347 struct sk_buff *beacon; 347 struct sk_buff *beacon;
@@ -349,7 +349,6 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
349 int ret; 349 int ret;
350 350
351 memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); 351 memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
352 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
353 352
354 spin_lock_bh(&priv->beacon_lock); 353 spin_lock_bh(&priv->beacon_lock);
355 354
@@ -384,12 +383,16 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
384 hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); 383 hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
385 } 384 }
386 385
387 tx_ctl.type = ATH9K_HTC_NORMAL; 386 tx_ctl = HTC_SKB_CB(beacon);
387 memset(tx_ctl, 0, sizeof(*tx_ctl));
388
389 tx_ctl->type = ATH9K_HTC_BEACON;
390
388 beacon_hdr.vif_index = avp->index; 391 beacon_hdr.vif_index = avp->index;
389 tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); 392 tx_fhdr = skb_push(beacon, sizeof(beacon_hdr));
390 memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); 393 memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
391 394
392 ret = htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); 395 ret = htc_send(priv->htc, beacon, priv->beacon_ep);
393 if (ret != 0) { 396 if (ret != 0) {
394 if (ret == -ENOMEM) { 397 if (ret == -ENOMEM) {
395 ath_dbg(common, ATH_DBG_BSTUCK, 398 ath_dbg(common, ATH_DBG_BSTUCK,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 7cd3e4e66aa6..ab55dff4721f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -89,13 +89,16 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
89 struct ieee80211_vif *vif = tx_info->control.vif; 89 struct ieee80211_vif *vif = tx_info->control.vif;
90 struct ath9k_htc_sta *ista; 90 struct ath9k_htc_sta *ista;
91 struct ath9k_htc_vif *avp = NULL; 91 struct ath9k_htc_vif *avp = NULL;
92 struct ath9k_htc_tx_ctl tx_ctl; 92 struct ath9k_htc_tx_ctl *tx_ctl;
93 enum htc_endpoint_id epid; 93 enum htc_endpoint_id epid;
94 u16 qnum; 94 u16 qnum;
95 __le16 fc; 95 __le16 fc;
96 u8 *tx_fhdr; 96 u8 *tx_fhdr;
97 u8 sta_idx, vif_idx; 97 u8 sta_idx, vif_idx;
98 98
99 tx_ctl = HTC_SKB_CB(skb);
100 memset(tx_ctl, 0, sizeof(*tx_ctl));
101
99 hdr = (struct ieee80211_hdr *) skb->data; 102 hdr = (struct ieee80211_hdr *) skb->data;
100 fc = hdr->frame_control; 103 fc = hdr->frame_control;
101 104
@@ -126,8 +129,6 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
126 sta_idx = priv->vif_sta_pos[vif_idx]; 129 sta_idx = priv->vif_sta_pos[vif_idx];
127 } 130 }
128 131
129 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
130
131 if (ieee80211_is_data(fc)) { 132 if (ieee80211_is_data(fc)) {
132 struct tx_frame_hdr tx_hdr; 133 struct tx_frame_hdr tx_hdr;
133 u32 flags = 0; 134 u32 flags = 0;
@@ -139,10 +140,10 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
139 tx_hdr.vif_idx = vif_idx; 140 tx_hdr.vif_idx = vif_idx;
140 141
141 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { 142 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
142 tx_ctl.type = ATH9K_HTC_AMPDU; 143 tx_ctl->type = ATH9K_HTC_AMPDU;
143 tx_hdr.data_type = ATH9K_HTC_AMPDU; 144 tx_hdr.data_type = ATH9K_HTC_AMPDU;
144 } else { 145 } else {
145 tx_ctl.type = ATH9K_HTC_NORMAL; 146 tx_ctl->type = ATH9K_HTC_NORMAL;
146 tx_hdr.data_type = ATH9K_HTC_NORMAL; 147 tx_hdr.data_type = ATH9K_HTC_NORMAL;
147 } 148 }
148 149
@@ -212,7 +213,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
212 mgmt->u.probe_resp.timestamp = avp->tsfadjust; 213 mgmt->u.probe_resp.timestamp = avp->tsfadjust;
213 } 214 }
214 215
215 tx_ctl.type = ATH9K_HTC_NORMAL; 216 tx_ctl->type = ATH9K_HTC_MGMT;
216 217
217 mgmt_hdr.node_idx = sta_idx; 218 mgmt_hdr.node_idx = sta_idx;
218 mgmt_hdr.vif_idx = vif_idx; 219 mgmt_hdr.vif_idx = vif_idx;
@@ -230,7 +231,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
230 epid = priv->mgmt_ep; 231 epid = priv->mgmt_ep;
231 } 232 }
232send: 233send:
233 return htc_send(priv->htc, skb, epid, &tx_ctl); 234 return htc_send(priv->htc, skb, epid);
234} 235}
235 236
236static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, 237static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index c41ab8c30161..6ee53de45c6a 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -17,8 +17,8 @@
17#include "htc.h" 17#include "htc.h"
18 18
19static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, 19static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
20 u16 len, u8 flags, u8 epid, 20 u16 len, u8 flags, u8 epid)
21 struct ath9k_htc_tx_ctl *tx_ctl) 21
22{ 22{
23 struct htc_frame_hdr *hdr; 23 struct htc_frame_hdr *hdr;
24 struct htc_endpoint *endpoint = &target->endpoint[epid]; 24 struct htc_endpoint *endpoint = &target->endpoint[epid];
@@ -30,8 +30,8 @@ static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
30 hdr->flags = flags; 30 hdr->flags = flags;
31 hdr->payload_len = cpu_to_be16(len); 31 hdr->payload_len = cpu_to_be16(len);
32 32
33 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb, 33 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb);
34 tx_ctl); 34
35 return status; 35 return status;
36} 36}
37 37
@@ -162,7 +162,7 @@ static int htc_config_pipe_credits(struct htc_target *target)
162 162
163 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; 163 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
164 164
165 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); 165 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
166 if (ret) 166 if (ret)
167 goto err; 167 goto err;
168 168
@@ -197,7 +197,7 @@ static int htc_setup_complete(struct htc_target *target)
197 197
198 target->htc_flags |= HTC_OP_START_WAIT; 198 target->htc_flags |= HTC_OP_START_WAIT;
199 199
200 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); 200 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
201 if (ret) 201 if (ret)
202 goto err; 202 goto err;
203 203
@@ -268,7 +268,7 @@ int htc_connect_service(struct htc_target *target,
268 conn_msg->dl_pipeid = endpoint->dl_pipeid; 268 conn_msg->dl_pipeid = endpoint->dl_pipeid;
269 conn_msg->ul_pipeid = endpoint->ul_pipeid; 269 conn_msg->ul_pipeid = endpoint->ul_pipeid;
270 270
271 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); 271 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
272 if (ret) 272 if (ret)
273 goto err; 273 goto err;
274 274
@@ -287,9 +287,9 @@ err:
287} 287}
288 288
289int htc_send(struct htc_target *target, struct sk_buff *skb, 289int htc_send(struct htc_target *target, struct sk_buff *skb,
290 enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl) 290 enum htc_endpoint_id epid)
291{ 291{
292 return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl); 292 return htc_issue_send(target, skb, skb->len, 0, epid);
293} 293}
294 294
295void htc_stop(struct htc_target *target) 295void htc_stop(struct htc_target *target)
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index ecd018798c47..3531552672e0 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -35,8 +35,7 @@ struct ath9k_htc_hif {
35 35
36 void (*start) (void *hif_handle, u8 pipe); 36 void (*start) (void *hif_handle, u8 pipe);
37 void (*stop) (void *hif_handle, u8 pipe); 37 void (*stop) (void *hif_handle, u8 pipe);
38 int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf, 38 int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf);
39 struct ath9k_htc_tx_ctl *tx_ctl);
40}; 39};
41 40
42enum htc_endpoint_id { 41enum htc_endpoint_id {
@@ -206,7 +205,7 @@ int htc_connect_service(struct htc_target *target,
206 struct htc_service_connreq *service_connreq, 205 struct htc_service_connreq *service_connreq,
207 enum htc_endpoint_id *conn_rsp_eid); 206 enum htc_endpoint_id *conn_rsp_eid);
208int htc_send(struct htc_target *target, struct sk_buff *skb, 207int htc_send(struct htc_target *target, struct sk_buff *skb,
209 enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl); 208 enum htc_endpoint_id eid);
210void htc_stop(struct htc_target *target); 209void htc_stop(struct htc_target *target);
211void htc_start(struct htc_target *target); 210void htc_start(struct htc_target *target);
212 211
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 3b8f25fbecfd..83d1e0e5dd8c 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -267,7 +267,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi,
267 hdr->command_id = cpu_to_be16(cmd); 267 hdr->command_id = cpu_to_be16(cmd);
268 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); 268 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
269 269
270 return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL); 270 return htc_send(wmi->htc, skb, wmi->ctrl_epid);
271} 271}
272 272
273int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, 273int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,