aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c65
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;