xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/ssv6xxx/smac/ssv_ht_rc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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