diff options
Diffstat (limited to 'net/wireless/util.c')
| -rw-r--r-- | net/wireless/util.c | 89 | 
1 files changed, 63 insertions, 26 deletions
| diff --git a/net/wireless/util.c b/net/wireless/util.c index f01746894a4e..b4acc805114b 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -272,18 +272,53 @@ bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher)  	return false;  } -int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, -				   struct key_params *params, int key_idx, -				   bool pairwise, const u8 *mac_addr) +static bool +cfg80211_igtk_cipher_supported(struct cfg80211_registered_device *rdev)  { -	int max_key_idx = 5; +	struct wiphy *wiphy = &rdev->wiphy; +	int i; + +	for (i = 0; i < wiphy->n_cipher_suites; i++) { +		switch (wiphy->cipher_suites[i]) { +		case WLAN_CIPHER_SUITE_AES_CMAC: +		case WLAN_CIPHER_SUITE_BIP_CMAC_256: +		case WLAN_CIPHER_SUITE_BIP_GMAC_128: +		case WLAN_CIPHER_SUITE_BIP_GMAC_256: +			return true; +		} +	} + +	return false; +} -	if (wiphy_ext_feature_isset(&rdev->wiphy, -				    NL80211_EXT_FEATURE_BEACON_PROTECTION) || -	    wiphy_ext_feature_isset(&rdev->wiphy, -				    NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT)) +bool cfg80211_valid_key_idx(struct cfg80211_registered_device *rdev, +			    int key_idx, bool pairwise) +{ +	int max_key_idx; + +	if (pairwise) +		max_key_idx = 3; +	else if (wiphy_ext_feature_isset(&rdev->wiphy, +					 NL80211_EXT_FEATURE_BEACON_PROTECTION) || +		 wiphy_ext_feature_isset(&rdev->wiphy, +					 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))  		max_key_idx = 7; +	else if (cfg80211_igtk_cipher_supported(rdev)) +		max_key_idx = 5; +	else +		max_key_idx = 3; +  	if (key_idx < 0 || key_idx > max_key_idx) +		return false; + +	return true; +} + +int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, +				   struct key_params *params, int key_idx, +				   bool pairwise, const u8 *mac_addr) +{ +	if (!cfg80211_valid_key_idx(rdev, key_idx, pairwise))  		return -EINVAL;  	if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) @@ -335,6 +370,7 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,  	case WLAN_CIPHER_SUITE_WEP104:  		if (key_idx > 3)  			return -EINVAL; +		break;  	default:  		break;  	} @@ -550,8 +586,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,  			return -1;  		break;  	case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): -		if (unlikely(iftype != NL80211_IFTYPE_WDS && -			     iftype != NL80211_IFTYPE_MESH_POINT && +		if (unlikely(iftype != NL80211_IFTYPE_MESH_POINT &&  			     iftype != NL80211_IFTYPE_AP_VLAN &&  			     iftype != NL80211_IFTYPE_STATION))  			return -1; @@ -1051,7 +1086,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,  		case NL80211_IFTYPE_P2P_GO:  		case NL80211_IFTYPE_AP:  		case NL80211_IFTYPE_AP_VLAN: -		case NL80211_IFTYPE_WDS:  		case NL80211_IFTYPE_MESH_POINT:  			/* bridging OK */  			break; @@ -1063,6 +1097,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,  			/* not happening */  			break;  		case NL80211_IFTYPE_P2P_DEVICE: +		case NL80211_IFTYPE_WDS:  		case NL80211_IFTYPE_NAN:  			WARN_ON(1);  			break; @@ -1276,20 +1311,22 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)  static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)  { -#define SCALE 2048 -	u16 mcs_divisors[12] = { -		34133, /* 16.666666... */ -		17067, /*  8.333333... */ -		11378, /*  5.555555... */ -		 8533, /*  4.166666... */ -		 5689, /*  2.777777... */ -		 4267, /*  2.083333... */ -		 3923, /*  1.851851... */ -		 3413, /*  1.666666... */ -		 2844, /*  1.388888... */ -		 2560, /*  1.250000... */ -		 2276, /*  1.111111... */ -		 2048, /*  1.000000... */ +#define SCALE 6144 +	u32 mcs_divisors[14] = { +		102399, /* 16.666666... */ +		 51201, /*  8.333333... */ +		 34134, /*  5.555555... */ +		 25599, /*  4.166666... */ +		 17067, /*  2.777777... */ +		 12801, /*  2.083333... */ +		 11769, /*  1.851851... */ +		 10239, /*  1.666666... */ +		  8532, /*  1.388888... */ +		  7680, /*  1.250000... */ +		  6828, /*  1.111111... */ +		  6144, /*  1.000000... */ +		  5690, /*  0.926106... */ +		  5120, /*  0.833333... */  	};  	u32 rates_160M[3] = { 960777777, 907400000, 816666666 };  	u32 rates_969[3] =  { 480388888, 453700000, 408333333 }; @@ -1301,7 +1338,7 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)  	u64 tmp;  	u32 result; -	if (WARN_ON_ONCE(rate->mcs > 11)) +	if (WARN_ON_ONCE(rate->mcs > 13))  		return 0;  	if (WARN_ON_ONCE(rate->he_gi > NL80211_RATE_INFO_HE_GI_3_2)) | 
