aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-27 07:26:52 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-27 13:27:07 -0400
commit3ffc2a905b1faae4c0fe39d66f0752c3a4cbb3c7 (patch)
treed50902e1e171877e4fb034e36c837f16984ab9b4 /net/mac80211/main.c
parent7d64b7cc1fc33bab24567903a93f699d11649c0b (diff)
mac80211: allow vendor specific cipher suites
Allow drivers to specify their own set of cipher suites to advertise vendor-specific ciphers. The driver is then required to implement hardware crypto offload for it. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 80db5ea02052..15f0e960fde8 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -662,13 +662,40 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
662 if (local->hw.wiphy->max_scan_ie_len) 662 if (local->hw.wiphy->max_scan_ie_len)
663 local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; 663 local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;
664 664
665 local->hw.wiphy->cipher_suites = cipher_suites; 665 /* Set up cipher suites unless driver already did */
666 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 666 if (!local->hw.wiphy->cipher_suites) {
667 if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) 667 local->hw.wiphy->cipher_suites = cipher_suites;
668 local->hw.wiphy->n_cipher_suites--; 668 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
669 if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
670 local->hw.wiphy->n_cipher_suites--;
671 }
669 if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { 672 if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) {
670 local->hw.wiphy->cipher_suites += 2; 673 if (local->hw.wiphy->cipher_suites == cipher_suites) {
671 local->hw.wiphy->n_cipher_suites -= 2; 674 local->hw.wiphy->cipher_suites += 2;
675 local->hw.wiphy->n_cipher_suites -= 2;
676 } else {
677 u32 *suites;
678 int r, w = 0;
679
680 /* Filter out WEP */
681
682 suites = kmemdup(
683 local->hw.wiphy->cipher_suites,
684 sizeof(u32) * local->hw.wiphy->n_cipher_suites,
685 GFP_KERNEL);
686 if (!suites)
687 return -ENOMEM;
688 for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
689 u32 suite = local->hw.wiphy->cipher_suites[r];
690 if (suite == WLAN_CIPHER_SUITE_WEP40 ||
691 suite == WLAN_CIPHER_SUITE_WEP104)
692 continue;
693 suites[w++] = suite;
694 }
695 local->hw.wiphy->cipher_suites = suites;
696 local->hw.wiphy->n_cipher_suites = w;
697 local->wiphy_ciphers_allocated = true;
698 }
672 } 699 }
673 700
674 result = wiphy_register(local->hw.wiphy); 701 result = wiphy_register(local->hw.wiphy);
@@ -783,6 +810,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
783 fail_workqueue: 810 fail_workqueue:
784 wiphy_unregister(local->hw.wiphy); 811 wiphy_unregister(local->hw.wiphy);
785 fail_wiphy_register: 812 fail_wiphy_register:
813 if (local->wiphy_ciphers_allocated)
814 kfree(local->hw.wiphy->cipher_suites);
786 kfree(local->int_scan_req); 815 kfree(local->int_scan_req);
787 return result; 816 return result;
788} 817}
@@ -840,6 +869,9 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
840 mutex_destroy(&local->iflist_mtx); 869 mutex_destroy(&local->iflist_mtx);
841 mutex_destroy(&local->mtx); 870 mutex_destroy(&local->mtx);
842 871
872 if (local->wiphy_ciphers_allocated)
873 kfree(local->hw.wiphy->cipher_suites);
874
843 wiphy_free(local->hw.wiphy); 875 wiphy_free(local->hw.wiphy);
844} 876}
845EXPORT_SYMBOL(ieee80211_free_hw); 877EXPORT_SYMBOL(ieee80211_free_hw);