diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-12-02 12:20:42 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-12-05 09:35:51 -0500 |
commit | dddfb478b26e29a2b47f655ec219e743b8111015 (patch) | |
tree | 040ba518fcddc9b2e89a8bbf9d3a2e2d24f14b0e | |
parent | 0b927a079106e5f66c736e297370d3feb008e28e (diff) |
rt2x00: Implement HW encryption (rt2500usb)
rt2500usb supports hardware encryption.
rt2500usb supports up to 4 shared and pairwise keys.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/rt2x00/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 132 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00crypto.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00lib.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 8 |
8 files changed, 156 insertions, 9 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 95511ac22470..178b313293b4 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -57,6 +57,7 @@ config RT2500USB | |||
57 | tristate "Ralink rt2500 (USB) support" | 57 | tristate "Ralink rt2500 (USB) support" |
58 | depends on USB | 58 | depends on USB |
59 | select RT2X00_LIB_USB | 59 | select RT2X00_LIB_USB |
60 | select RT2X00_LIB_CRYPTO | ||
60 | ---help--- | 61 | ---help--- |
61 | This adds support for rt2500 wireless chipset family. | 62 | This adds support for rt2500 wireless chipset family. |
62 | Supported chips: RT2571 & RT2572. | 63 | Supported chips: RT2571 & RT2572. |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 0447e93306ad..90bf0b96caa3 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -36,6 +36,13 @@ | |||
36 | #include "rt2500usb.h" | 36 | #include "rt2500usb.h" |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * Allow hardware encryption to be disabled. | ||
40 | */ | ||
41 | static int modparam_nohwcrypt = 1; | ||
42 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | ||
43 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | ||
44 | |||
45 | /* | ||
39 | * Register access. | 46 | * Register access. |
40 | * All access to the CSR registers will go through the methods | 47 | * All access to the CSR registers will go through the methods |
41 | * rt2500usb_register_read and rt2500usb_register_write. | 48 | * rt2500usb_register_read and rt2500usb_register_write. |
@@ -323,6 +330,82 @@ static void rt2500usb_init_led(struct rt2x00_dev *rt2x00dev, | |||
323 | /* | 330 | /* |
324 | * Configuration handlers. | 331 | * Configuration handlers. |
325 | */ | 332 | */ |
333 | |||
334 | /* | ||
335 | * rt2500usb does not differentiate between shared and pairwise | ||
336 | * keys, so we should use the same function for both key types. | ||
337 | */ | ||
338 | static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, | ||
339 | struct rt2x00lib_crypto *crypto, | ||
340 | struct ieee80211_key_conf *key) | ||
341 | { | ||
342 | int timeout; | ||
343 | u32 mask; | ||
344 | u16 reg; | ||
345 | |||
346 | if (crypto->cmd == SET_KEY) { | ||
347 | /* | ||
348 | * Pairwise key will always be entry 0, but this | ||
349 | * could collide with a shared key on the same | ||
350 | * position... | ||
351 | */ | ||
352 | mask = TXRX_CSR0_KEY_ID.bit_mask; | ||
353 | |||
354 | rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
355 | reg &= mask; | ||
356 | |||
357 | if (reg && reg == mask) | ||
358 | return -ENOSPC; | ||
359 | |||
360 | reg = rt2x00_get_field16(reg, TXRX_CSR0_KEY_ID); | ||
361 | |||
362 | key->hw_key_idx += reg ? ffz(reg) : 0; | ||
363 | |||
364 | /* | ||
365 | * The encryption key doesn't fit within the CSR cache, | ||
366 | * this means we should allocate it seperately and use | ||
367 | * rt2x00usb_vendor_request() to send the key to the hardware. | ||
368 | */ | ||
369 | reg = KEY_ENTRY(key->hw_key_idx); | ||
370 | timeout = REGISTER_TIMEOUT32(sizeof(crypto->key)); | ||
371 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | ||
372 | USB_VENDOR_REQUEST_OUT, reg, | ||
373 | crypto->key, | ||
374 | sizeof(crypto->key), | ||
375 | timeout); | ||
376 | |||
377 | /* | ||
378 | * The driver does not support the IV/EIV generation | ||
379 | * in hardware. However it doesn't support the IV/EIV | ||
380 | * inside the ieee80211 frame either, but requires it | ||
381 | * to be provided seperately for the descriptor. | ||
382 | * rt2x00lib will cut the IV/EIV data out of all frames | ||
383 | * given to us by mac80211, but we must tell mac80211 | ||
384 | * to generate the IV/EIV data. | ||
385 | */ | ||
386 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
387 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * TXRX_CSR0_KEY_ID contains only single-bit fields to indicate | ||
392 | * a particular key is valid. | ||
393 | */ | ||
394 | rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
395 | rt2x00_set_field16(®, TXRX_CSR0_ALGORITHM, crypto->cipher); | ||
396 | rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); | ||
397 | |||
398 | mask = rt2x00_get_field16(reg, TXRX_CSR0_KEY_ID); | ||
399 | if (crypto->cmd == SET_KEY) | ||
400 | mask |= 1 << key->hw_key_idx; | ||
401 | else if (crypto->cmd == DISABLE_KEY) | ||
402 | mask &= ~(1 << key->hw_key_idx); | ||
403 | rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, mask); | ||
404 | rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
326 | static void rt2500usb_config_filter(struct rt2x00_dev *rt2x00dev, | 409 | static void rt2500usb_config_filter(struct rt2x00_dev *rt2x00dev, |
327 | const unsigned int filter_flags) | 410 | const unsigned int filter_flags) |
328 | { | 411 | { |
@@ -844,7 +927,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
844 | 927 | ||
845 | rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 928 | rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
846 | rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); | 929 | rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); |
847 | rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, 0xff); | 930 | rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, 0); |
848 | rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 931 | rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
849 | 932 | ||
850 | rt2500usb_register_read(rt2x00dev, MAC_CSR18, ®); | 933 | rt2500usb_register_read(rt2x00dev, MAC_CSR18, ®); |
@@ -1066,7 +1149,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1066 | * Start writing the descriptor words. | 1149 | * Start writing the descriptor words. |
1067 | */ | 1150 | */ |
1068 | rt2x00_desc_read(txd, 1, &word); | 1151 | rt2x00_desc_read(txd, 1, &word); |
1069 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1152 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); |
1070 | rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); | 1153 | rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); |
1071 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); | 1154 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1072 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1155 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
@@ -1079,6 +1162,11 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1079 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); | 1162 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1080 | rt2x00_desc_write(txd, 2, word); | 1163 | rt2x00_desc_write(txd, 2, word); |
1081 | 1164 | ||
1165 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { | ||
1166 | _rt2x00_desc_write(txd, 3, skbdesc->iv[0]); | ||
1167 | _rt2x00_desc_write(txd, 4, skbdesc->iv[1]); | ||
1168 | } | ||
1169 | |||
1082 | rt2x00_desc_read(txd, 0, &word); | 1170 | rt2x00_desc_read(txd, 0, &word); |
1083 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit); | 1171 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit); |
1084 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1172 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
@@ -1093,7 +1181,8 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1093 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); | 1181 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); |
1094 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1182 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1095 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); | 1183 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); |
1096 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); | 1184 | rt2x00_set_field32(&word, TXD_W0_CIPHER, txdesc->cipher); |
1185 | rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); | ||
1097 | rt2x00_desc_write(txd, 0, word); | 1186 | rt2x00_desc_write(txd, 0, word); |
1098 | } | 1187 | } |
1099 | 1188 | ||
@@ -1204,6 +1293,7 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1204 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, | 1293 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, |
1205 | struct rxdone_entry_desc *rxdesc) | 1294 | struct rxdone_entry_desc *rxdesc) |
1206 | { | 1295 | { |
1296 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1207 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 1297 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
1208 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1298 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1209 | __le32 *rxd = | 1299 | __le32 *rxd = |
@@ -1231,6 +1321,31 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1231 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1321 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1232 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1322 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1233 | 1323 | ||
1324 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | ||
1325 | rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER); | ||
1326 | if (rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) | ||
1327 | rxdesc->cipher_status = RX_CRYPTO_FAIL_KEY; | ||
1328 | } | ||
1329 | |||
1330 | if (rxdesc->cipher != CIPHER_NONE) { | ||
1331 | _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]); | ||
1332 | _rt2x00_desc_read(rxd, 3, &rxdesc->iv[1]); | ||
1333 | /* ICV is located at the end of frame */ | ||
1334 | |||
1335 | /* | ||
1336 | * Hardware has stripped IV/EIV data from 802.11 frame during | ||
1337 | * decryption. It has provided the data seperately but rt2x00lib | ||
1338 | * should decide if it should be reinserted. | ||
1339 | */ | ||
1340 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; | ||
1341 | if (rxdesc->cipher != CIPHER_TKIP) | ||
1342 | rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; | ||
1343 | if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) | ||
1344 | rxdesc->flags |= RX_FLAG_DECRYPTED; | ||
1345 | else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) | ||
1346 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; | ||
1347 | } | ||
1348 | |||
1234 | /* | 1349 | /* |
1235 | * Obtain the status about this packet. | 1350 | * Obtain the status about this packet. |
1236 | * When frame was received with an OFDM bitrate, | 1351 | * When frame was received with an OFDM bitrate, |
@@ -1238,8 +1353,8 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1238 | * a CCK bitrate the signal is the rate in 100kbit/s. | 1353 | * a CCK bitrate the signal is the rate in 100kbit/s. |
1239 | */ | 1354 | */ |
1240 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1355 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1241 | rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - | 1356 | rxdesc->rssi = |
1242 | entry->queue->rt2x00dev->rssi_offset; | 1357 | rt2x00_get_field32(word1, RXD_W1_RSSI) - rt2x00dev->rssi_offset; |
1243 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1358 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1244 | 1359 | ||
1245 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | 1360 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) |
@@ -1727,6 +1842,10 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1727 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1842 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1728 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | 1843 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); |
1729 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); | 1844 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); |
1845 | if (!modparam_nohwcrypt) { | ||
1846 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | ||
1847 | __set_bit(CONFIG_CRYPTO_COPY_IV, &rt2x00dev->flags); | ||
1848 | } | ||
1730 | __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); | 1849 | __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); |
1731 | 1850 | ||
1732 | /* | 1851 | /* |
@@ -1746,6 +1865,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { | |||
1746 | .config = rt2x00mac_config, | 1865 | .config = rt2x00mac_config, |
1747 | .config_interface = rt2x00mac_config_interface, | 1866 | .config_interface = rt2x00mac_config_interface, |
1748 | .configure_filter = rt2x00mac_configure_filter, | 1867 | .configure_filter = rt2x00mac_configure_filter, |
1868 | .set_key = rt2x00mac_set_key, | ||
1749 | .get_stats = rt2x00mac_get_stats, | 1869 | .get_stats = rt2x00mac_get_stats, |
1750 | .bss_info_changed = rt2x00mac_bss_info_changed, | 1870 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1751 | .conf_tx = rt2x00mac_conf_tx, | 1871 | .conf_tx = rt2x00mac_conf_tx, |
@@ -1767,6 +1887,8 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1767 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1887 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1768 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1888 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1769 | .fill_rxdone = rt2500usb_fill_rxdone, | 1889 | .fill_rxdone = rt2500usb_fill_rxdone, |
1890 | .config_shared_key = rt2500usb_config_key, | ||
1891 | .config_pairwise_key = rt2500usb_config_key, | ||
1770 | .config_filter = rt2500usb_config_filter, | 1892 | .config_filter = rt2500usb_config_filter, |
1771 | .config_intf = rt2500usb_config_intf, | 1893 | .config_intf = rt2500usb_config_intf, |
1772 | .config_erp = rt2500usb_config_erp, | 1894 | .config_erp = rt2500usb_config_erp, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index dbb5d689e23d..4347dfdabcd4 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -447,6 +447,9 @@ | |||
447 | #define SEC_CSR30 0x04bc | 447 | #define SEC_CSR30 0x04bc |
448 | #define SEC_CSR31 0x04be | 448 | #define SEC_CSR31 0x04be |
449 | 449 | ||
450 | #define KEY_ENTRY(__idx) \ | ||
451 | ( SEC_CSR0 + ((__idx) * 16) ) | ||
452 | |||
450 | /* | 453 | /* |
451 | * PHY control registers. | 454 | * PHY control registers. |
452 | */ | 455 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index e7ed56dcf684..03d34bb66189 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -653,6 +653,7 @@ enum rt2x00_flags { | |||
653 | CONFIG_EXTERNAL_LNA_BG, | 653 | CONFIG_EXTERNAL_LNA_BG, |
654 | CONFIG_DOUBLE_ANTENNA, | 654 | CONFIG_DOUBLE_ANTENNA, |
655 | CONFIG_DISABLE_LINK_TUNING, | 655 | CONFIG_DISABLE_LINK_TUNING, |
656 | CONFIG_CRYPTO_COPY_IV, | ||
656 | }; | 657 | }; |
657 | 658 | ||
658 | /* | 659 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index e0fc7c193040..c6709b392165 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c | |||
@@ -69,6 +69,18 @@ unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) | |||
69 | return overhead; | 69 | return overhead; |
70 | } | 70 | } |
71 | 71 | ||
72 | void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len) | ||
73 | { | ||
74 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
75 | unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb); | ||
76 | |||
77 | if (unlikely(!iv_len)) | ||
78 | return; | ||
79 | |||
80 | /* Copy IV/EIV data */ | ||
81 | memcpy(skbdesc->iv, skb->data + header_length, iv_len); | ||
82 | } | ||
83 | |||
72 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len) | 84 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len) |
73 | { | 85 | { |
74 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 86 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 93997333d46d..1e1893772b6c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -219,6 +219,7 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | |||
219 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 219 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
220 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); | 220 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); |
221 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info); | 221 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info); |
222 | void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len); | ||
222 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); | 223 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); |
223 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); | 224 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); |
224 | void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, | 225 | void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, |
@@ -235,6 +236,11 @@ static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx | |||
235 | return 0; | 236 | return 0; |
236 | } | 237 | } |
237 | 238 | ||
239 | static inline void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, | ||
240 | unsigned int iv_len) | ||
241 | { | ||
242 | } | ||
243 | |||
238 | static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, | 244 | static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, |
239 | unsigned int iv_len) | 245 | unsigned int iv_len) |
240 | { | 246 | { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 4c0395729066..fa91ca5cd0e2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -79,10 +79,8 @@ 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 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | ||
83 | if (!frag_skb->do_not_encrypt) | 82 | if (!frag_skb->do_not_encrypt) |
84 | data_length += rt2x00crypto_tx_overhead(tx_info); | 83 | data_length += rt2x00crypto_tx_overhead(tx_info); |
85 | #endif /* CONFIG_RT2X00_LIB_CRYPTO */ | ||
86 | 84 | ||
87 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | 85 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
88 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, | 86 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 7f908a17e368..e4a1dbeb18fd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -420,8 +420,12 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
420 | * the frame so we can provide it to the driver seperately. | 420 | * the frame so we can provide it to the driver seperately. |
421 | */ | 421 | */ |
422 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && | 422 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && |
423 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) | 423 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { |
424 | rt2x00crypto_tx_remove_iv(skb, iv_len); | 424 | if (test_bit(CONFIG_CRYPTO_COPY_IV, &queue->rt2x00dev->flags)) |
425 | rt2x00crypto_tx_copy_iv(skb, iv_len); | ||
426 | else | ||
427 | rt2x00crypto_tx_remove_iv(skb, iv_len); | ||
428 | } | ||
425 | 429 | ||
426 | /* | 430 | /* |
427 | * It could be possible that the queue was corrupted and this | 431 | * It could be possible that the queue was corrupted and this |