aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-12-20 04:58:33 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 15:58:39 -0500
commit7b40982e235d6ff9343d38703eb48a0143afcc26 (patch)
tree996ffa0777166be363b55b9568fcd38f7a3c1e4e /drivers/net/wireless/rt2x00
parent91581b627287d8cc3ee382ee038e04c4beca8176 (diff)
rt2x00: Move code into seperate functions
Some functions have grown rapidly in size over the last time, some of those functions (like the rt2x00queue_create_tx_descriptor) will further increase in size soon, so it is best to start cutting it into logical pieces. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c40
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c193
4 files changed, 138 insertions, 114 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index aee9cba13eb3..e9d3ddae2785 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -49,9 +49,14 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
49void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, 49void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
50 struct txentry_desc *txdesc) 50 struct txentry_desc *txdesc)
51{ 51{
52 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
52 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 53 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
53 struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; 54 struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
54 55
56 if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
57 !hw_key || entry->skb->do_not_encrypt)
58 return;
59
55 __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); 60 __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags);
56 61
57 txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key); 62 txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key);
@@ -69,11 +74,17 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
69 __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags); 74 __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags);
70} 75}
71 76
72unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) 77unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
78 struct sk_buff *skb)
73{ 79{
80 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
74 struct ieee80211_key_conf *key = tx_info->control.hw_key; 81 struct ieee80211_key_conf *key = tx_info->control.hw_key;
75 unsigned int overhead = 0; 82 unsigned int overhead = 0;
76 83
84 if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
85 !key || skb->do_not_encrypt)
86 return overhead;
87
77 /* 88 /*
78 * Extend frame length to include IV/EIV/ICV/MMIC, 89 * Extend frame length to include IV/EIV/ICV/MMIC,
79 * note that these lengths should only be added when 90 * note that these lengths should only be added when
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index fccaffde6f55..5e8df250e50d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -282,7 +282,8 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
282enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); 282enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key);
283void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, 283void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
284 struct txentry_desc *txdesc); 284 struct txentry_desc *txdesc);
285unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info); 285unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
286 struct sk_buff *skb);
286void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len); 287void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len);
287void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); 288void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len);
288void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); 289void rt2x00crypto_tx_insert_iv(struct sk_buff *skb);
@@ -300,7 +301,8 @@ static inline void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
300{ 301{
301} 302}
302 303
303static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) 304static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
305 struct sk_buff *skb)
304{ 306{
305 return 0; 307 return 0;
306} 308}
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index e6fba830d1d3..bf7755a21645 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -79,8 +79,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
79 * RTS/CTS frame should use the length of the frame plus any 79 * RTS/CTS frame should use the length of the frame plus any
80 * encryption overhead that will be added by the hardware. 80 * encryption overhead that will be added by the hardware.
81 */ 81 */
82 if (!frag_skb->do_not_encrypt) 82 data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb);
83 data_length += rt2x00crypto_tx_overhead(tx_info);
84 83
85 if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) 84 if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
86 ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, 85 ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
@@ -484,6 +483,24 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
484EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); 483EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
485 484
486#ifdef CONFIG_RT2X00_LIB_CRYPTO 485#ifdef CONFIG_RT2X00_LIB_CRYPTO
486static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
487{
488 if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
489 memcpy(&crypto->key,
490 &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
491 sizeof(crypto->key));
492
493 if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
494 memcpy(&crypto->tx_mic,
495 &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
496 sizeof(crypto->tx_mic));
497
498 if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
499 memcpy(&crypto->rx_mic,
500 &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
501 sizeof(crypto->rx_mic));
502}
503
487int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 504int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
488 const u8 *local_address, const u8 *address, 505 const u8 *local_address, const u8 *address,
489 struct ieee80211_key_conf *key) 506 struct ieee80211_key_conf *key)
@@ -521,22 +538,9 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
521 crypto.cmd = cmd; 538 crypto.cmd = cmd;
522 crypto.address = address; 539 crypto.address = address;
523 540
524 if (crypto.cipher == CIPHER_TKIP) { 541 if (crypto.cipher == CIPHER_TKIP)
525 if (key->keylen > NL80211_TKIP_DATA_OFFSET_ENCR_KEY) 542 memcpy_tkip(&crypto, &key->key[0], key->keylen);
526 memcpy(&crypto.key, 543 else
527 &key->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
528 sizeof(crypto.key));
529
530 if (key->keylen > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
531 memcpy(&crypto.tx_mic,
532 &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
533 sizeof(crypto.tx_mic));
534
535 if (key->keylen > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
536 memcpy(&crypto.rx_mic,
537 &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
538 sizeof(crypto.rx_mic));
539 } else
540 memcpy(&crypto.key, &key->key[0], key->keylen); 544 memcpy(&crypto.key, &key->key[0], key->keylen);
541 545
542 /* 546 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 01125563aba3..f4a951338f8f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -148,20 +148,105 @@ 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
151static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
152 struct txentry_desc *txdesc)
153{
154 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
155 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
156 struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
157 unsigned long irqflags;
158
159 if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) ||
160 unlikely(!tx_info->control.vif))
161 return;
162
163 /*
164 * Hardware should insert sequence counter.
165 * FIXME: We insert a software sequence counter first for
166 * hardware that doesn't support hardware sequence counting.
167 *
168 * This is wrong because beacons are not getting sequence
169 * numbers assigned properly.
170 *
171 * A secondary problem exists for drivers that cannot toggle
172 * sequence counting per-frame, since those will override the
173 * sequence counter given by mac80211.
174 */
175 spin_lock_irqsave(&intf->seqlock, irqflags);
176
177 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
178 intf->seqno += 0x10;
179 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
180 hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
181
182 spin_unlock_irqrestore(&intf->seqlock, irqflags);
183
184 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
185}
186
187static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry,
188 struct txentry_desc *txdesc,
189 const struct rt2x00_rate *hwrate)
190{
191 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
192 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
193 struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
194 unsigned int data_length;
195 unsigned int duration;
196 unsigned int residual;
197
198 /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */
199 data_length = entry->skb->len + 4;
200 data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb);
201
202 /*
203 * PLCP setup
204 * Length calculation depends on OFDM/CCK rate.
205 */
206 txdesc->signal = hwrate->plcp;
207 txdesc->service = 0x04;
208
209 if (hwrate->flags & DEV_RATE_OFDM) {
210 txdesc->length_high = (data_length >> 6) & 0x3f;
211 txdesc->length_low = data_length & 0x3f;
212 } else {
213 /*
214 * Convert length to microseconds.
215 */
216 residual = GET_DURATION_RES(data_length, hwrate->bitrate);
217 duration = GET_DURATION(data_length, hwrate->bitrate);
218
219 if (residual != 0) {
220 duration++;
221
222 /*
223 * Check if we need to set the Length Extension
224 */
225 if (hwrate->bitrate == 110 && residual <= 30)
226 txdesc->service |= 0x80;
227 }
228
229 txdesc->length_high = (duration >> 8) & 0xff;
230 txdesc->length_low = duration & 0xff;
231
232 /*
233 * When preamble is enabled we should set the
234 * preamble bit for the signal.
235 */
236 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
237 txdesc->signal |= 0x08;
238 }
239}
240
151static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, 241static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
152 struct txentry_desc *txdesc) 242 struct txentry_desc *txdesc)
153{ 243{
154 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 244 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
155 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 245 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
156 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; 246 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
157 struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
158 struct ieee80211_rate *rate = 247 struct ieee80211_rate *rate =
159 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); 248 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
160 const struct rt2x00_rate *hwrate; 249 const struct rt2x00_rate *hwrate;
161 unsigned int data_length;
162 unsigned int duration;
163 unsigned int residual;
164 unsigned long irqflags;
165 250
166 memset(txdesc, 0, sizeof(*txdesc)); 251 memset(txdesc, 0, sizeof(*txdesc));
167 252
@@ -173,27 +258,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
173 txdesc->cw_max = entry->queue->cw_max; 258 txdesc->cw_max = entry->queue->cw_max;
174 txdesc->aifs = entry->queue->aifs; 259 txdesc->aifs = entry->queue->aifs;
175 260
176 /* Data length + CRC */
177 data_length = entry->skb->len + 4;
178
179 /* 261 /*
180 * Check whether this frame is to be acked. 262 * Check whether this frame is to be acked.
181 */ 263 */
182 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) 264 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
183 __set_bit(ENTRY_TXD_ACK, &txdesc->flags); 265 __set_bit(ENTRY_TXD_ACK, &txdesc->flags);
184 266
185 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) &&
186 !entry->skb->do_not_encrypt) {
187 /* Apply crypto specific descriptor information */
188 rt2x00crypto_create_tx_descriptor(entry, txdesc);
189
190 /*
191 * Extend frame length to include all encryption overhead
192 * that will be added by the hardware.
193 */
194 data_length += rt2x00crypto_tx_overhead(tx_info);
195 }
196
197 /* 267 /*
198 * Check if this is a RTS/CTS frame 268 * Check if this is a RTS/CTS frame
199 */ 269 */
@@ -237,86 +307,23 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
237 * Set ifs to IFS_SIFS when the this is not the first fragment, 307 * Set ifs to IFS_SIFS when the this is not the first fragment,
238 * or this fragment came after RTS/CTS. 308 * or this fragment came after RTS/CTS.
239 */ 309 */
240 if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) { 310 if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) &&
241 txdesc->ifs = IFS_SIFS; 311 !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
242 } else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
243 __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); 312 __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags);
244 txdesc->ifs = IFS_BACKOFF; 313 txdesc->ifs = IFS_BACKOFF;
245 } else { 314 } else
246 txdesc->ifs = IFS_SIFS; 315 txdesc->ifs = IFS_SIFS;
247 }
248 316
249 /*
250 * Hardware should insert sequence counter.
251 * FIXME: We insert a software sequence counter first for
252 * hardware that doesn't support hardware sequence counting.
253 *
254 * This is wrong because beacons are not getting sequence
255 * numbers assigned properly.
256 *
257 * A secondary problem exists for drivers that cannot toggle
258 * sequence counting per-frame, since those will override the
259 * sequence counter given by mac80211.
260 */
261 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
262 if (likely(tx_info->control.vif)) {
263 struct rt2x00_intf *intf;
264
265 intf = vif_to_intf(tx_info->control.vif);
266
267 spin_lock_irqsave(&intf->seqlock, irqflags);
268
269 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
270 intf->seqno += 0x10;
271 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
272 hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
273
274 spin_unlock_irqrestore(&intf->seqlock, irqflags);
275
276 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
277 }
278 }
279
280 /*
281 * PLCP setup
282 * Length calculation depends on OFDM/CCK rate.
283 */
284 hwrate = rt2x00_get_rate(rate->hw_value); 317 hwrate = rt2x00_get_rate(rate->hw_value);
285 txdesc->signal = hwrate->plcp; 318 if (hwrate->flags & DEV_RATE_OFDM)
286 txdesc->service = 0x04;
287
288 if (hwrate->flags & DEV_RATE_OFDM) {
289 __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags); 319 __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags);
290 320
291 txdesc->length_high = (data_length >> 6) & 0x3f; 321 /*
292 txdesc->length_low = data_length & 0x3f; 322 * Apply TX descriptor handling by components
293 } else { 323 */
294 /* 324 rt2x00crypto_create_tx_descriptor(entry, txdesc);
295 * Convert length to microseconds. 325 rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
296 */ 326 rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
297 residual = GET_DURATION_RES(data_length, hwrate->bitrate);
298 duration = GET_DURATION(data_length, hwrate->bitrate);
299
300 if (residual != 0) {
301 duration++;
302
303 /*
304 * Check if we need to set the Length Extension
305 */
306 if (hwrate->bitrate == 110 && residual <= 30)
307 txdesc->service |= 0x80;
308 }
309
310 txdesc->length_high = (duration >> 8) & 0xff;
311 txdesc->length_low = duration & 0xff;
312
313 /*
314 * When preamble is enabled we should set the
315 * preamble bit for the signal.
316 */
317 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
318 txdesc->signal |= 0x08;
319 }
320} 327}
321 328
322static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, 329static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,