diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rc.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/rc.c | 97 |
1 files changed, 58 insertions, 39 deletions
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index ee28a1a3d010..7863bd278b22 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c | |||
@@ -11,10 +11,6 @@ | |||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
12 | * more details. | 12 | * more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | 14 | * The full GNU General Public License is included in this distribution in the |
19 | * file called LICENSE. | 15 | * file called LICENSE. |
20 | * | 16 | * |
@@ -35,13 +31,13 @@ | |||
35 | *Finds the highest rate index we can use | 31 | *Finds the highest rate index we can use |
36 | *if skb is special data like DHCP/EAPOL, we set should | 32 | *if skb is special data like DHCP/EAPOL, we set should |
37 | *it to lowest rate CCK_1M, otherwise we set rate to | 33 | *it to lowest rate CCK_1M, otherwise we set rate to |
38 | *CCK11M or OFDM_54M based on wireless mode. | 34 | *highest rate based on wireless mode used for iwconfig |
35 | *show Tx rate. | ||
39 | */ | 36 | */ |
40 | static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, | 37 | static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, |
41 | struct ieee80211_sta *sta, | 38 | struct ieee80211_sta *sta, |
42 | struct sk_buff *skb, bool not_data) | 39 | struct sk_buff *skb, bool not_data) |
43 | { | 40 | { |
44 | struct rtl_mac *rtlmac = rtl_mac(rtlpriv); | ||
45 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | 41 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); |
46 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 42 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
47 | struct rtl_sta_info *sta_entry = NULL; | 43 | struct rtl_sta_info *sta_entry = NULL; |
@@ -54,21 +50,13 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, | |||
54 | *2.in rtl_get_tcb_desc when we check rate is | 50 | *2.in rtl_get_tcb_desc when we check rate is |
55 | * 1M we will not use FW rate but user rate. | 51 | * 1M we will not use FW rate but user rate. |
56 | */ | 52 | */ |
57 | if (rtlmac->opmode == NL80211_IFTYPE_AP || | 53 | |
58 | rtlmac->opmode == NL80211_IFTYPE_ADHOC || | 54 | if (sta) { |
59 | rtlmac->opmode == NL80211_IFTYPE_MESH_POINT) { | 55 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; |
60 | if (sta) { | 56 | wireless_mode = sta_entry->wireless_mode; |
61 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
62 | wireless_mode = sta_entry->wireless_mode; | ||
63 | } else { | ||
64 | return 0; | ||
65 | } | ||
66 | } else { | ||
67 | wireless_mode = rtlmac->mode; | ||
68 | } | 57 | } |
69 | 58 | ||
70 | if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) || | 59 | if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) || not_data) { |
71 | not_data) { | ||
72 | return 0; | 60 | return 0; |
73 | } else { | 61 | } else { |
74 | if (rtlhal->current_bandtype == BAND_ON_2_4G) { | 62 | if (rtlhal->current_bandtype == BAND_ON_2_4G) { |
@@ -76,21 +64,27 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, | |||
76 | return B_MODE_MAX_RIX; | 64 | return B_MODE_MAX_RIX; |
77 | } else if (wireless_mode == WIRELESS_MODE_G) { | 65 | } else if (wireless_mode == WIRELESS_MODE_G) { |
78 | return G_MODE_MAX_RIX; | 66 | return G_MODE_MAX_RIX; |
79 | } else { | 67 | } else if (wireless_mode == WIRELESS_MODE_N_24G) { |
80 | if (get_rf_type(rtlphy) != RF_2T2R) | 68 | if (get_rf_type(rtlphy) != RF_2T2R) |
81 | return N_MODE_MCS7_RIX; | 69 | return N_MODE_MCS7_RIX; |
82 | else | 70 | else |
83 | return N_MODE_MCS15_RIX; | 71 | return N_MODE_MCS15_RIX; |
72 | } else if (wireless_mode == WIRELESS_MODE_AC_24G) { | ||
73 | return AC_MODE_MCS9_RIX; | ||
84 | } | 74 | } |
75 | return 0; | ||
85 | } else { | 76 | } else { |
86 | if (wireless_mode == WIRELESS_MODE_A) { | 77 | if (wireless_mode == WIRELESS_MODE_A) { |
87 | return A_MODE_MAX_RIX; | 78 | return A_MODE_MAX_RIX; |
88 | } else { | 79 | } else if (wireless_mode == WIRELESS_MODE_N_5G) { |
89 | if (get_rf_type(rtlphy) != RF_2T2R) | 80 | if (get_rf_type(rtlphy) != RF_2T2R) |
90 | return N_MODE_MCS7_RIX; | 81 | return N_MODE_MCS7_RIX; |
91 | else | 82 | else |
92 | return N_MODE_MCS15_RIX; | 83 | return N_MODE_MCS15_RIX; |
84 | } else if (wireless_mode == WIRELESS_MODE_AC_5G) { | ||
85 | return AC_MODE_MCS9_RIX; | ||
93 | } | 86 | } |
87 | return 0; | ||
94 | } | 88 | } |
95 | } | 89 | } |
96 | } | 90 | } |
@@ -103,35 +97,52 @@ static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, | |||
103 | bool not_data) | 97 | bool not_data) |
104 | { | 98 | { |
105 | struct rtl_mac *mac = rtl_mac(rtlpriv); | 99 | struct rtl_mac *mac = rtl_mac(rtlpriv); |
106 | u8 sgi_20 = 0, sgi_40 = 0; | 100 | struct rtl_sta_info *sta_entry = NULL; |
101 | u8 wireless_mode = 0; | ||
102 | u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0; | ||
107 | 103 | ||
108 | if (sta) { | 104 | if (sta) { |
109 | sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; | 105 | sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; |
110 | sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; | 106 | sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; |
107 | sgi_80 = sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80; | ||
108 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; | ||
109 | wireless_mode = sta_entry->wireless_mode; | ||
111 | } | 110 | } |
112 | rate->count = tries; | 111 | rate->count = tries; |
113 | rate->idx = rix >= 0x00 ? rix : 0x00; | 112 | rate->idx = rix >= 0x00 ? rix : 0x00; |
113 | if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE && | ||
114 | wireless_mode == WIRELESS_MODE_AC_5G) | ||
115 | rate->idx += 0x10;/*2NSS for 8812AE*/ | ||
114 | 116 | ||
115 | if (!not_data) { | 117 | if (!not_data) { |
116 | if (txrc->short_preamble) | 118 | if (txrc->short_preamble) |
117 | rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; | 119 | rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; |
118 | if (mac->opmode == NL80211_IFTYPE_AP || | 120 | if (mac->opmode == NL80211_IFTYPE_AP || |
119 | mac->opmode == NL80211_IFTYPE_ADHOC) { | 121 | mac->opmode == NL80211_IFTYPE_ADHOC) { |
120 | if (sta && (sta->bandwidth >= IEEE80211_STA_RX_BW_40)) | 122 | if (sta && (sta->ht_cap.cap & |
123 | IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | ||
121 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | 124 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; |
125 | if (sta && (sta->vht_cap.vht_supported)) | ||
126 | rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; | ||
122 | } else { | 127 | } else { |
123 | if (mac->bw_40) | 128 | if (mac->bw_40) |
124 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | 129 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; |
130 | if (mac->bw_80) | ||
131 | rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; | ||
125 | } | 132 | } |
126 | if (sgi_20 || sgi_40) | 133 | |
134 | if (sgi_20 || sgi_40 || sgi_80) | ||
127 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | 135 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; |
128 | if (sta && sta->ht_cap.ht_supported) | 136 | if (sta && sta->ht_cap.ht_supported && |
137 | ((wireless_mode == WIRELESS_MODE_N_5G) || | ||
138 | (wireless_mode == WIRELESS_MODE_N_24G))) | ||
129 | rate->flags |= IEEE80211_TX_RC_MCS; | 139 | rate->flags |= IEEE80211_TX_RC_MCS; |
130 | } | 140 | } |
131 | } | 141 | } |
132 | 142 | ||
133 | static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta, | 143 | static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta, |
134 | void *priv_sta, struct ieee80211_tx_rate_control *txrc) | 144 | void *priv_sta, |
145 | struct ieee80211_tx_rate_control *txrc) | ||
135 | { | 146 | { |
136 | struct rtl_priv *rtlpriv = ppriv; | 147 | struct rtl_priv *rtlpriv = ppriv; |
137 | struct sk_buff *skb = txrc->skb; | 148 | struct sk_buff *skb = txrc->skb; |
@@ -158,7 +169,7 @@ static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta, | |||
158 | } | 169 | } |
159 | 170 | ||
160 | static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, | 171 | static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, |
161 | struct rtl_sta_info *sta_entry, u16 tid) | 172 | struct rtl_sta_info *sta_entry, u16 tid) |
162 | { | 173 | { |
163 | struct rtl_mac *mac = rtl_mac(rtlpriv); | 174 | struct rtl_mac *mac = rtl_mac(rtlpriv); |
164 | 175 | ||
@@ -166,7 +177,7 @@ static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, | |||
166 | return false; | 177 | return false; |
167 | 178 | ||
168 | if (mac->opmode == NL80211_IFTYPE_STATION && | 179 | if (mac->opmode == NL80211_IFTYPE_STATION && |
169 | mac->cnt_after_linked < 3) | 180 | mac->cnt_after_linked < 3) |
170 | return false; | 181 | return false; |
171 | 182 | ||
172 | if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP) | 183 | if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP) |
@@ -193,23 +204,23 @@ static void rtl_tx_status(void *ppriv, | |||
193 | if (rtl_is_special_data(mac->hw, skb, true)) | 204 | if (rtl_is_special_data(mac->hw, skb, true)) |
194 | return; | 205 | return; |
195 | 206 | ||
196 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) | 207 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || |
197 | || is_broadcast_ether_addr(ieee80211_get_DA(hdr))) | 208 | is_broadcast_ether_addr(ieee80211_get_DA(hdr))) |
198 | return; | 209 | return; |
199 | 210 | ||
200 | if (sta) { | 211 | if (sta) { |
201 | /* Check if aggregation has to be enabled for this tid */ | 212 | /* Check if aggregation has to be enabled for this tid */ |
202 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | 213 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; |
203 | if ((sta->ht_cap.ht_supported) && | 214 | if ((sta->ht_cap.ht_supported) && |
204 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | 215 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { |
205 | if (ieee80211_is_data_qos(fc)) { | 216 | if (ieee80211_is_data_qos(fc)) { |
206 | u8 tid = rtl_get_tid(skb); | 217 | u8 tid = rtl_get_tid(skb); |
207 | if (_rtl_tx_aggr_check(rtlpriv, sta_entry, | 218 | if (_rtl_tx_aggr_check(rtlpriv, sta_entry, |
208 | tid)) { | 219 | tid)) { |
209 | sta_entry->tids[tid].agg.agg_state = | 220 | sta_entry->tids[tid].agg.agg_state = |
210 | RTL_AGG_PROGRESS; | 221 | RTL_AGG_PROGRESS; |
211 | ieee80211_start_tx_ba_session(sta, | 222 | ieee80211_start_tx_ba_session(sta, tid, |
212 | tid, 5000); | 223 | 5000); |
213 | } | 224 | } |
214 | } | 225 | } |
215 | } | 226 | } |
@@ -223,8 +234,15 @@ static void rtl_rate_init(void *ppriv, | |||
223 | { | 234 | { |
224 | } | 235 | } |
225 | 236 | ||
226 | static void *rtl_rate_alloc(struct ieee80211_hw *hw, | 237 | static void rtl_rate_update(void *ppriv, |
227 | struct dentry *debugfsdir) | 238 | struct ieee80211_supported_band *sband, |
239 | struct cfg80211_chan_def *chandef, | ||
240 | struct ieee80211_sta *sta, void *priv_sta, | ||
241 | u32 changed) | ||
242 | { | ||
243 | } | ||
244 | |||
245 | static void *rtl_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | ||
228 | { | 246 | { |
229 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 247 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
230 | return rtlpriv; | 248 | return rtlpriv; |
@@ -260,13 +278,14 @@ static void rtl_rate_free_sta(void *rtlpriv, | |||
260 | kfree(rate_priv); | 278 | kfree(rate_priv); |
261 | } | 279 | } |
262 | 280 | ||
263 | static const struct rate_control_ops rtl_rate_ops = { | 281 | static struct rate_control_ops rtl_rate_ops = { |
264 | .name = "rtl_rc", | 282 | .name = "rtl_rc", |
265 | .alloc = rtl_rate_alloc, | 283 | .alloc = rtl_rate_alloc, |
266 | .free = rtl_rate_free, | 284 | .free = rtl_rate_free, |
267 | .alloc_sta = rtl_rate_alloc_sta, | 285 | .alloc_sta = rtl_rate_alloc_sta, |
268 | .free_sta = rtl_rate_free_sta, | 286 | .free_sta = rtl_rate_free_sta, |
269 | .rate_init = rtl_rate_init, | 287 | .rate_init = rtl_rate_init, |
288 | .rate_update = rtl_rate_update, | ||
270 | .tx_status = rtl_tx_status, | 289 | .tx_status = rtl_tx_status, |
271 | .get_rate = rtl_get_rate, | 290 | .get_rate = rtl_get_rate, |
272 | }; | 291 | }; |