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.c111
1 files changed, 68 insertions, 43 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 6ab99da38db9..5e09d354c5a5 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[] = {
@@ -667,79 +666,109 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
667 WLAN_CIPHER_SUITE_WEP104, 666 WLAN_CIPHER_SUITE_WEP104,
668 WLAN_CIPHER_SUITE_TKIP, 667 WLAN_CIPHER_SUITE_TKIP,
669 WLAN_CIPHER_SUITE_CCMP, 668 WLAN_CIPHER_SUITE_CCMP,
669 WLAN_CIPHER_SUITE_CCMP_256,
670 WLAN_CIPHER_SUITE_GCMP,
671 WLAN_CIPHER_SUITE_GCMP_256,
670 672
671 /* keep last -- depends on hw flags! */ 673 /* keep last -- depends on hw flags! */
672 WLAN_CIPHER_SUITE_AES_CMAC 674 WLAN_CIPHER_SUITE_AES_CMAC,
675 WLAN_CIPHER_SUITE_BIP_CMAC_256,
676 WLAN_CIPHER_SUITE_BIP_GMAC_128,
677 WLAN_CIPHER_SUITE_BIP_GMAC_256,
673 }; 678 };
674 679
675 /* Driver specifies the ciphers, we have nothing to do... */ 680 if (local->hw.flags & IEEE80211_HW_SW_CRYPTO_CONTROL ||
676 if (local->hw.wiphy->cipher_suites && have_wep) 681 local->hw.wiphy->cipher_suites) {
677 return 0; 682 /* If the driver advertises, or doesn't support SW crypto,
683 * we only need to remove WEP if necessary.
684 */
685 if (have_wep)
686 return 0;
687
688 /* well if it has _no_ ciphers ... fine */
689 if (!local->hw.wiphy->n_cipher_suites)
690 return 0;
691
692 /* Driver provides cipher suites, but we need to exclude WEP */
693 suites = kmemdup(local->hw.wiphy->cipher_suites,
694 sizeof(u32) * local->hw.wiphy->n_cipher_suites,
695 GFP_KERNEL);
696 if (!suites)
697 return -ENOMEM;
698
699 for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
700 u32 suite = local->hw.wiphy->cipher_suites[r];
678 701
679 /* Set up cipher suites if driver relies on mac80211 cipher defs */ 702 if (suite == WLAN_CIPHER_SUITE_WEP40 ||
680 if (!local->hw.wiphy->cipher_suites && !cs) { 703 suite == WLAN_CIPHER_SUITE_WEP104)
704 continue;
705 suites[w++] = suite;
706 }
707 } else if (!local->hw.cipher_schemes) {
708 /* If the driver doesn't have cipher schemes, there's nothing
709 * else to do other than assign the (software supported and
710 * perhaps offloaded) cipher suites.
711 */
681 local->hw.wiphy->cipher_suites = cipher_suites; 712 local->hw.wiphy->cipher_suites = cipher_suites;
682 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 713 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
683 714
684 if (!have_mfp) 715 if (!have_mfp)
685 local->hw.wiphy->n_cipher_suites--; 716 local->hw.wiphy->n_cipher_suites -= 4;
686 717
687 if (!have_wep) { 718 if (!have_wep) {
688 local->hw.wiphy->cipher_suites += 2; 719 local->hw.wiphy->cipher_suites += 2;
689 local->hw.wiphy->n_cipher_suites -= 2; 720 local->hw.wiphy->n_cipher_suites -= 2;
690 } 721 }
691 722
723 /* not dynamically allocated, so just return */
692 return 0; 724 return 0;
693 } 725 } else {
726 const struct ieee80211_cipher_scheme *cs;
694 727
695 if (!local->hw.wiphy->cipher_suites) { 728 cs = local->hw.cipher_schemes;
696 /* 729
697 * Driver specifies cipher schemes only 730 /* Driver specifies cipher schemes only (but not cipher suites
698 * We start counting ciphers defined by schemes, TKIP and CCMP 731 * including the schemes)
732 *
733 * We start counting ciphers defined by schemes, TKIP, CCMP,
734 * CCMP-256, GCMP, and GCMP-256
699 */ 735 */
700 n_suites = local->hw.n_cipher_schemes + 2; 736 n_suites = local->hw.n_cipher_schemes + 5;
701 737
702 /* check if we have WEP40 and WEP104 */ 738 /* check if we have WEP40 and WEP104 */
703 if (have_wep) 739 if (have_wep)
704 n_suites += 2; 740 n_suites += 2;
705 741
706 /* check if we have AES_CMAC */ 742 /* check if we have AES_CMAC, BIP-CMAC-256, BIP-GMAC-128,
743 * BIP-GMAC-256
744 */
707 if (have_mfp) 745 if (have_mfp)
708 n_suites++; 746 n_suites += 4;
709 747
710 suites = kmalloc(sizeof(u32) * n_suites, GFP_KERNEL); 748 suites = kmalloc(sizeof(u32) * n_suites, GFP_KERNEL);
711 if (!suites) 749 if (!suites)
712 return -ENOMEM; 750 return -ENOMEM;
713 751
714 suites[w++] = WLAN_CIPHER_SUITE_CCMP; 752 suites[w++] = WLAN_CIPHER_SUITE_CCMP;
753 suites[w++] = WLAN_CIPHER_SUITE_CCMP_256;
715 suites[w++] = WLAN_CIPHER_SUITE_TKIP; 754 suites[w++] = WLAN_CIPHER_SUITE_TKIP;
755 suites[w++] = WLAN_CIPHER_SUITE_GCMP;
756 suites[w++] = WLAN_CIPHER_SUITE_GCMP_256;
716 757
717 if (have_wep) { 758 if (have_wep) {
718 suites[w++] = WLAN_CIPHER_SUITE_WEP40; 759 suites[w++] = WLAN_CIPHER_SUITE_WEP40;
719 suites[w++] = WLAN_CIPHER_SUITE_WEP104; 760 suites[w++] = WLAN_CIPHER_SUITE_WEP104;
720 } 761 }
721 762
722 if (have_mfp) 763 if (have_mfp) {
723 suites[w++] = WLAN_CIPHER_SUITE_AES_CMAC; 764 suites[w++] = WLAN_CIPHER_SUITE_AES_CMAC;
765 suites[w++] = WLAN_CIPHER_SUITE_BIP_CMAC_256;
766 suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_128;
767 suites[w++] = WLAN_CIPHER_SUITE_BIP_GMAC_256;
768 }
724 769
725 for (r = 0; r < local->hw.n_cipher_schemes; r++) 770 for (r = 0; r < local->hw.n_cipher_schemes; r++)
726 suites[w++] = cs[r].cipher; 771 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 } 772 }
744 773
745 local->hw.wiphy->cipher_suites = suites; 774 local->hw.wiphy->cipher_suites = suites;
@@ -916,10 +945,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
916 } 945 }
917 } 946 }
918 947
919 WARN((local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)
920 && (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK),
921 "U-APSD not supported with HW_PS_NULLFUNC_STACK\n");
922
923 /* 948 /*
924 * Calculate scan IE length -- we need this to alloc 949 * Calculate scan IE length -- we need this to alloc
925 * memory and to subtract from the driver limit. It 950 * memory and to subtract from the driver limit. It
@@ -1045,10 +1070,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1045 ieee80211_max_network_latency; 1070 ieee80211_max_network_latency;
1046 result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, 1071 result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
1047 &local->network_latency_notifier); 1072 &local->network_latency_notifier);
1048 if (result) { 1073 if (result)
1049 rtnl_lock();
1050 goto fail_pm_qos; 1074 goto fail_pm_qos;
1051 }
1052 1075
1053#ifdef CONFIG_INET 1076#ifdef CONFIG_INET
1054 local->ifa_notifier.notifier_call = ieee80211_ifa_changed; 1077 local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
@@ -1076,15 +1099,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1076 fail_ifa: 1099 fail_ifa:
1077 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, 1100 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
1078 &local->network_latency_notifier); 1101 &local->network_latency_notifier);
1079 rtnl_lock();
1080#endif 1102#endif
1081 fail_pm_qos: 1103 fail_pm_qos:
1082 ieee80211_led_exit(local); 1104 rtnl_lock();
1105 rate_control_deinitialize(local);
1083 ieee80211_remove_interfaces(local); 1106 ieee80211_remove_interfaces(local);
1084 fail_rate: 1107 fail_rate:
1085 rtnl_unlock(); 1108 rtnl_unlock();
1109 ieee80211_led_exit(local);
1086 ieee80211_wep_free(local); 1110 ieee80211_wep_free(local);
1087 sta_info_stop(local);
1088 destroy_workqueue(local->workqueue); 1111 destroy_workqueue(local->workqueue);
1089 fail_workqueue: 1112 fail_workqueue:
1090 wiphy_unregister(local->hw.wiphy); 1113 wiphy_unregister(local->hw.wiphy);
@@ -1180,6 +1203,8 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
1180 1203
1181 kfree(rcu_access_pointer(local->tx_latency)); 1204 kfree(rcu_access_pointer(local->tx_latency));
1182 1205
1206 sta_info_stop(local);
1207
1183 wiphy_free(local->hw.wiphy); 1208 wiphy_free(local->hw.wiphy);
1184} 1209}
1185EXPORT_SYMBOL(ieee80211_free_hw); 1210EXPORT_SYMBOL(ieee80211_free_hw);