diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 71 |
1 files changed, 36 insertions, 35 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 38edee5fe168..71de8a7144f9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -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, |
@@ -226,6 +225,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
226 | break; | 225 | break; |
227 | case NL80211_IFTYPE_STATION: | 226 | case NL80211_IFTYPE_STATION: |
228 | case NL80211_IFTYPE_ADHOC: | 227 | case NL80211_IFTYPE_ADHOC: |
228 | case NL80211_IFTYPE_MESH_POINT: | ||
229 | case NL80211_IFTYPE_WDS: | ||
229 | /* | 230 | /* |
230 | * We don't support mixed combinations of | 231 | * We don't support mixed combinations of |
231 | * sta and ap interfaces. | 232 | * sta and ap interfaces. |
@@ -482,16 +483,36 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
482 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | 483 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); |
483 | 484 | ||
484 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 485 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
486 | static 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 | |||
485 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 504 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
486 | const u8 *local_address, const u8 *address, | 505 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
487 | struct ieee80211_key_conf *key) | 506 | struct ieee80211_key_conf *key) |
488 | { | 507 | { |
489 | struct rt2x00_dev *rt2x00dev = hw->priv; | 508 | struct rt2x00_dev *rt2x00dev = hw->priv; |
490 | struct ieee80211_sta *sta; | 509 | struct rt2x00_intf *intf = vif_to_intf(vif); |
491 | int (*set_key) (struct rt2x00_dev *rt2x00dev, | 510 | int (*set_key) (struct rt2x00_dev *rt2x00dev, |
492 | struct rt2x00lib_crypto *crypto, | 511 | struct rt2x00lib_crypto *crypto, |
493 | struct ieee80211_key_conf *key); | 512 | struct ieee80211_key_conf *key); |
494 | struct rt2x00lib_crypto crypto; | 513 | struct rt2x00lib_crypto crypto; |
514 | static const u8 bcast_addr[ETH_ALEN] = | ||
515 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; | ||
495 | 516 | ||
496 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | 517 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
497 | return 0; | 518 | return 0; |
@@ -509,45 +530,25 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
509 | if (rt2x00dev->intf_sta_count) | 530 | if (rt2x00dev->intf_sta_count) |
510 | crypto.bssidx = 0; | 531 | crypto.bssidx = 0; |
511 | else | 532 | else |
512 | crypto.bssidx = | 533 | crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1); |
513 | local_address[5] & (rt2x00dev->ops->max_ap_intf - 1); | ||
514 | 534 | ||
515 | crypto.cipher = rt2x00crypto_key_to_cipher(key); | 535 | crypto.cipher = rt2x00crypto_key_to_cipher(key); |
516 | if (crypto.cipher == CIPHER_NONE) | 536 | if (crypto.cipher == CIPHER_NONE) |
517 | return -EOPNOTSUPP; | 537 | return -EOPNOTSUPP; |
518 | 538 | ||
519 | crypto.cmd = cmd; | 539 | crypto.cmd = cmd; |
520 | crypto.address = address; | ||
521 | |||
522 | if (crypto.cipher == CIPHER_TKIP) { | ||
523 | if (key->keylen > NL80211_TKIP_DATA_OFFSET_ENCR_KEY) | ||
524 | memcpy(&crypto.key, | ||
525 | &key->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY], | ||
526 | sizeof(crypto.key)); | ||
527 | |||
528 | if (key->keylen > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) | ||
529 | memcpy(&crypto.tx_mic, | ||
530 | &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], | ||
531 | sizeof(crypto.tx_mic)); | ||
532 | |||
533 | if (key->keylen > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY) | ||
534 | memcpy(&crypto.rx_mic, | ||
535 | &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], | ||
536 | sizeof(crypto.rx_mic)); | ||
537 | } else | ||
538 | memcpy(&crypto.key, &key->key[0], key->keylen); | ||
539 | 540 | ||
540 | /* | 541 | if (sta) { |
541 | * Discover the Association ID from mac80211. | 542 | /* some drivers need the AID */ |
542 | * Some drivers need this information when updating the | ||
543 | * hardware key (either adding or removing). | ||
544 | */ | ||
545 | rcu_read_lock(); | ||
546 | sta = ieee80211_find_sta(hw, address); | ||
547 | if (sta) | ||
548 | crypto.aid = sta->aid; | 543 | crypto.aid = sta->aid; |
549 | rcu_read_unlock(); | 544 | crypto.address = sta->addr; |
545 | } else | ||
546 | crypto.address = bcast_addr; | ||
550 | 547 | ||
548 | if (crypto.cipher == CIPHER_TKIP) | ||
549 | memcpy_tkip(&crypto, &key->key[0], key->keylen); | ||
550 | else | ||
551 | memcpy(&crypto.key, &key->key[0], key->keylen); | ||
551 | /* | 552 | /* |
552 | * Each BSS has a maximum of 4 shared keys. | 553 | * Each BSS has a maximum of 4 shared keys. |
553 | * Shared key index values: | 554 | * Shared key index values: |