aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c68
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c33
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h27
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h14
6 files changed, 143 insertions, 48 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 0be395528261..7c5cbb192a6c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -103,6 +103,15 @@
103#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate)) 103#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
104 104
105/* 105/*
106 * Determine the alignment requirement,
107 * to make sure the 802.11 payload is padded to a 4-byte boundrary
108 * we must determine the address of the payload and calculate the
109 * amount of bytes needed to move the data.
110 */
111#define ALIGN_SIZE(__skb, __header) \
112 ( ((unsigned long)((__skb)->data + (__header))) & 3 )
113
114/*
106 * Standard timing and size defines. 115 * Standard timing and size defines.
107 * These values should follow the ieee80211 specifications. 116 * These values should follow the ieee80211 specifications.
108 */ 117 */
@@ -590,6 +599,7 @@ enum rt2x00_flags {
590 DRIVER_REQUIRE_SCHEDULED, 599 DRIVER_REQUIRE_SCHEDULED,
591 DRIVER_REQUIRE_DMA, 600 DRIVER_REQUIRE_DMA,
592 DRIVER_REQUIRE_COPY_IV, 601 DRIVER_REQUIRE_COPY_IV,
602 DRIVER_REQUIRE_L2PAD,
593 603
594 /* 604 /*
595 * Driver features 605 * Driver features
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index ae31581372c0..57ab42cfed34 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -65,7 +65,7 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
65 __set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags); 65 __set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags);
66 66
67 txdesc->key_idx = hw_key->hw_key_idx; 67 txdesc->key_idx = hw_key->hw_key_idx;
68 txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb); 68 txdesc->iv_offset = txdesc->header_length;
69 txdesc->iv_len = hw_key->iv_len; 69 txdesc->iv_len = hw_key->iv_len;
70 70
71 if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) 71 if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
@@ -132,17 +132,16 @@ void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
132 skb_pull(skb, txdesc->iv_len); 132 skb_pull(skb, txdesc->iv_len);
133 133
134 /* IV/EIV data has officially be stripped */ 134 /* IV/EIV data has officially be stripped */
135 skbdesc->flags |= FRAME_DESC_IV_STRIPPED; 135 skbdesc->flags |= SKBDESC_IV_STRIPPED;
136} 136}
137 137
138void rt2x00crypto_tx_insert_iv(struct sk_buff *skb) 138void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length)
139{ 139{
140 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 140 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
141 unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
142 const unsigned int iv_len = 141 const unsigned int iv_len =
143 ((!!(skbdesc->iv[0])) * 4) + ((!!(skbdesc->iv[1])) * 4); 142 ((!!(skbdesc->iv[0])) * 4) + ((!!(skbdesc->iv[1])) * 4);
144 143
145 if (!(skbdesc->flags & FRAME_DESC_IV_STRIPPED)) 144 if (!(skbdesc->flags & SKBDESC_IV_STRIPPED))
146 return; 145 return;
147 146
148 skb_push(skb, iv_len); 147 skb_push(skb, iv_len);
@@ -154,14 +153,15 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
154 memcpy(skb->data + header_length, skbdesc->iv, iv_len); 153 memcpy(skb->data + header_length, skbdesc->iv, iv_len);
155 154
156 /* IV/EIV data has returned into the frame */ 155 /* IV/EIV data has returned into the frame */
157 skbdesc->flags &= ~FRAME_DESC_IV_STRIPPED; 156 skbdesc->flags &= ~SKBDESC_IV_STRIPPED;
158} 157}
159 158
160void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, 159void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
161 unsigned int header_length, 160 unsigned int header_length,
162 struct rxdone_entry_desc *rxdesc) 161 struct rxdone_entry_desc *rxdesc)
163{ 162{
164 unsigned int payload_len = rxdesc->size - header_length; 163 unsigned int payload_len = rxdesc->size - header_length;
164 unsigned int align = ALIGN_SIZE(skb, header_length);
165 unsigned int iv_len; 165 unsigned int iv_len;
166 unsigned int icv_len; 166 unsigned int icv_len;
167 unsigned int transfer = 0; 167 unsigned int transfer = 0;
@@ -191,32 +191,48 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
191 } 191 }
192 192
193 /* 193 /*
194 * Make room for new data, note that we increase both 194 * Make room for new data. There are 2 possibilities
195 * headsize and tailsize when required. The tailsize is 195 * either the alignment is already present between
196 * only needed when ICV data needs to be inserted and 196 * the 802.11 header and payload. In that case we
197 * the padding is smaller than the ICV data. 197 * we have to move the header less then the iv_len
198 * When alignment requirements is greater than the 198 * since we can use the already available l2pad bytes
199 * ICV data we must trim the skb to the correct size 199 * for the iv data.
200 * because we need to remove the extra bytes. 200 * When the alignment must be added manually we must
201 * move the header more then iv_len since we must
202 * make room for the payload move as well.
201 */ 203 */
202 skb_push(skb, iv_len + align); 204 if (l2pad) {
203 if (align < icv_len) 205 skb_push(skb, iv_len - align);
204 skb_put(skb, icv_len - align); 206 skb_put(skb, icv_len);
205 else if (align > icv_len)
206 skb_trim(skb, rxdesc->size + iv_len + icv_len);
207 207
208 /* Move ieee80211 header */ 208 /* Move ieee80211 header */
209 memmove(skb->data + transfer, 209 memmove(skb->data + transfer,
210 skb->data + transfer + iv_len + align, 210 skb->data + transfer + (iv_len - align),
211 header_length); 211 header_length);
212 transfer += header_length; 212 transfer += header_length;
213 } else {
214 skb_push(skb, iv_len + align);
215 if (align < icv_len)
216 skb_put(skb, icv_len - align);
217 else if (align > icv_len)
218 skb_trim(skb, rxdesc->size + iv_len + icv_len);
219
220 /* Move ieee80211 header */
221 memmove(skb->data + transfer,
222 skb->data + transfer + iv_len + align,
223 header_length);
224 transfer += header_length;
225 }
213 226
214 /* Copy IV/EIV data */ 227 /* Copy IV/EIV data */
215 memcpy(skb->data + transfer, rxdesc->iv, iv_len); 228 memcpy(skb->data + transfer, rxdesc->iv, iv_len);
216 transfer += iv_len; 229 transfer += iv_len;
217 230
218 /* Move payload */ 231 /*
219 if (align) { 232 * Move payload for alignment purposes. Note that
233 * this is only needed when no l2 padding is present.
234 */
235 if (!l2pad) {
220 memmove(skb->data + transfer, 236 memmove(skb->data + transfer,
221 skb->data + transfer + align, 237 skb->data + transfer + align,
222 payload_len); 238 payload_len);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 5752aaae906b..e15086af7278 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -227,6 +227,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
227 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 227 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
228 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 228 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
229 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); 229 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
230 unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
230 u8 rate_idx, rate_flags; 231 u8 rate_idx, rate_flags;
231 232
232 /* 233 /*
@@ -235,13 +236,19 @@ void rt2x00lib_txdone(struct queue_entry *entry,
235 rt2x00queue_unmap_skb(rt2x00dev, entry->skb); 236 rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
236 237
237 /* 238 /*
239 * Remove L2 padding which was added during
240 */
241 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
242 rt2x00queue_payload_align(entry->skb, true, header_length);
243
244 /*
238 * If the IV/EIV data was stripped from the frame before it was 245 * If the IV/EIV data was stripped from the frame before it was
239 * passed to the hardware, we should now reinsert it again because 246 * passed to the hardware, we should now reinsert it again because
240 * mac80211 will expect the the same data to be present it the 247 * mac80211 will expect the the same data to be present it the
241 * frame as it was passed to us. 248 * frame as it was passed to us.
242 */ 249 */
243 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) 250 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
244 rt2x00crypto_tx_insert_iv(entry->skb); 251 rt2x00crypto_tx_insert_iv(entry->skb, header_length);
245 252
246 /* 253 /*
247 * Send frame to debugfs immediately, after this call is completed 254 * Send frame to debugfs immediately, after this call is completed
@@ -325,7 +332,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
325 struct ieee80211_supported_band *sband; 332 struct ieee80211_supported_band *sband;
326 const struct rt2x00_rate *rate; 333 const struct rt2x00_rate *rate;
327 unsigned int header_length; 334 unsigned int header_length;
328 unsigned int align; 335 bool l2pad;
329 unsigned int i; 336 unsigned int i;
330 int idx = -1; 337 int idx = -1;
331 338
@@ -348,12 +355,15 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
348 memset(&rxdesc, 0, sizeof(rxdesc)); 355 memset(&rxdesc, 0, sizeof(rxdesc));
349 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); 356 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
350 357
358 /* Trim buffer to correct size */
359 skb_trim(entry->skb, rxdesc.size);
360
351 /* 361 /*
352 * The data behind the ieee80211 header must be 362 * The data behind the ieee80211 header must be
353 * aligned on a 4 byte boundary. 363 * aligned on a 4 byte boundary.
354 */ 364 */
355 header_length = ieee80211_get_hdrlen_from_skb(entry->skb); 365 header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
356 align = ((unsigned long)(entry->skb->data + header_length)) & 3; 366 l2pad = !!(rxdesc.dev_flags & RXDONE_L2PAD);
357 367
358 /* 368 /*
359 * Hardware might have stripped the IV/EIV/ICV data, 369 * Hardware might have stripped the IV/EIV/ICV data,
@@ -362,18 +372,11 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
362 * in which case we should reinsert the data into the frame. 372 * in which case we should reinsert the data into the frame.
363 */ 373 */
364 if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) && 374 if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) &&
365 (rxdesc.flags & RX_FLAG_IV_STRIPPED)) { 375 (rxdesc.flags & RX_FLAG_IV_STRIPPED))
366 rt2x00crypto_rx_insert_iv(entry->skb, align, 376 rt2x00crypto_rx_insert_iv(entry->skb, l2pad, header_length,
367 header_length, &rxdesc); 377 &rxdesc);
368 } else if (align) { 378 else
369 skb_push(entry->skb, align); 379 rt2x00queue_payload_align(entry->skb, l2pad, header_length);
370 /* Move entire frame in 1 command */
371 memmove(entry->skb->data, entry->skb->data + align,
372 rxdesc.size);
373 }
374
375 /* Update data pointers, trim buffer to correct size */
376 skb_trim(entry->skb, rxdesc.size);
377 380
378 /* 381 /*
379 * Update RX statistics. 382 * Update RX statistics.
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index af3c47bd43bd..aa284e48d2c2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -113,6 +113,23 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
113void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); 113void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
114 114
115/** 115/**
116 * rt2x00queue_payload_align - Align 802.11 payload to 4-byte boundary
117 * @skb: The skb to align
118 * @l2pad: Should L2 padding be used
119 * @header_length: Length of 802.11 header
120 *
121 * This function prepares the @skb to be send to the device or mac80211.
122 * If @l2pad is set to true padding will occur between the 802.11 header
123 * and payload. Otherwise the padding will be done in front of the 802.11
124 * header.
125 * When @l2pad is set the function will check for the &SKBDESC_L2_PADDED
126 * flag in &skb_frame_desc. If that flag is set, the padding is removed
127 * and the flag cleared. Otherwise the padding is added and the flag is set.
128 */
129void rt2x00queue_payload_align(struct sk_buff *skb,
130 bool l2pad, unsigned int header_length);
131
132/**
116 * rt2x00queue_write_tx_frame - Write TX frame to hardware 133 * rt2x00queue_write_tx_frame - Write TX frame to hardware
117 * @queue: Queue over which the frame should be send 134 * @queue: Queue over which the frame should be send
118 * @skb: The skb to send 135 * @skb: The skb to send
@@ -299,8 +316,8 @@ void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
299 struct txentry_desc *txdesc); 316 struct txentry_desc *txdesc);
300void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, 317void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
301 struct txentry_desc *txdesc); 318 struct txentry_desc *txdesc);
302void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); 319void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length);
303void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, 320void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
304 unsigned int header_length, 321 unsigned int header_length,
305 struct rxdone_entry_desc *rxdesc); 322 struct rxdone_entry_desc *rxdesc);
306#else 323#else
@@ -330,12 +347,12 @@ static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
330{ 347{
331} 348}
332 349
333static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb) 350static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb,
351 unsigned int header_length)
334{ 352{
335} 353}
336 354
337static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, 355static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
338 unsigned int align,
339 unsigned int header_length, 356 unsigned int header_length,
340 struct rxdone_entry_desc *rxdesc) 357 struct rxdone_entry_desc *rxdesc)
341{ 358{
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 6f78915b364c..bc1742c1d51c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -148,6 +148,35 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
148 dev_kfree_skb_any(skb); 148 dev_kfree_skb_any(skb);
149} 149}
150 150
151void rt2x00queue_payload_align(struct sk_buff *skb,
152 bool l2pad, unsigned int header_length)
153{
154 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
155 unsigned int frame_length = skb->len;
156 unsigned int align = ALIGN_SIZE(skb, header_length);
157
158 if (!align)
159 return;
160
161 if (l2pad) {
162 if (skbdesc->flags & SKBDESC_L2_PADDED) {
163 /* Remove L2 padding */
164 memmove(skb->data + align, skb->data, header_length);
165 skb_pull(skb, align);
166 skbdesc->flags &= ~SKBDESC_L2_PADDED;
167 } else {
168 /* Add L2 padding */
169 skb_push(skb, align);
170 memmove(skb->data, skb->data + align, header_length);
171 skbdesc->flags |= SKBDESC_L2_PADDED;
172 }
173 } else {
174 /* Generic payload alignment to 4-byte boundary */
175 skb_push(skb, align);
176 memmove(skb->data, skb->data + align, frame_length);
177 }
178}
179
151static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, 180static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
152 struct txentry_desc *txdesc) 181 struct txentry_desc *txdesc)
153{ 182{
@@ -259,6 +288,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
259 txdesc->aifs = entry->queue->aifs; 288 txdesc->aifs = entry->queue->aifs;
260 289
261 /* 290 /*
291 * Header and alignment information.
292 */
293 txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
294 txdesc->l2pad = ALIGN_SIZE(entry->skb, txdesc->header_length);
295
296 /*
262 * Check whether this frame is to be acked. 297 * Check whether this frame is to be acked.
263 */ 298 */
264 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) 299 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
@@ -416,6 +451,10 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
416 rt2x00crypto_tx_remove_iv(skb, &txdesc); 451 rt2x00crypto_tx_remove_iv(skb, &txdesc);
417 } 452 }
418 453
454 if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags))
455 rt2x00queue_payload_align(entry->skb, true,
456 txdesc.header_length);
457
419 /* 458 /*
420 * It could be possible that the queue was corrupted and this 459 * It could be possible that the queue was corrupted and this
421 * call failed. Since we always return NETDEV_TX_OK to mac80211, 460 * call failed. Since we always return NETDEV_TX_OK to mac80211,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index e3bfd73e319b..13e0ece176a1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -87,13 +87,16 @@ enum data_queue_qid {
87 * 87 *
88 * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX 88 * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX
89 * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX 89 * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
90 * @FRAME_DESC_IV_STRIPPED: Frame contained a IV/EIV provided by 90 * @SKBDESC_IV_STRIPPED: Frame contained a IV/EIV provided by
91 * mac80211 but was stripped for processing by the driver. 91 * mac80211 but was stripped for processing by the driver.
92 * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment,
93 * the padded bytes are located between header and payload.
92 */ 94 */
93enum skb_frame_desc_flags { 95enum skb_frame_desc_flags {
94 SKBDESC_DMA_MAPPED_RX = 1 << 0, 96 SKBDESC_DMA_MAPPED_RX = 1 << 0,
95 SKBDESC_DMA_MAPPED_TX = 1 << 1, 97 SKBDESC_DMA_MAPPED_TX = 1 << 1,
96 FRAME_DESC_IV_STRIPPED = 1 << 2, 98 SKBDESC_IV_STRIPPED = 1 << 2,
99 SKBDESC_L2_PADDED = 1 << 3
97}; 100};
98 101
99/** 102/**
@@ -148,6 +151,7 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
148 * @RXDONE_MY_BSS: Does this frame originate from device's BSS. 151 * @RXDONE_MY_BSS: Does this frame originate from device's BSS.
149 * @RXDONE_CRYPTO_IV: Driver provided IV/EIV data. 152 * @RXDONE_CRYPTO_IV: Driver provided IV/EIV data.
150 * @RXDONE_CRYPTO_ICV: Driver provided ICV data. 153 * @RXDONE_CRYPTO_ICV: Driver provided ICV data.
154 * @RXDONE_L2PAD: 802.11 payload has been padded to 4-byte boundary.
151 */ 155 */
152enum rxdone_entry_desc_flags { 156enum rxdone_entry_desc_flags {
153 RXDONE_SIGNAL_PLCP = 1 << 0, 157 RXDONE_SIGNAL_PLCP = 1 << 0,
@@ -155,6 +159,7 @@ enum rxdone_entry_desc_flags {
155 RXDONE_MY_BSS = 1 << 2, 159 RXDONE_MY_BSS = 1 << 2,
156 RXDONE_CRYPTO_IV = 1 << 3, 160 RXDONE_CRYPTO_IV = 1 << 3,
157 RXDONE_CRYPTO_ICV = 1 << 4, 161 RXDONE_CRYPTO_ICV = 1 << 4,
162 RXDONE_L2PAD = 1 << 5,
158}; 163};
159 164
160/** 165/**
@@ -267,6 +272,8 @@ enum txentry_desc_flags {
267 * 272 *
268 * @flags: Descriptor flags (See &enum queue_entry_flags). 273 * @flags: Descriptor flags (See &enum queue_entry_flags).
269 * @queue: Queue identification (See &enum data_queue_qid). 274 * @queue: Queue identification (See &enum data_queue_qid).
275 * @header_length: Length of 802.11 header.
276 * @l2pad: Amount of padding to align 802.11 payload to 4-byte boundrary.
270 * @length_high: PLCP length high word. 277 * @length_high: PLCP length high word.
271 * @length_low: PLCP length low word. 278 * @length_low: PLCP length low word.
272 * @signal: PLCP signal. 279 * @signal: PLCP signal.
@@ -287,6 +294,9 @@ struct txentry_desc {
287 294
288 enum data_queue_qid queue; 295 enum data_queue_qid queue;
289 296
297 u16 header_length;
298 u16 l2pad;
299
290 u16 length_high; 300 u16 length_high;
291 u16 length_low; 301 u16 length_low;
292 u16 signal; 302 u16 signal;