a80a46f0147b79aa41c94efcc1a60c9f8e40289f
[openwrt.git] / package / mac80211 / patches / 540-mac80211_optimize_mcs_rate_mask.patch
1 --- a/net/mac80211/ieee80211_i.h
2 +++ b/net/mac80211/ieee80211_i.h
3 @@ -761,6 +761,8 @@ struct ieee80211_sub_if_data {
4  
5         /* bitmap of allowed (non-MCS) rate indexes for rate control */
6         u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
7 +
8 +       bool rc_has_mcs_mask[IEEE80211_NUM_BANDS];
9         u8  rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
10  
11         union {
12 --- a/net/mac80211/cfg.c
13 +++ b/net/mac80211/cfg.c
14 @@ -2291,9 +2291,20 @@ static int ieee80211_set_bitrate_mask(st
15         }
16  
17         for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
18 +               struct ieee80211_supported_band *sband = wiphy->bands[i];
19 +
20                 sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
21                 memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
22                        sizeof(mask->control[i].mcs));
23 +
24 +               sdata->rc_has_mcs_mask[i] = false;
25 +               if (!sband)
26 +                       continue;
27 +
28 +               if (memcmp(sdata->rc_rateidx_mcs_mask[i],
29 +                          sband->ht_cap.mcs.rx_mask,
30 +                          sizeof(sband->ht_cap.mcs.rx_mask)) != 0)
31 +                       sdata->rc_has_mcs_mask[i] = true;
32         }
33  
34         return 0;
35 --- a/include/net/mac80211.h
36 +++ b/include/net/mac80211.h
37 @@ -3968,7 +3968,7 @@ void ieee80211_send_bar(struct ieee80211
38   *     (deprecated; this will be removed once drivers get updated to use
39   *     rate_idx_mask)
40   * @rate_idx_mask: user-requested (legacy) rate mask
41 - * @rate_idx_mcs_mask: user-requested MCS rate mask
42 + * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use)
43   * @bss: whether this frame is sent out in AP or IBSS mode
44   */
45  struct ieee80211_tx_rate_control {
46 @@ -3980,7 +3980,7 @@ struct ieee80211_tx_rate_control {
47         bool rts, short_preamble;
48         u8 max_rate_idx;
49         u32 rate_idx_mask;
50 -       u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
51 +       u8 *rate_idx_mcs_mask;
52         bool bss;
53  };
54  
55 --- a/net/mac80211/tx.c
56 +++ b/net/mac80211/tx.c
57 @@ -636,9 +636,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
58                 txrc.max_rate_idx = -1;
59         else
60                 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
61 -       memcpy(txrc.rate_idx_mcs_mask,
62 -              tx->sdata->rc_rateidx_mcs_mask[info->band],
63 -              sizeof(txrc.rate_idx_mcs_mask));
64 +
65 +       if (tx->sdata->rc_has_mcs_mask[info->band])
66 +               txrc.rate_idx_mcs_mask =
67 +                       tx->sdata->rc_rateidx_mcs_mask[info->band];
68 +
69         txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
70                     tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
71                     tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
72 @@ -2502,8 +2504,6 @@ struct sk_buff *ieee80211_beacon_get_tim
73                 txrc.max_rate_idx = -1;
74         else
75                 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
76 -       memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
77 -              sizeof(txrc.rate_idx_mcs_mask));
78         txrc.bss = true;
79         rate_control_get_rate(sdata, NULL, &txrc);
80  
81 --- a/net/mac80211/rate.c
82 +++ b/net/mac80211/rate.c
83 @@ -460,9 +460,12 @@ void rate_control_get_rate(struct ieee80
84          * the common case.
85          */
86         mask = sdata->rc_rateidx_mask[info->band];
87 -       memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
88 -              sizeof(mcs_mask));
89 -       if (mask != (1 << txrc->sband->n_bitrates) - 1) {
90 +       if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) {
91 +               if (txrc->rate_idx_mcs_mask)
92 +                       memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask));
93 +               else
94 +                       memset(mcs_mask, 0xff, sizeof(mcs_mask));
95 +
96                 if (sta) {
97                         /* Filter out rates that the STA does not support */
98                         mask &= sta->sta.supp_rates[info->band];