diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 65 |
1 files changed, 39 insertions, 26 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 46264cb6604b..ea6b82ac4f0b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -658,7 +658,6 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local) | |||
658 | bool have_wep = !(IS_ERR(local->wep_tx_tfm) || | 658 | bool have_wep = !(IS_ERR(local->wep_tx_tfm) || |
659 | IS_ERR(local->wep_rx_tfm)); | 659 | IS_ERR(local->wep_rx_tfm)); |
660 | bool have_mfp = local->hw.flags & IEEE80211_HW_MFP_CAPABLE; | 660 | bool have_mfp = local->hw.flags & IEEE80211_HW_MFP_CAPABLE; |
661 | const struct ieee80211_cipher_scheme *cs = local->hw.cipher_schemes; | ||
662 | int n_suites = 0, r = 0, w = 0; | 661 | int n_suites = 0, r = 0, w = 0; |
663 | u32 *suites; | 662 | u32 *suites; |
664 | static const u32 cipher_suites[] = { | 663 | static const u32 cipher_suites[] = { |
@@ -672,12 +671,38 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local) | |||
672 | WLAN_CIPHER_SUITE_AES_CMAC | 671 | WLAN_CIPHER_SUITE_AES_CMAC |
673 | }; | 672 | }; |
674 | 673 | ||
675 | /* Driver specifies the ciphers, we have nothing to do... */ | 674 | if (local->hw.flags & IEEE80211_HW_SW_CRYPTO_CONTROL || |
676 | if (local->hw.wiphy->cipher_suites && have_wep) | 675 | local->hw.wiphy->cipher_suites) { |
677 | return 0; | 676 | /* If the driver advertises, or doesn't support SW crypto, |
677 | * we only need to remove WEP if necessary. | ||
678 | */ | ||
679 | if (have_wep) | ||
680 | return 0; | ||
681 | |||
682 | /* well if it has _no_ ciphers ... fine */ | ||
683 | if (!local->hw.wiphy->n_cipher_suites) | ||
684 | return 0; | ||
685 | |||
686 | /* Driver provides cipher suites, but we need to exclude WEP */ | ||
687 | suites = kmemdup(local->hw.wiphy->cipher_suites, | ||
688 | sizeof(u32) * local->hw.wiphy->n_cipher_suites, | ||
689 | GFP_KERNEL); | ||
690 | if (!suites) | ||
691 | return -ENOMEM; | ||
678 | 692 | ||
679 | /* Set up cipher suites if driver relies on mac80211 cipher defs */ | 693 | for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { |
680 | if (!local->hw.wiphy->cipher_suites && !cs) { | 694 | u32 suite = local->hw.wiphy->cipher_suites[r]; |
695 | |||
696 | if (suite == WLAN_CIPHER_SUITE_WEP40 || | ||
697 | suite == WLAN_CIPHER_SUITE_WEP104) | ||
698 | continue; | ||
699 | suites[w++] = suite; | ||
700 | } | ||
701 | } else if (!local->hw.cipher_schemes) { | ||
702 | /* If the driver doesn't have cipher schemes, there's nothing | ||
703 | * else to do other than assign the (software supported and | ||
704 | * perhaps offloaded) cipher suites. | ||
705 | */ | ||
681 | local->hw.wiphy->cipher_suites = cipher_suites; | 706 | local->hw.wiphy->cipher_suites = cipher_suites; |
682 | local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); | 707 | local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); |
683 | 708 | ||
@@ -689,12 +714,16 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local) | |||
689 | local->hw.wiphy->n_cipher_suites -= 2; | 714 | local->hw.wiphy->n_cipher_suites -= 2; |
690 | } | 715 | } |
691 | 716 | ||
717 | /* not dynamically allocated, so just return */ | ||
692 | return 0; | 718 | return 0; |
693 | } | 719 | } else { |
720 | const struct ieee80211_cipher_scheme *cs; | ||
694 | 721 | ||
695 | if (!local->hw.wiphy->cipher_suites) { | 722 | cs = local->hw.cipher_schemes; |
696 | /* | 723 | |
697 | * Driver specifies cipher schemes only | 724 | /* Driver specifies cipher schemes only (but not cipher suites |
725 | * including the schemes) | ||
726 | * | ||
698 | * We start counting ciphers defined by schemes, TKIP and CCMP | 727 | * We start counting ciphers defined by schemes, TKIP and CCMP |
699 | */ | 728 | */ |
700 | n_suites = local->hw.n_cipher_schemes + 2; | 729 | n_suites = local->hw.n_cipher_schemes + 2; |
@@ -724,22 +753,6 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local) | |||
724 | 753 | ||
725 | for (r = 0; r < local->hw.n_cipher_schemes; r++) | 754 | for (r = 0; r < local->hw.n_cipher_schemes; r++) |
726 | suites[w++] = cs[r].cipher; | 755 | suites[w++] = cs[r].cipher; |
727 | } else { | ||
728 | /* Driver provides cipher suites, but we need to exclude WEP */ | ||
729 | suites = kmemdup(local->hw.wiphy->cipher_suites, | ||
730 | sizeof(u32) * local->hw.wiphy->n_cipher_suites, | ||
731 | GFP_KERNEL); | ||
732 | if (!suites) | ||
733 | return -ENOMEM; | ||
734 | |||
735 | for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { | ||
736 | u32 suite = local->hw.wiphy->cipher_suites[r]; | ||
737 | |||
738 | if (suite == WLAN_CIPHER_SUITE_WEP40 || | ||
739 | suite == WLAN_CIPHER_SUITE_WEP104) | ||
740 | continue; | ||
741 | suites[w++] = suite; | ||
742 | } | ||
743 | } | 756 | } |
744 | 757 | ||
745 | local->hw.wiphy->cipher_suites = suites; | 758 | local->hw.wiphy->cipher_suites = suites; |