cfg80211: Fix 160 MHz channels with 80+80 and 160 MHz drivers
The VHT supported channel width field is a two bit integer, not a
bitfield. cfg80211_chandef_usable() was interpreting it incorrectly and
ended up rejecting 160 MHz channel width if the driver indicated support
for both 160 and 80+80 MHz channels.
Cc: stable@vger.kernel.org (3.16+)
Fixes: 3d9d1d6656 ("nl80211/cfg80211: support VHT channel configuration")
       (however, no real drivers had 160 MHz support it until 3.16)
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
	
	
This commit is contained in:
		
					parent
					
						
							
								d025933e29
							
						
					
				
			
			
				commit
				
					
						08f6f14777
					
				
			
		
					 1 changed files with 6 additions and 3 deletions
				
			
		| 
						 | 
					@ -603,7 +603,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ieee80211_sta_ht_cap *ht_cap;
 | 
						struct ieee80211_sta_ht_cap *ht_cap;
 | 
				
			||||||
	struct ieee80211_sta_vht_cap *vht_cap;
 | 
						struct ieee80211_sta_vht_cap *vht_cap;
 | 
				
			||||||
	u32 width, control_freq;
 | 
						u32 width, control_freq, cap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
 | 
						if (WARN_ON(!cfg80211_chandef_valid(chandef)))
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
| 
						 | 
					@ -643,7 +643,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case NL80211_CHAN_WIDTH_80P80:
 | 
						case NL80211_CHAN_WIDTH_80P80:
 | 
				
			||||||
		if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
 | 
							cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
 | 
				
			||||||
 | 
							if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
	case NL80211_CHAN_WIDTH_80:
 | 
						case NL80211_CHAN_WIDTH_80:
 | 
				
			||||||
		if (!vht_cap->vht_supported)
 | 
							if (!vht_cap->vht_supported)
 | 
				
			||||||
| 
						 | 
					@ -654,7 +655,9 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
 | 
				
			||||||
	case NL80211_CHAN_WIDTH_160:
 | 
						case NL80211_CHAN_WIDTH_160:
 | 
				
			||||||
		if (!vht_cap->vht_supported)
 | 
							if (!vht_cap->vht_supported)
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
 | 
							cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
 | 
				
			||||||
 | 
							if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
 | 
				
			||||||
 | 
							    cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
 | 
							prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
 | 
				
			||||||
		width = 160;
 | 
							width = 160;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue