mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-29 21:14:28 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			99 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- a/net/mac80211/ieee80211_i.h
 | |
| +++ b/net/mac80211/ieee80211_i.h
 | |
| @@ -726,6 +726,8 @@ struct ieee80211_sub_if_data {
 | |
|  
 | |
|  	/* bitmap of allowed (non-MCS) rate indexes for rate control */
 | |
|  	u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
 | |
| +
 | |
| +	bool rc_has_mcs_mask[IEEE80211_NUM_BANDS];
 | |
|  	u8  rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
 | |
|  
 | |
|  	union {
 | |
| --- a/net/mac80211/cfg.c
 | |
| +++ b/net/mac80211/cfg.c
 | |
| @@ -2112,9 +2112,20 @@ static int ieee80211_set_bitrate_mask(st
 | |
|  	}
 | |
|  
 | |
|  	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
 | |
| +		struct ieee80211_supported_band *sband = wiphy->bands[i];
 | |
| +
 | |
|  		sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
 | |
|  		memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
 | |
|  		       sizeof(mask->control[i].mcs));
 | |
| +
 | |
| +		sdata->rc_has_mcs_mask[i] = false;
 | |
| +		if (!sband)
 | |
| +			continue;
 | |
| +
 | |
| +		if (memcmp(sdata->rc_rateidx_mcs_mask[i],
 | |
| +			   sband->ht_cap.mcs.rx_mask,
 | |
| +			   sizeof(sband->ht_cap.mcs.rx_mask)) != 0)
 | |
| +			sdata->rc_has_mcs_mask[i] = true;
 | |
|  	}
 | |
|  
 | |
|  	return 0;
 | |
| --- a/include/net/mac80211.h
 | |
| +++ b/include/net/mac80211.h
 | |
| @@ -3672,7 +3672,7 @@ void ieee80211_send_bar(struct ieee80211
 | |
|   *	(deprecated; this will be removed once drivers get updated to use
 | |
|   *	rate_idx_mask)
 | |
|   * @rate_idx_mask: user-requested (legacy) rate mask
 | |
| - * @rate_idx_mcs_mask: user-requested MCS rate mask
 | |
| + * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use)
 | |
|   * @bss: whether this frame is sent out in AP or IBSS mode
 | |
|   */
 | |
|  struct ieee80211_tx_rate_control {
 | |
| @@ -3684,7 +3684,7 @@ struct ieee80211_tx_rate_control {
 | |
|  	bool rts, short_preamble;
 | |
|  	u8 max_rate_idx;
 | |
|  	u32 rate_idx_mask;
 | |
| -	u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
 | |
| +	u8 *rate_idx_mcs_mask;
 | |
|  	bool bss;
 | |
|  };
 | |
|  
 | |
| --- a/net/mac80211/tx.c
 | |
| +++ b/net/mac80211/tx.c
 | |
| @@ -642,9 +642,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
 | |
|  		txrc.max_rate_idx = -1;
 | |
|  	else
 | |
|  		txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
 | |
| -	memcpy(txrc.rate_idx_mcs_mask,
 | |
| -	       tx->sdata->rc_rateidx_mcs_mask[tx->channel->band],
 | |
| -	       sizeof(txrc.rate_idx_mcs_mask));
 | |
| +
 | |
| +	if (tx->sdata->rc_has_mcs_mask[tx->channel->band])
 | |
| +		txrc.rate_idx_mcs_mask =
 | |
| +			tx->sdata->rc_rateidx_mcs_mask[tx->channel->band];
 | |
| +
 | |
|  	txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
 | |
|  		    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
 | |
|  		    tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
 | |
| @@ -2480,8 +2482,6 @@ struct sk_buff *ieee80211_beacon_get_tim
 | |
|  		txrc.max_rate_idx = -1;
 | |
|  	else
 | |
|  		txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
 | |
| -	memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
 | |
| -	       sizeof(txrc.rate_idx_mcs_mask));
 | |
|  	txrc.bss = true;
 | |
|  	rate_control_get_rate(sdata, NULL, &txrc);
 | |
|  
 | |
| --- a/net/mac80211/rate.c
 | |
| +++ b/net/mac80211/rate.c
 | |
| @@ -461,9 +461,12 @@ void rate_control_get_rate(struct ieee80
 | |
|  	 * the common case.
 | |
|  	 */
 | |
|  	mask = sdata->rc_rateidx_mask[info->band];
 | |
| -	memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
 | |
| -	       sizeof(mcs_mask));
 | |
| -	if (mask != (1 << txrc->sband->n_bitrates) - 1) {
 | |
| +	if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) {
 | |
| +		if (txrc->rate_idx_mcs_mask)
 | |
| +			memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask));
 | |
| +		else
 | |
| +			memset(mcs_mask, 0xff, sizeof(mcs_mask));
 | |
| +
 | |
|  		if (sta) {
 | |
|  			/* Filter out rates that the STA does not support */
 | |
|  			mask &= sta->sta.supp_rates[info->band];
 |