1 /*
2 * Copyright (c) 2015 South Silicon Valley Microelectronics Inc.
3 * Copyright (c) 2015 iComm Corporation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/version.h>
18 #include <ssv6200.h>
19 #include "dev.h"
20 #include "ssv_ht_rc.h"
21 #include "ssv_rc.h"
22 #define SAMPLE_COUNT 4
23 #define HT_CW_MIN 15
24 #define HT_SEGMENT_SIZE 6000
25 #define AVG_PKT_SIZE 12000
26 #define SAMPLE_COLUMNS 10
27 #define EWMA_LEVEL 75
28 #define MCS_NBITS (AVG_PKT_SIZE << 3)
29 #define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps))
30 #define MCS_SYMBOL_TIME(sgi,syms) \
31 (sgi ? \
32 ((syms) * 18 + 4) / 5 : \
33 (syms) << 2 \
34 )
35 #define MCS_DURATION(streams,sgi,bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps)))
36 #define MCS_GROUP(_streams,_sgi,_ht40) { \
37 .duration = { \
38 MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26), \
39 MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52), \
40 MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78), \
41 MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104), \
42 MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156), \
43 MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208), \
44 MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234), \
45 MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \
46 } \
47 }
48 const struct mcs_group minstrel_mcs_groups_ssv[] = {
49 MCS_GROUP(1, 0, 0),
50 MCS_GROUP(1, 1, 0),
51 };
52 const u16 ampdu_max_transmit_length[RATE_TABLE_SIZE] =
53 {
54 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0,
56 4600, 9200, 13800, 18500, 27700, 37000, 41600, 46200,
57 5100, 10200, 15400, 20500, 30800, 41100, 46200, 51300,
58 4600, 9200, 13800, 18500, 27700, 37000, 41600, 46200
59 };
60 static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES];
minstrel_ewma(int old,int new,int weight)61 static int minstrel_ewma(int old, int new, int weight)
62 {
63 return (new * (100 - weight) + old * weight) / 100;
64 }
minstrel_get_ratestats(struct ssv62xx_ht * mi,int index)65 static inline struct minstrel_rate_stats *minstrel_get_ratestats(struct ssv62xx_ht *mi, int index)
66 {
67 return &mi->groups.rates[index % MCS_GROUP_RATES];
68 }
minstrel_calc_rate_ewma(struct minstrel_rate_stats * mr)69 static void minstrel_calc_rate_ewma(struct minstrel_rate_stats *mr)
70 {
71 if (unlikely(mr->attempts > 0)) {
72 mr->sample_skipped = 0;
73 mr->cur_prob = MINSTREL_FRAC(mr->success, mr->attempts);
74 if (!mr->att_hist)
75 mr->probability = mr->cur_prob;
76 else
77 mr->probability = minstrel_ewma(mr->probability,
78 mr->cur_prob, EWMA_LEVEL);
79 mr->att_hist += mr->attempts;
80 mr->succ_hist += mr->success;
81 } else {
82 mr->sample_skipped++;
83 }
84 mr->last_success = mr->success;
85 mr->last_attempts = mr->attempts;
86 mr->success = 0;
87 mr->attempts = 0;
88 }
minstrel_ht_calc_tp(struct ssv62xx_ht * mi,struct ssv_sta_rc_info * rc_sta,int rate)89 static void minstrel_ht_calc_tp(struct ssv62xx_ht *mi, struct ssv_sta_rc_info *rc_sta, int rate)
90 {
91 struct minstrel_rate_stats *mr;
92 unsigned int usecs,group_id;
93 if(rc_sta->ht_rc_type == RC_TYPE_HT_LGI_20)
94 group_id = 0;
95 else
96 group_id = 1;
97 mr = &mi->groups.rates[rate];
98 if (mr->probability < MINSTREL_FRAC(1, 10)) {
99 mr->cur_tp = 0;
100 return;
101 }
102 usecs = mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
103 usecs += minstrel_mcs_groups_ssv[group_id].duration[rate];
104 mr->cur_tp = MINSTREL_TRUNC((1000000 / usecs) * mr->probability);
105 }
rate_control_ht_sample(struct ssv62xx_ht * mi,struct ssv_sta_rc_info * rc_sta)106 static void rate_control_ht_sample(struct ssv62xx_ht *mi,struct ssv_sta_rc_info *rc_sta)
107 {
108 struct minstrel_mcs_group_data *mg;
109 struct minstrel_rate_stats *mr;
110 int cur_prob, cur_prob_tp, cur_tp, cur_tp2;
111 int i, index;
112 if (mi->ampdu_packets > 0) {
113 mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
114 MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), EWMA_LEVEL);
115 mi->ampdu_len = 0;
116 mi->ampdu_packets = 0;
117 }
118 else
119 return;
120 mi->sample_slow = 0;
121 mi->sample_count = 0;
122 {
123 cur_prob = 0;
124 cur_prob_tp = 0;
125 cur_tp = 0;
126 cur_tp2 = 0;
127 mg = &mi->groups;
128 mg->max_tp_rate = 0;
129 mg->max_tp_rate2 = 0;
130 mg->max_prob_rate = 0;
131 for (i = 0; i < MCS_GROUP_RATES; i++) {
132 if (!(rc_sta->ht_supp_rates & BIT(i)))
133 continue;
134 mr = &mg->rates[i];
135 index = i;
136 minstrel_calc_rate_ewma(mr);
137 minstrel_ht_calc_tp(mi, rc_sta, i);
138 #ifdef RATE_CONTROL_HT_PARAMETER_DEBUG
139 if(mr->cur_prob)
140 printk("rate[%d]probability[%08d]cur_prob[%08d]TP[%04d]\n",i,mr->probability,mr->cur_prob,mr->cur_tp);
141 #endif
142 #ifdef RATE_CONTROL_HT_STUPID_DEBUG
143 printk("HT sample result max_tp_rate[%d]max_tp_rate2[%d]max_prob_rate[%d]\n",mg->max_tp_rate,mg->max_tp_rate2,mg->max_prob_rate);
144 printk("rate[%d]probability[%08d]TP[%d]\n",i,mr->probability,mr->cur_tp);
145 #endif
146 if (!mr->cur_tp)
147 continue;
148 #ifdef RATE_CONTROL_HT_STUPID_DEBUG
149 printk("HT--1 mr->cur_tp[%d]cur_prob_tp[%d]\n",mr->cur_tp,cur_prob_tp);
150 #endif
151 if ((mr->cur_tp > cur_prob_tp && mr->probability >
152 MINSTREL_FRAC(3, 4)) || mr->probability > cur_prob) {
153 mg->max_prob_rate = index;
154 cur_prob = mr->probability;
155 cur_prob_tp = mr->cur_tp;
156 }
157 #ifdef RATE_CONTROL_HT_STUPID_DEBUG
158 printk("HT--2 mr->cur_tp[%d]cur_tp[%d]\n",mr->cur_tp,cur_tp);
159 #endif
160 if (mr->cur_tp > cur_tp) {
161 swap(index, mg->max_tp_rate);
162 cur_tp = mr->cur_tp;
163 mr = minstrel_get_ratestats(mi, index);
164 }
165 #ifdef RATE_CONTROL_HT_STUPID_DEBUG
166 if(index != i)
167 printk("HT--3 index[%d]i[%d]mg->max_tp_rate[%d]\n",index,i,mg->max_tp_rate);
168 #endif
169 if (index >= mg->max_tp_rate)
170 continue;
171 #ifdef RATE_CONTROL_HT_STUPID_DEBUG
172 if(index != i)
173 printk("HT--4 mr->cur_tp[%d]cur_tp2[%d]\n",mr->cur_tp,cur_tp2);
174 #endif
175 if (mr->cur_tp > cur_tp2) {
176 mg->max_tp_rate2 = index;
177 cur_tp2 = mr->cur_tp;
178 }
179 }
180 }
181 mi->sample_count = SAMPLE_COUNT;
182 #if 0
183 cur_prob = 0;
184 cur_prob_tp = 0;
185 cur_tp = 0;
186 cur_tp2 = 0;
187 {
188 mg = &mi->groups;
189 mr = minstrel_get_ratestats(mi, mg->max_prob_rate);
190 if (cur_prob_tp < mr->cur_tp) {
191 mi->max_prob_rate = mg->max_prob_rate;
192 cur_prob = mr->cur_prob;
193 cur_prob_tp = mr->cur_tp;
194 }
195 mr = minstrel_get_ratestats(mi, mg->max_tp_rate);
196 if (cur_tp < mr->cur_tp) {
197 mi->max_tp_rate2 = mi->max_tp_rate;
198 cur_tp2 = cur_tp;
199 mi->max_tp_rate = mg->max_tp_rate;
200 cur_tp = mr->cur_tp;
201 }
202 mr = minstrel_get_ratestats(mi, mg->max_tp_rate2);
203 if (cur_tp2 < mr->cur_tp) {
204 mi->max_tp_rate2 = mg->max_tp_rate2;
205 cur_tp2 = mr->cur_tp;
206 }
207 }
208 #else
209 mi->max_tp_rate = mg->max_tp_rate;
210 mi->max_tp_rate2 = mg->max_tp_rate2;
211 mi->max_prob_rate = mg->max_prob_rate;
212 #endif
213 #ifdef RATE_CONTROL_HT_STUPID_DEBUG
214 printk("HT sample result max_tp_rate[%d]max_tp_rate2[%d]max_prob_rate[%d]\n",mi->max_tp_rate,mi->max_tp_rate2,mi->max_prob_rate);
215 #endif
216 mi->stats_update = jiffies;
217 }
218 #if 0
219 static void minstrel_calc_retransmit(struct ssv62xx_ht *mi,int index, struct ssv_sta_rc_info *rc_sta)
220 {
221 struct minstrel_rate_stats *mr;
222 const struct mcs_group *group;
223 unsigned int tx_time, tx_time_rtscts, tx_time_data;
224 unsigned int cw = HT_CW_MIN;
225 unsigned int cw_max = 1023;
226 unsigned int ctime = 0;
227 unsigned int t_slot = 9;
228 unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len);
229 unsigned int group_id;
230 if(rc_sta->ht_rc_type == RC_TYPE_HT_LGI_20)
231 group_id = 0;
232 else
233 group_id = 1;
234 mr = minstrel_get_ratestats(mi, index);
235 if (mr->probability < MINSTREL_FRAC(1, 10)) {
236 mr->retry_count = 1;
237 mr->retry_count_rtscts = 1;
238 return;
239 }
240 mr->retry_count = 2;
241 mr->retry_count_rtscts = 2;
242 mr->retry_updated = true;
243 group = &minstrel_mcs_groups_ssv[group_id];
244 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len;
245 ctime = (t_slot * cw) >> 1;
246 cw = min((cw << 1) | 1, cw_max);
247 ctime += (t_slot * cw) >> 1;
248 cw = min((cw << 1) | 1, cw_max);
249 tx_time = ctime + 2 * (mi->overhead + tx_time_data);
250 tx_time_rtscts = ctime + 2 * (mi->overhead_rtscts + tx_time_data);
251 do {
252 ctime = (t_slot * cw) >> 1;
253 cw = min((cw << 1) | 1, cw_max);
254 tx_time += ctime + mi->overhead + tx_time_data;
255 tx_time_rtscts += ctime + mi->overhead_rtscts + tx_time_data;
256 if (tx_time_rtscts < HT_SEGMENT_SIZE)
257 mr->retry_count_rtscts++;
258 } while ((tx_time < HT_SEGMENT_SIZE) &&
259 (++mr->retry_count < HW_MAX_RATE_TRIES));
260 }
261 #endif
minstrel_ht_set_rate(struct ssv62xx_ht * mi,struct fw_rc_retry_params * rate,int index,bool sample,bool rtscts,struct ssv_sta_rc_info * rc_sta,struct ssv_rate_ctrl * ssv_rc)262 static void minstrel_ht_set_rate(struct ssv62xx_ht *mi,
263 struct fw_rc_retry_params *rate, int index,
264 bool sample, bool rtscts, struct ssv_sta_rc_info *rc_sta,
265 struct ssv_rate_ctrl *ssv_rc)
266 {
267 struct minstrel_rate_stats *mr;
268 mr = minstrel_get_ratestats(mi, index);
269 #if 0
270 if (!mr->retry_updated)
271 minstrel_calc_retransmit(mi, index, rc_sta);
272 if (sample)
273 rate->count = 1;
274 else if (mr->probability < MINSTREL_FRAC(20, 100))
275 rate->count = 2;
276 else if (rtscts)
277 rate->count = mr->retry_count_rtscts;
278 else
279 rate->count = mr->retry_count;
280 #endif
281 rate->drate = ssv_rc->rc_table[mr->rc_index].hw_rate_idx;
282 rate->crate = ssv_rc->rc_table[mr->rc_index].ctrl_rate_idx;
283 }
minstrel_get_duration(int index,struct ssv_sta_rc_info * rc_sta)284 static inline int minstrel_get_duration(int index, struct ssv_sta_rc_info *rc_sta)
285 {
286 unsigned int group_id;
287 const struct mcs_group *group;
288 if(rc_sta->ht_rc_type == RC_TYPE_HT_LGI_20)
289 group_id = 0;
290 else
291 group_id = 1;
292 group = &minstrel_mcs_groups_ssv[group_id];
293 return group->duration[index % MCS_GROUP_RATES];
294 }
minstrel_next_sample_idx(struct ssv62xx_ht * mi)295 static void minstrel_next_sample_idx(struct ssv62xx_ht *mi)
296 {
297 struct minstrel_mcs_group_data *mg;
298 for (;;) {
299 mg = &mi->groups;
300 if (++mg->index >= MCS_GROUP_RATES) {
301 mg->index = 0;
302 if (++mg->column >= ARRAY_SIZE(sample_table))
303 mg->column = 0;
304 }
305 break;
306 }
307 }
minstrel_get_sample_rate(struct ssv62xx_ht * mi,struct ssv_sta_rc_info * rc_sta)308 static int minstrel_get_sample_rate(struct ssv62xx_ht *mi, struct ssv_sta_rc_info *rc_sta)
309 {
310 struct minstrel_rate_stats *mr;
311 struct minstrel_mcs_group_data *mg;
312 int sample_idx = 0;
313 if (mi->sample_wait > 0) {
314 mi->sample_wait--;
315 return -1;
316 }
317 if (!mi->sample_tries)
318 return -1;
319 mi->sample_tries--;
320 mg = &mi->groups;
321 sample_idx = sample_table[mg->column][mg->index];
322 mr = &mg->rates[sample_idx];
323 minstrel_next_sample_idx(mi);
324 if (minstrel_get_duration(sample_idx, rc_sta) >
325 minstrel_get_duration(mi->max_tp_rate, rc_sta)) {
326 if (mr->sample_skipped < 20)
327 {
328 return -1;
329 }
330 if (mi->sample_slow++ > 2)
331 {
332 return -1;
333 }
334 }
335 return sample_idx;
336 }
_fill_txinfo_rates(struct ssv_rate_ctrl * ssv_rc,struct sk_buff * skb,struct fw_rc_retry_params * ar)337 static void _fill_txinfo_rates (struct ssv_rate_ctrl *ssv_rc, struct sk_buff *skb, struct fw_rc_retry_params *ar)
338 {
339 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
340 info->control.rates[0].idx = ssv_rc->rc_table[ar[0].drate].dot11_rate_idx;
341 info->control.rates[0].count = 1;
342 info->control.rates[SSV_DRATE_IDX].count = ar[0].drate;
343 info->control.rates[SSV_CRATE_IDX].count = ar[0].crate;
344 }
345 extern const u16 ssv6xxx_rc_rate_set[RC_TYPE_MAX][13];
ssv62xx_ht_rate_update(struct sk_buff * skb,struct ssv_softc * sc,struct fw_rc_retry_params * ar)346 s32 ssv62xx_ht_rate_update(struct sk_buff *skb, struct ssv_softc *sc, struct fw_rc_retry_params *ar)
347 {
348 struct ssv_rate_ctrl *ssv_rc = sc->rc;
349 struct SKB_info_st *skb_info = (struct SKB_info_st *)skb->head;
350 struct ieee80211_sta *sta = skb_info->sta;
351 struct ssv62xx_ht *mi = NULL;
352 int sample_idx;
353 bool sample = false;
354 struct ssv_sta_rc_info *rc_sta;
355 struct ssv_sta_priv_data *sta_priv;
356 struct rc_pid_sta_info *spinfo;
357 int ret = 0;
358 if (sc->sc_flags & SC_OP_FIXED_RATE)
359 {
360 ar[0].count = 3;
361 ar[0].drate = ssv_rc->rc_table[sc->max_rate_idx].hw_rate_idx;
362 ar[0].crate = ssv_rc->rc_table[sc->max_rate_idx].ctrl_rate_idx;
363 ar[1].count = 2;
364 ar[1].drate = ssv_rc->rc_table[sc->max_rate_idx].hw_rate_idx;
365 ar[1].crate = ssv_rc->rc_table[sc->max_rate_idx].ctrl_rate_idx;
366 ar[2].count = 2;
367 ar[2].drate = ssv_rc->rc_table[sc->max_rate_idx].hw_rate_idx;
368 ar[2].crate = ssv_rc->rc_table[sc->max_rate_idx].ctrl_rate_idx;
369 _fill_txinfo_rates(ssv_rc, skb, ar);
370 return ssv_rc->rc_table[sc->max_rate_idx].hw_rate_idx;
371 }
372 if(sta == NULL)
373 {
374 printk("@Q@...station NULL\n");
375 BUG_ON(1);
376 }
377 sta_priv = (struct ssv_sta_priv_data *)sta->drv_priv;
378 rc_sta = &ssv_rc->sta_rc_info[sta_priv->rc_idx];
379 spinfo= &rc_sta->spinfo;
380 if ((rc_sta->rc_wsid >= SSV_RC_MAX_HARDWARE_SUPPORT) || (rc_sta->rc_wsid < 0))
381 {
382 struct ssv_sta_priv_data *ssv_sta_priv;
383 int rateidx=99;
384 ssv_sta_priv = (struct ssv_sta_priv_data *)sta->drv_priv;
385 {
386 if ((rc_sta->ht_rc_type >= RC_TYPE_HT_SGI_20) &&
387 (ssv_sta_priv->rx_data_rate < SSV62XX_RATE_MCS_INDEX))
388 {
389 if(ssv6xxx_rc_rate_set[rc_sta->ht_rc_type][0] == 12)
390 rateidx = (int)rc_sta->pinfo.rinfo[4].rc_index;
391 else
392 rateidx = (int)rc_sta->pinfo.rinfo[0].rc_index;
393 #if 0
394 printk("RC %d rx %d tx %d\n", ssv_sta_priv->sta_idx,
395 ssv_sta_priv->rx_data_rate, rateidx);
396 #endif
397 }
398 else
399 {
400 rateidx = (int)ssv_sta_priv->rx_data_rate;
401 rateidx -= SSV62XX_RATE_MCS_INDEX;
402 rateidx %= 8;
403 if(rc_sta->ht_rc_type == RC_TYPE_HT_SGI_20)
404 rateidx += SSV62XX_RATE_MCS_SGI_INDEX;
405 else if(rc_sta->ht_rc_type == RC_TYPE_HT_LGI_20)
406 rateidx += SSV62XX_RATE_MCS_LGI_INDEX;
407 else
408 rateidx += SSV62XX_RATE_MCS_GREENFIELD_INDEX;
409 }
410 }
411 ar[0].count = 3;
412 ar[2].drate = ar[1].drate = ar[0].drate = ssv_rc->rc_table[rateidx].hw_rate_idx;
413 ar[2].crate = ar[1].crate = ar[0].crate = ssv_rc->rc_table[rateidx].ctrl_rate_idx;
414 ar[1].count = 2;
415 ar[2].count = 2;
416 _fill_txinfo_rates(ssv_rc, skb, ar);
417 return rateidx;
418 }
419 mi = &rc_sta->ht;
420 sample_idx = minstrel_get_sample_rate(mi, rc_sta);
421 if (sample_idx >= 0) {
422 sample = true;
423 minstrel_ht_set_rate(mi, &ar[0], sample_idx,
424 true, false, rc_sta, ssv_rc);
425 } else {
426 minstrel_ht_set_rate(mi, &ar[0], mi->max_tp_rate,
427 false, false, rc_sta, ssv_rc);
428 }
429 ar[0].count = mi->first_try_count;
430 ret = ar[0].drate;
431 {
432 if (sample_idx >= 0)
433 minstrel_ht_set_rate(mi, &ar[1], mi->max_tp_rate,
434 false, false, rc_sta, ssv_rc);
435 else
436 minstrel_ht_set_rate(mi, &ar[1], mi->max_tp_rate2,
437 false, true, rc_sta, ssv_rc);
438 ar[1].count = mi->second_try_count;
439 if(ret > ar[1].drate)
440 ret = ar[1].drate;
441 minstrel_ht_set_rate(mi, &ar[2], mi->max_prob_rate,
442 false, !sample, rc_sta, ssv_rc);
443 ar[2].count = mi->other_try_count;
444 if(ret > ar[2].drate)
445 ret = ar[2].drate;
446 }
447 mi->total_packets++;
448 if (mi->total_packets == ~0) {
449 mi->total_packets = 0;
450 mi->sample_packets = 0;
451 }
452 if(spinfo->real_hw_index < SSV62XX_RATE_MCS_INDEX)
453 return spinfo->real_hw_index;
454 _fill_txinfo_rates(ssv_rc, skb, ar);
455 return ret;
456 }
init_sample_table(void)457 static void init_sample_table(void)
458 {
459 int col, i, new_idx;
460 u8 rnd[MCS_GROUP_RATES];
461 memset(sample_table, 0xff, sizeof(sample_table));
462 for (col = 0; col < SAMPLE_COLUMNS; col++) {
463 for (i = 0; i < MCS_GROUP_RATES; i++) {
464 get_random_bytes(rnd, sizeof(rnd));
465 new_idx = (i + rnd[i]) % MCS_GROUP_RATES;
466 while (sample_table[col][new_idx] != 0xff)
467 new_idx = (new_idx + 1) % MCS_GROUP_RATES;
468 sample_table[col][new_idx] = i;
469 }
470 }
471 }
ssv62xx_ht_rc_caps(const u16 ssv6xxx_rc_rate_set[RC_TYPE_MAX][13],struct ssv_sta_rc_info * rc_sta)472 void ssv62xx_ht_rc_caps(const u16 ssv6xxx_rc_rate_set[RC_TYPE_MAX][13],struct ssv_sta_rc_info *rc_sta)
473 {
474 struct ssv62xx_ht *mi = &rc_sta->ht;
475 int ack_dur;
476 int i;
477 #if 1
478 unsigned int group_id;
479 if(rc_sta->ht_rc_type == RC_TYPE_HT_LGI_20)
480 group_id = 0;
481 else
482 group_id = 1;
483 for (i = 0; i < MCS_GROUP_RATES; i++) {
484 printk("[RC]HT duration[%d][%d]\n",i,minstrel_mcs_groups_ssv[group_id].duration[i]);
485 }
486 #endif
487 init_sample_table();
488 memset(mi, 0, sizeof(*mi));
489 mi->stats_update = jiffies;
490 ack_dur = pide_frame_duration( 10, 60, 0, 0);
491 mi->overhead = pide_frame_duration( 0, 60, 0, 0) + ack_dur;
492 mi->overhead_rtscts = mi->overhead + 2 * ack_dur;
493 mi->avg_ampdu_len = MINSTREL_FRAC(1, 1);
494 mi->sample_count = 16;
495 mi->sample_wait = 0;
496 mi->sample_tries = 4;
497 #ifdef DISABLE_RATE_CONTROL_SAMPLE
498 mi->max_tp_rate = MCS_GROUP_RATES - 1;
499 mi->max_tp_rate2 = MCS_GROUP_RATES - 1;
500 mi->max_prob_rate = MCS_GROUP_RATES - 1;
501 #endif
502 #if (HW_MAX_RATE_TRIES == 7)
503 {
504 mi->first_try_count = 3;
505 mi->second_try_count = 2;
506 mi->other_try_count = 2;
507 }
508 #else
509 {
510 mi->first_try_count = 2;
511 mi->second_try_count = 1;
512 mi->other_try_count = 1;
513 }
514 #endif
515 for (i = 0; i < MCS_GROUP_RATES; i++) {
516 mi->groups.rates[i].rc_index = ssv6xxx_rc_rate_set[rc_sta->ht_rc_type][i+1];
517 }
518 }
minstrel_ht_txstat_valid(struct ssv62xx_tx_rate * rate)519 static bool minstrel_ht_txstat_valid(struct ssv62xx_tx_rate *rate)
520 {
521 if (!rate->count)
522 return false;
523 if (rate->data_rate < 0)
524 return false;
525 return true;
526 }
ssv6xxx_ht_report_handler(struct ssv_softc * sc,struct sk_buff * skb,struct ssv_sta_rc_info * rc_sta)527 void ssv6xxx_ht_report_handler(struct ssv_softc *sc,struct sk_buff *skb,struct ssv_sta_rc_info *rc_sta)
528 {
529 struct cfg_host_event *host_event;
530 struct firmware_rate_control_report_data *report_data;
531 struct ssv62xx_ht *mi;
532 struct minstrel_rate_stats *rate;
533 bool last = false;
534 int i = 0;
535 u16 report_ampdu_packets = 0;
536 unsigned long period;
537 host_event = (struct cfg_host_event *)skb->data;
538 report_data = (struct firmware_rate_control_report_data *)&host_event->dat[0];
539 if(host_event->h_event == SOC_EVT_RC_AMPDU_REPORT) {
540 #if 0
541 printk("SC HT AMPDU wsid[%d]ampdu_len[%d]ampdu_ack_len[%d]\n",report_data->wsid,report_data->ampdu_len,report_data->ampdu_ack_len);
542 for (i = 0; i < SSV62XX_TX_MAX_RATES ; i++) {
543 if(report_data->rates[i].data_rate == -1)
544 break;
545 if(report_data->rates[i].count == 0) {
546 printk("*********************************\n");
547 printk(" Illegal HT report \n");
548 printk("*********************************\n");
549 }
550 printk(" i=[%d] rate[%d] count[%d]\n",i,report_data->rates[i].data_rate,report_data->rates[i].count);
551 }
552 #endif
553 report_ampdu_packets = 1;
554 }
555 else if(host_event->h_event == SOC_EVT_RC_MPDU_REPORT) {
556 report_data->ampdu_len = 1;
557 report_ampdu_packets = report_data->ampdu_len;
558 #if 0
559 printk("SC MPDU wsid[%d]ampdu_len[%d]ampdu_ack_len[%d]\n",report_data->wsid,report_data->ampdu_len,report_data->ampdu_ack_len);
560 for (i = 0; i < SSV62XX_TX_MAX_RATES ; i++) {
561 if(report_data->rates[i].data_rate == -1)
562 break;
563 if(report_data->rates[i].count == 0) {
564 printk("*********************************\n");
565 printk(" Illegal MPDU report \n");
566 printk("*********************************\n");
567 }
568 printk(" i=[%d] rate[%d] count[%d]\n",i,report_data->rates[i].data_rate,report_data->rates[i].count);
569 }
570 #endif
571 }
572 else
573 {
574 printk("RC work get garbage!!\n");
575 return;
576 }
577 mi = &rc_sta->ht;
578 mi->ampdu_packets += report_ampdu_packets;
579 mi->ampdu_len += report_data->ampdu_len;
580 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
581 mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
582 mi->sample_tries = 2;
583 mi->sample_count--;
584 }
585 for (i = 0; !last; i++) {
586 last = (i == SSV62XX_TX_MAX_RATES - 1) ||
587 !minstrel_ht_txstat_valid(&report_data->rates[i+1]);
588 if (!minstrel_ht_txstat_valid(&report_data->rates[i]))
589 break;
590 #ifdef RATE_CONTROL_DEBUG
591 if((report_data->rates[i].data_rate < SSV62XX_RATE_MCS_INDEX) || (report_data->rates[i].data_rate >= SSV62XX_RATE_MCS_GREENFIELD_INDEX)) {
592 printk("[RC]ssv6xxx_ht_report_handler get error report rate[%d]\n",report_data->rates[i].data_rate);
593 break;
594 }
595 #endif
596 rate = &mi->groups.rates[(report_data->rates[i].data_rate - SSV62XX_RATE_MCS_INDEX) % MCS_GROUP_RATES];
597 if (last)
598 rate->success += report_data->ampdu_ack_len;
599 rate->attempts += report_data->rates[i].count * report_data->ampdu_len;
600 }
601 #if 0
602 rate = minstrel_get_ratestats(mi, mi->max_tp_rate);
603 if (rate->attempts > 30 &&
604 MINSTREL_FRAC(rate->success, rate->attempts) <
605 MINSTREL_FRAC(20, 100))
606 minstrel_downgrade_rate(mi, &mi->max_tp_rate, true);
607 rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate2);
608 if (rate2->attempts > 30 &&
609 MINSTREL_FRAC(rate2->success, rate2->attempts) <
610 MINSTREL_FRAC(20, 100))
611 minstrel_downgrade_rate(mi, &mi->max_tp_rate2, false);
612 #endif
613 period = msecs_to_jiffies(SSV_RC_HT_INTERVAL/2);
614 if (time_after(jiffies, mi->stats_update + period)) {
615 rate_control_ht_sample(mi,rc_sta);
616 }
617 #if 0
618 period = msecs_to_jiffies(HT_RC_UPDATE_INTERVAL);
619 if (time_after(jiffies, mi->stats_update + period)) {
620 struct rc_pid_sta_info *spinfo;
621 spinfo = &rc_sta->spinfo;
622 #if 1
623 printk("AMPDU rate update time!!\n");
624 #endif
625 if(rc_sta->rc_num_rate == 12)
626 {
627 if(spinfo->txrate_idx >= 4)
628 rc_sta->ht.max_tp_rate = spinfo->txrate_idx - 4;
629 else
630 rc_sta->ht.max_tp_rate = 0;
631 }
632 else
633 rc_sta->ht.max_tp_rate = spinfo->txrate_idx;
634 mi->stats_update = jiffies;
635 }
636 #endif
637 }
638