aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-08-26 02:11:21 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-29 15:30:31 -0400
commit2c452297ff3eaafad41d24fa03d54a169ced8de1 (patch)
treedd0df8030f6eea40766f205c81709c04a9fa090e
parentae2c30bfcd29c6f1215d58a1c5663d58978011b8 (diff)
iwlagn: upper layer stores iwl_rxon_context in skb's CB
This removes the need for iwl_tx_info. Each tx queue holds an array of skbs, the transport layer doesn't need to know anything about the context in which a specific skb is sent. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h8
5 files changed, 25 insertions, 41 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 8edb3f89b22d..60ba4f84285a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -454,7 +454,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
454 454
455 iwl_update_stats(priv, true, fc, len); 455 iwl_update_stats(priv, true, fc, len);
456 456
457 if (iwl_trans_tx(trans(priv), skb, tx_cmd, txq_id, fc, is_agg, ctx)) 457 info->driver_data[0] = ctx;
458
459 if (iwl_trans_tx(trans(priv), skb, tx_cmd, txq_id, fc, is_agg))
458 goto drop_unlock_sta; 460 goto drop_unlock_sta;
459 461
460 if (ieee80211_is_data_qos(fc)) { 462 if (ieee80211_is_data_qos(fc)) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 413340498997..aa56736aebb3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -146,12 +146,6 @@ struct iwl_queue {
146 * space less than this */ 146 * space less than this */
147}; 147};
148 148
149/* One for each TFD */
150struct iwl_tx_info {
151 struct sk_buff *skb;
152 struct iwl_rxon_context *ctx;
153};
154
155/** 149/**
156 * struct iwl_tx_queue - Tx Queue for DMA 150 * struct iwl_tx_queue - Tx Queue for DMA
157 * @q: generic Rx/Tx queue descriptor 151 * @q: generic Rx/Tx queue descriptor
@@ -177,7 +171,7 @@ struct iwl_tx_queue {
177 struct iwl_tfd *tfds; 171 struct iwl_tfd *tfds;
178 struct iwl_device_cmd **cmd; 172 struct iwl_device_cmd **cmd;
179 struct iwl_cmd_meta *meta; 173 struct iwl_cmd_meta *meta;
180 struct iwl_tx_info *txb; 174 struct sk_buff **skbs;
181 unsigned long time_stamp; 175 unsigned long time_stamp;
182 u8 need_update; 176 u8 need_update;
183 u8 sched_retry; 177 u8 sched_retry;
@@ -1373,9 +1367,9 @@ extern struct iwl_mod_params iwlagn_mod_params;
1373static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, 1367static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
1374 int txq_id, int idx) 1368 int txq_id, int idx)
1375{ 1369{
1376 if (priv->txq[txq_id].txb[idx].skb) 1370 if (priv->txq[txq_id].skbs[idx])
1377 return (struct ieee80211_hdr *)priv->txq[txq_id]. 1371 return (struct ieee80211_hdr *)priv->txq[txq_id].
1378 txb[idx].skb->data; 1372 skbs[idx]->data;
1379 return NULL; 1373 return NULL;
1380} 1374}
1381 1375
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
index 8c18a7545afd..cc518afd39e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
@@ -215,15 +215,15 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
215 DMA_TO_DEVICE); 215 DMA_TO_DEVICE);
216 216
217 /* free SKB */ 217 /* free SKB */
218 if (txq->txb) { 218 if (txq->skbs) {
219 struct sk_buff *skb; 219 struct sk_buff *skb;
220 220
221 skb = txq->txb[index].skb; 221 skb = txq->skbs[index];
222 222
223 /* can be called from irqs-disabled context */ 223 /* can be called from irqs-disabled context */
224 if (skb) { 224 if (skb) {
225 dev_kfree_skb_any(skb); 225 dev_kfree_skb_any(skb);
226 txq->txb[index].skb = NULL; 226 txq->skbs[index] = NULL;
227 } 227 }
228 } 228 }
229} 229}
@@ -1056,8 +1056,6 @@ void iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
1056{ 1056{
1057 struct iwl_tx_queue *txq = &priv(trans)->txq[txq_id]; 1057 struct iwl_tx_queue *txq = &priv(trans)->txq[txq_id];
1058 struct iwl_queue *q = &txq->q; 1058 struct iwl_queue *q = &txq->q;
1059 struct iwl_tx_info *tx_info;
1060 struct ieee80211_tx_info *info;
1061 int last_to_free; 1059 int last_to_free;
1062 1060
1063 /*Since we free until index _not_ inclusive, the one before index is 1061 /*Since we free until index _not_ inclusive, the one before index is
@@ -1083,17 +1081,12 @@ void iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
1083 q->read_ptr != index; 1081 q->read_ptr != index;
1084 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { 1082 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
1085 1083
1086 tx_info = &txq->txb[txq->q.read_ptr]; 1084 if (WARN_ON_ONCE(txq->skbs[txq->q.read_ptr] == NULL))
1087
1088 if (WARN_ON_ONCE(tx_info->skb == NULL))
1089 continue; 1085 continue;
1090 1086
1091 info = IEEE80211_SKB_CB(tx_info->skb); 1087 __skb_queue_tail(skbs, txq->skbs[txq->q.read_ptr]);
1092 info->driver_data[0] = tx_info->ctx;
1093
1094 __skb_queue_tail(skbs, tx_info->skb);
1095 1088
1096 tx_info->skb = NULL; 1089 txq->skbs[txq->q.read_ptr] = NULL;
1097 1090
1098 iwlagn_txq_inval_byte_cnt_tbl(trans, txq); 1091 iwlagn_txq_inval_byte_cnt_tbl(trans, txq);
1099 1092
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
index 0a3dd6bfd26a..e545898cddb3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -304,7 +304,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
304 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; 304 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;
305 int i; 305 int i;
306 306
307 if (WARN_ON(txq->meta || txq->cmd || txq->txb || txq->tfds)) 307 if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds))
308 return -EINVAL; 308 return -EINVAL;
309 309
310 txq->q.n_window = slots_num; 310 txq->q.n_window = slots_num;
@@ -328,15 +328,15 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
328 /* Driver private data, only for Tx (not command) queues, 328 /* Driver private data, only for Tx (not command) queues,
329 * not shared with device. */ 329 * not shared with device. */
330 if (txq_id != trans->shrd->cmd_queue) { 330 if (txq_id != trans->shrd->cmd_queue) {
331 txq->txb = kzalloc(sizeof(txq->txb[0]) * 331 txq->skbs = kzalloc(sizeof(txq->skbs[0]) *
332 TFD_QUEUE_SIZE_MAX, GFP_KERNEL); 332 TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
333 if (!txq->txb) { 333 if (!txq->skbs) {
334 IWL_ERR(trans, "kmalloc for auxiliary BD " 334 IWL_ERR(trans, "kmalloc for auxiliary BD "
335 "structures failed\n"); 335 "structures failed\n");
336 goto error; 336 goto error;
337 } 337 }
338 } else { 338 } else {
339 txq->txb = NULL; 339 txq->skbs = NULL;
340 } 340 }
341 341
342 /* Circular buffer of transmit frame descriptors (TFDs), 342 /* Circular buffer of transmit frame descriptors (TFDs),
@@ -351,8 +351,8 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
351 351
352 return 0; 352 return 0;
353error: 353error:
354 kfree(txq->txb); 354 kfree(txq->skbs);
355 txq->txb = NULL; 355 txq->skbs = NULL;
356 /* since txq->cmd has been zeroed, 356 /* since txq->cmd has been zeroed,
357 * all non allocated cmd[i] will be NULL */ 357 * all non allocated cmd[i] will be NULL */
358 if (txq->cmd) 358 if (txq->cmd)
@@ -453,8 +453,8 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id)
453 } 453 }
454 454
455 /* De-alloc array of per-TFD driver data */ 455 /* De-alloc array of per-TFD driver data */
456 kfree(txq->txb); 456 kfree(txq->skbs);
457 txq->txb = NULL; 457 txq->skbs = NULL;
458 458
459 /* deallocate arrays */ 459 /* deallocate arrays */
460 kfree(txq->cmd); 460 kfree(txq->cmd);
@@ -1035,8 +1035,7 @@ static struct iwl_tx_cmd *iwl_trans_pcie_get_tx_cmd(struct iwl_trans *trans,
1035} 1035}
1036 1036
1037static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb, 1037static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb,
1038 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu, 1038 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu)
1039 struct iwl_rxon_context *ctx)
1040{ 1039{
1041 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 1040 struct iwl_tx_queue *txq = &priv->txq[txq_id];
1042 struct iwl_queue *q = &txq->q; 1041 struct iwl_queue *q = &txq->q;
@@ -1051,9 +1050,7 @@ static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb,
1051 u8 hdr_len = ieee80211_hdrlen(fc); 1050 u8 hdr_len = ieee80211_hdrlen(fc);
1052 1051
1053 /* Set up driver data for this TFD */ 1052 /* Set up driver data for this TFD */
1054 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); 1053 txq->skbs[q->write_ptr] = skb;
1055 txq->txb[q->write_ptr].skb = skb;
1056 txq->txb[q->write_ptr].ctx = ctx;
1057 1054
1058 /* Set up first empty entry in queue's array of Tx/cmd buffers */ 1055 /* Set up first empty entry in queue's array of Tx/cmd buffers */
1059 out_meta = &txq->meta[q->write_ptr]; 1056 out_meta = &txq->meta[q->write_ptr];
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index e72e4809a410..2385de267bb7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -119,8 +119,7 @@ struct iwl_trans_ops {
119 const void *data); 119 const void *data);
120 struct iwl_tx_cmd * (*get_tx_cmd)(struct iwl_trans *trans, int txq_id); 120 struct iwl_tx_cmd * (*get_tx_cmd)(struct iwl_trans *trans, int txq_id);
121 int (*tx)(struct iwl_priv *priv, struct sk_buff *skb, 121 int (*tx)(struct iwl_priv *priv, struct sk_buff *skb,
122 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu, 122 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu);
123 struct iwl_rxon_context *ctx);
124 void (*reclaim)(struct iwl_trans *trans, int txq_id, int ssn, 123 void (*reclaim)(struct iwl_trans *trans, int txq_id, int ssn,
125 u32 status, struct sk_buff_head *skbs); 124 u32 status, struct sk_buff_head *skbs);
126 125
@@ -198,10 +197,9 @@ static inline struct iwl_tx_cmd *iwl_trans_get_tx_cmd(struct iwl_trans *trans,
198} 197}
199 198
200static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, 199static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
201 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu, 200 struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu)
202 struct iwl_rxon_context *ctx)
203{ 201{
204 return trans->ops->tx(priv(trans), skb, tx_cmd, txq_id, fc, ampdu, ctx); 202 return trans->ops->tx(priv(trans), skb, tx_cmd, txq_id, fc, ampdu);
205} 203}
206 204
207static inline void iwl_trans_reclaim(struct iwl_trans *trans, int txq_id, 205static inline void iwl_trans_reclaim(struct iwl_trans *trans, int txq_id,