aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-04-16 07:38:42 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-04-16 17:42:29 -0400
commit2ffbe6d333664a089f17b13aa79eefe38f794bb7 (patch)
tree29927d762aff0f9d8a8eea57784fb0067fb58ca7 /net
parentdad6330d034a24a22008ee28b8ec447cbb0961c9 (diff)
mac80211: fix and optimize MCS mask handling
Currently the code always copies the configured MCS mask (even if it is set to default), but only uses it if legacy rates were also masked out. Fix this by adding a flag that tracks whether the configured MCS mask is set to default or not. Optimize the code further by storing a pointer to the configured rate mask in txrc instead of using memcpy. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c13
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/rate.c9
-rw-r--r--net/mac80211/tx.c10
4 files changed, 26 insertions, 8 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index fdd95bd751a1..72ab1c0e3ca7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2417,9 +2417,22 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
2417 } 2417 }
2418 2418
2419 for (i = 0; i < IEEE80211_NUM_BANDS; i++) { 2419 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
2420 struct ieee80211_supported_band *sband = wiphy->bands[i];
2421 int j;
2422
2420 sdata->rc_rateidx_mask[i] = mask->control[i].legacy; 2423 sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
2421 memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs, 2424 memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
2422 sizeof(mask->control[i].mcs)); 2425 sizeof(mask->control[i].mcs));
2426
2427 sdata->rc_has_mcs_mask[i] = false;
2428 if (!sband)
2429 continue;
2430
2431 for (j = 0; j < IEEE80211_HT_MCS_MASK_LEN; j++)
2432 if (~sdata->rc_rateidx_mcs_mask[i][j]) {
2433 sdata->rc_has_mcs_mask[i] = true;
2434 break;
2435 }
2423 } 2436 }
2424 2437
2425 return 0; 2438 return 0;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f4a65a340a52..21c1720eee00 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -739,6 +739,8 @@ struct ieee80211_sub_if_data {
739 739
740 /* bitmap of allowed (non-MCS) rate indexes for rate control */ 740 /* bitmap of allowed (non-MCS) rate indexes for rate control */
741 u32 rc_rateidx_mask[IEEE80211_NUM_BANDS]; 741 u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
742
743 bool rc_has_mcs_mask[IEEE80211_NUM_BANDS];
742 u8 rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN]; 744 u8 rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
743 745
744 union { 746 union {
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index dd88381c53b7..5d545dd2d050 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -460,9 +460,12 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
460 * the common case. 460 * the common case.
461 */ 461 */
462 mask = sdata->rc_rateidx_mask[info->band]; 462 mask = sdata->rc_rateidx_mask[info->band];
463 memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band], 463 if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) {
464 sizeof(mcs_mask)); 464 if (txrc->rate_idx_mcs_mask)
465 if (mask != (1 << txrc->sband->n_bitrates) - 1) { 465 memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask));
466 else
467 memset(mcs_mask, 0xff, sizeof(mcs_mask));
468
466 if (sta) { 469 if (sta) {
467 /* Filter out rates that the STA does not support */ 470 /* Filter out rates that the STA does not support */
468 mask &= sta->sta.supp_rates[info->band]; 471 mask &= sta->sta.supp_rates[info->band];
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index bb82c873f774..15c1b286e280 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -642,9 +642,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
642 txrc.max_rate_idx = -1; 642 txrc.max_rate_idx = -1;
643 else 643 else
644 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; 644 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
645 memcpy(txrc.rate_idx_mcs_mask, 645
646 tx->sdata->rc_rateidx_mcs_mask[info->band], 646 if (tx->sdata->rc_has_mcs_mask[info->band])
647 sizeof(txrc.rate_idx_mcs_mask)); 647 txrc.rate_idx_mcs_mask =
648 tx->sdata->rc_rateidx_mcs_mask[info->band];
649
648 txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || 650 txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
649 tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT || 651 tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
650 tx->sdata->vif.type == NL80211_IFTYPE_ADHOC); 652 tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
@@ -2508,8 +2510,6 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2508 txrc.max_rate_idx = -1; 2510 txrc.max_rate_idx = -1;
2509 else 2511 else
2510 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; 2512 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
2511 memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
2512 sizeof(txrc.rate_idx_mcs_mask));
2513 txrc.bss = true; 2513 txrc.bss = true;
2514 rate_control_get_rate(sdata, NULL, &txrc); 2514 rate_control_get_rate(sdata, NULL, &txrc);
2515 2515