Changeset 35566


Ignore:
Timestamp:
2013-02-11T19:59:14+01:00 (5 years ago)
Author:
nbd
Message:

mac80211: add CCK rate support to minstrel_ht to improve range

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/package/mac80211/patches/300-pending_work.patch

    r35264 r35566  
    26382638 { 
    26392639        struct ath_hw *ah = sc->sc_ah; 
     2640--- a/net/mac80211/rc80211_minstrel.c 
     2641+++ b/net/mac80211/rc80211_minstrel.c 
     2642@@ -494,6 +494,33 @@ minstrel_free_sta(void *priv, struct iee 
     2643        kfree(mi); 
     2644 } 
     2645  
     2646+static void 
     2647+minstrel_init_cck_rates(struct minstrel_priv *mp) 
     2648+{ 
     2649+       static const int bitrates[4] = { 10, 20, 55, 110 }; 
     2650+       struct ieee80211_supported_band *sband; 
     2651+       int i, j; 
     2652+ 
     2653+       sband = mp->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; 
     2654+       if (!sband) 
     2655+               return; 
     2656+ 
     2657+       for (i = 0, j = 0; i < sband->n_bitrates; i++) { 
     2658+               struct ieee80211_rate *rate = &sband->bitrates[i]; 
     2659+ 
     2660+               if (rate->flags & IEEE80211_RATE_ERP_G) 
     2661+                       continue; 
     2662+ 
     2663+               for (j = 0; j < ARRAY_SIZE(bitrates); j++) { 
     2664+                       if (rate->bitrate != bitrates[j]) 
     2665+                               continue; 
     2666+ 
     2667+                       mp->cck_rates[j] = i; 
     2668+                       break; 
     2669+               } 
     2670+       } 
     2671+} 
     2672+ 
     2673 static void * 
     2674 minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 
     2675 { 
     2676@@ -539,6 +566,8 @@ minstrel_alloc(struct ieee80211_hw *hw,  
     2677                        S_IRUGO | S_IWUGO, debugfsdir, &mp->fixed_rate_idx); 
     2678 #endif 
     2679  
     2680+       minstrel_init_cck_rates(mp); 
     2681+ 
     2682        return mp; 
     2683 } 
     2684  
     2685--- a/net/mac80211/rc80211_minstrel.h 
     2686+++ b/net/mac80211/rc80211_minstrel.h 
     2687@@ -79,6 +79,8 @@ struct minstrel_priv { 
     2688        unsigned int lookaround_rate; 
     2689        unsigned int lookaround_rate_mrr; 
     2690  
     2691+       u8 cck_rates[4]; 
     2692+ 
     2693 #ifdef CONFIG_MAC80211_DEBUGFS 
     2694        /* 
     2695         * enable fixed rate processing per RC 
     2696--- a/net/mac80211/rc80211_minstrel_ht.c 
     2697+++ b/net/mac80211/rc80211_minstrel_ht.c 
     2698@@ -1,5 +1,5 @@ 
     2699 /* 
     2700- * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org> 
     2701+ * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org> 
     2702  * 
     2703  * This program is free software; you can redistribute it and/or modify 
     2704  * it under the terms of the GNU General Public License version 2 as 
     2705@@ -63,6 +63,30 @@ 
     2706        }                                                               \ 
     2707 } 
     2708  
     2709+#define CCK_DURATION(_bitrate, _short, _len)           \ 
     2710+       (10 /* SIFS */ +                                \ 
     2711+        (_short ? 72 + 24 : 144 + 48 ) +               \ 
     2712+        (8 * (_len + 4) * 10) / (_bitrate)) 
     2713+ 
     2714+#define CCK_ACK_DURATION(_bitrate, _short)                     \ 
     2715+       (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) +   \ 
     2716+        CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE)) 
     2717+ 
     2718+#define CCK_DURATION_LIST(_short)                      \ 
     2719+       CCK_ACK_DURATION(10, _short),                   \ 
     2720+       CCK_ACK_DURATION(20, _short),                   \ 
     2721+       CCK_ACK_DURATION(55, _short),                   \ 
     2722+       CCK_ACK_DURATION(110, _short) 
     2723+ 
     2724+#define CCK_GROUP                                      \ 
     2725+       {                                               \ 
     2726+               .streams = 0,                           \ 
     2727+               .duration = {                           \ 
     2728+                       CCK_DURATION_LIST(false),       \ 
     2729+                       CCK_DURATION_LIST(true)         \ 
     2730+               }                                       \ 
     2731+       } 
     2732+ 
     2733 /* 
     2734  * To enable sufficiently targeted rate sampling, MCS rates are divided into 
     2735  * groups, based on the number of streams and flags (HT40, SGI) that they 
     2736@@ -95,8 +119,13 @@ const struct mcs_group minstrel_mcs_grou 
     2737 #if MINSTREL_MAX_STREAMS >= 3 
     2738        MCS_GROUP(3, 1, 1), 
     2739 #endif 
     2740+ 
     2741+       /* must be last */ 
     2742+       CCK_GROUP 
     2743 }; 
     2744  
     2745+#define MINSTREL_CCK_GROUP     (ARRAY_SIZE(minstrel_mcs_groups) - 1) 
     2746+ 
     2747 static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES]; 
     2748  
     2749 /* 
     2750@@ -119,6 +148,29 @@ minstrel_ht_get_group_idx(struct ieee802 
     2751                         !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); 
     2752 } 
     2753  
     2754+struct minstrel_rate_stats * 
     2755+minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, 
     2756+                     struct ieee80211_tx_rate *rate) 
     2757+{ 
     2758+       int group, idx; 
     2759+ 
     2760+       if (rate->flags & IEEE80211_TX_RC_MCS) { 
     2761+               group = minstrel_ht_get_group_idx(rate); 
     2762+               idx = rate->idx % MCS_GROUP_RATES; 
     2763+       } else { 
     2764+               group = MINSTREL_CCK_GROUP; 
     2765+ 
     2766+               for (idx = 0; idx <= ARRAY_SIZE(mp->cck_rates); idx++) 
     2767+                       if (rate->idx == mp->cck_rates[idx]) 
     2768+                               break; 
     2769+ 
     2770+               /* short preamble */ 
     2771+               if (!(mi->groups[group].supported & BIT(idx))) 
     2772+                       idx += 4; 
     2773+       } 
     2774+       return &mi->groups[group].rates[idx]; 
     2775+} 
     2776+ 
     2777 static inline struct minstrel_rate_stats * 
     2778 minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index) 
     2779 { 
     2780@@ -159,7 +211,7 @@ static void 
     2781 minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) 
     2782 { 
     2783        struct minstrel_rate_stats *mr; 
     2784-       unsigned int usecs; 
     2785+       unsigned int usecs = 0; 
     2786  
     2787        mr = &mi->groups[group].rates[rate]; 
     2788  
     2789@@ -168,7 +220,9 @@ minstrel_ht_calc_tp(struct minstrel_ht_s 
     2790                return; 
     2791        } 
     2792  
     2793-       usecs = mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); 
     2794+       if (group != MINSTREL_CCK_GROUP) 
     2795+               usecs = mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); 
     2796+ 
     2797        usecs += minstrel_mcs_groups[group].duration[rate]; 
     2798        mr->cur_tp = MINSTREL_TRUNC((1000000 / usecs) * mr->probability); 
     2799 } 
     2800@@ -231,10 +285,6 @@ minstrel_ht_update_stats(struct minstrel 
     2801                        if (!mr->cur_tp) 
     2802                                continue; 
     2803  
     2804-                       /* ignore the lowest rate of each single-stream group */ 
     2805-                       if (!i && minstrel_mcs_groups[group].streams == 1) 
     2806-                               continue; 
     2807- 
     2808                        if ((mr->cur_tp > cur_prob_tp && mr->probability > 
     2809                             MINSTREL_FRAC(3, 4)) || mr->probability > cur_prob) { 
     2810                                mg->max_prob_rate = index; 
     2811@@ -297,7 +347,7 @@ minstrel_ht_update_stats(struct minstrel 
     2812 } 
     2813  
     2814 static bool 
     2815-minstrel_ht_txstat_valid(struct ieee80211_tx_rate *rate) 
     2816+minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct ieee80211_tx_rate *rate) 
     2817 { 
     2818        if (rate->idx < 0) 
     2819                return false; 
     2820@@ -305,7 +355,13 @@ minstrel_ht_txstat_valid(struct ieee8021 
     2821        if (!rate->count) 
     2822                return false; 
     2823  
     2824-       return !!(rate->flags & IEEE80211_TX_RC_MCS); 
     2825+       if (rate->flags & IEEE80211_TX_RC_MCS); 
     2826+               return true; 
     2827+ 
     2828+       return rate->idx == mp->cck_rates[0] || 
     2829+              rate->idx == mp->cck_rates[1] || 
     2830+              rate->idx == mp->cck_rates[2] || 
     2831+              rate->idx == mp->cck_rates[3]; 
     2832 } 
     2833  
     2834 static void 
     2835@@ -390,7 +446,6 @@ minstrel_ht_tx_status(void *priv, struct 
     2836        struct minstrel_rate_stats *rate, *rate2; 
     2837        struct minstrel_priv *mp = priv; 
     2838        bool last; 
     2839-       int group; 
     2840        int i; 
     2841  
     2842        if (!msp->is_ht) 
     2843@@ -419,13 +474,12 @@ minstrel_ht_tx_status(void *priv, struct 
     2844        if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) 
     2845                mi->sample_packets += info->status.ampdu_len; 
     2846  
     2847-       last = !minstrel_ht_txstat_valid(&ar[0]); 
     2848+       last = !minstrel_ht_txstat_valid(mp, &ar[0]); 
     2849        for (i = 0; !last; i++) { 
     2850                last = (i == IEEE80211_TX_MAX_RATES - 1) || 
     2851-                      !minstrel_ht_txstat_valid(&ar[i + 1]); 
     2852+                      !minstrel_ht_txstat_valid(mp, &ar[i + 1]); 
     2853  
     2854-               group = minstrel_ht_get_group_idx(&ar[i]); 
     2855-               rate = &mi->groups[group].rates[ar[i].idx % 8]; 
     2856+               rate = minstrel_ht_get_stats(mp, mi, &ar[i]); 
     2857  
     2858                if (last) 
     2859                        rate->success += info->status.ampdu_ack_len; 
     2860@@ -451,7 +505,8 @@ minstrel_ht_tx_status(void *priv, struct 
     2861  
     2862        if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { 
     2863                minstrel_ht_update_stats(mp, mi); 
     2864-               if (!(info->flags & IEEE80211_TX_CTL_AMPDU)) 
     2865+               if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && 
     2866+                   mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) 
     2867                        minstrel_aggr_check(sta, skb); 
     2868        } 
     2869 } 
     2870@@ -467,6 +522,7 @@ minstrel_calc_retransmit(struct minstrel 
     2871        unsigned int ctime = 0; 
     2872        unsigned int t_slot = 9; /* FIXME */ 
     2873        unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); 
     2874+       unsigned int overhead = 0, overhead_rtscts = 0; 
     2875  
     2876        mr = minstrel_get_ratestats(mi, index); 
     2877        if (mr->probability < MINSTREL_FRAC(1, 10)) { 
     2878@@ -488,9 +544,14 @@ minstrel_calc_retransmit(struct minstrel 
     2879        ctime += (t_slot * cw) >> 1; 
     2880        cw = min((cw << 1) | 1, mp->cw_max); 
     2881  
     2882+       if (index / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) { 
     2883+               overhead = mi->overhead; 
     2884+               overhead_rtscts = mi->overhead_rtscts; 
     2885+       } 
     2886+ 
     2887        /* Total TX time for data and Contention after first 2 tries */ 
     2888-       tx_time = ctime + 2 * (mi->overhead + tx_time_data); 
     2889-       tx_time_rtscts = ctime + 2 * (mi->overhead_rtscts + tx_time_data); 
     2890+       tx_time = ctime + 2 * (overhead + tx_time_data); 
     2891+       tx_time_rtscts = ctime + 2 * (overhead_rtscts + tx_time_data); 
     2892  
     2893        /* See how many more tries we can fit inside segment size */ 
     2894        do { 
     2895@@ -499,8 +560,8 @@ minstrel_calc_retransmit(struct minstrel 
     2896                cw = min((cw << 1) | 1, mp->cw_max); 
     2897  
     2898                /* Total TX time after this try */ 
     2899-               tx_time += ctime + mi->overhead + tx_time_data; 
     2900-               tx_time_rtscts += ctime + mi->overhead_rtscts + tx_time_data; 
     2901+               tx_time += ctime + overhead + tx_time_data; 
     2902+               tx_time_rtscts += ctime + overhead_rtscts + tx_time_data; 
     2903  
     2904                if (tx_time_rtscts < mp->segment_size) 
     2905                        mr->retry_count_rtscts++; 
     2906@@ -530,9 +591,16 @@ minstrel_ht_set_rate(struct minstrel_pri 
     2907        else 
     2908                rate->count = mr->retry_count; 
     2909  
     2910-       rate->flags = IEEE80211_TX_RC_MCS | group->flags; 
     2911+       rate->flags = 0; 
     2912        if (rtscts) 
     2913                rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; 
     2914+ 
     2915+       if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { 
     2916+               rate->idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; 
     2917+               return; 
     2918+       } 
     2919+ 
     2920+       rate->flags |= IEEE80211_TX_RC_MCS | group->flags; 
     2921        rate->idx = index % MCS_GROUP_RATES + (group->streams - 1) * MCS_GROUP_RATES; 
     2922 } 
     2923  
     2924@@ -596,6 +664,22 @@ minstrel_get_sample_rate(struct minstrel 
     2925 } 
     2926  
     2927 static void 
     2928+minstrel_ht_check_cck_shortpreamble(struct minstrel_priv *mp, 
     2929+                                   struct minstrel_ht_sta *mi, bool val) 
     2930+{ 
     2931+       u8 supported = mi->groups[MINSTREL_CCK_GROUP].supported; 
     2932+ 
     2933+       if (!supported || !mi->cck_supported_short) 
     2934+               return; 
     2935+ 
     2936+       if (supported & (mi->cck_supported_short << (val * 4))) 
     2937+               return; 
     2938+ 
     2939+       supported ^= mi->cck_supported_short | (mi->cck_supported_short << 4); 
     2940+       mi->groups[MINSTREL_CCK_GROUP].supported = supported; 
     2941+} 
     2942+ 
     2943+static void 
     2944 minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, 
     2945                      struct ieee80211_tx_rate_control *txrc) 
     2946 { 
     2947@@ -614,6 +698,7 @@ minstrel_ht_get_rate(void *priv, struct  
     2948                return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc); 
     2949  
     2950        info->flags |= mi->tx_flags; 
     2951+       minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble); 
     2952  
     2953        /* Don't use EAPOL frames for sampling on non-mrr hw */ 
     2954        if (mp->hw->max_rates == 1 && 
     2955@@ -687,6 +772,30 @@ minstrel_ht_get_rate(void *priv, struct  
     2956 } 
     2957  
     2958 static void 
     2959+minstrel_ht_update_cck(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, 
     2960+                      struct ieee80211_supported_band *sband, 
     2961+                      struct ieee80211_sta *sta) 
     2962+{ 
     2963+       int i; 
     2964+ 
     2965+       if (sband->band != IEEE80211_BAND_2GHZ) 
     2966+               return; 
     2967+ 
     2968+       mi->cck_supported = 0; 
     2969+       mi->cck_supported_short = 0; 
     2970+       for (i = 0; i < 4; i++) { 
     2971+               if (!rate_supported(sta, sband->band, mp->cck_rates[i])) 
     2972+                       continue; 
     2973+ 
     2974+               mi->cck_supported |= BIT(i); 
     2975+               if (sband->bitrates[i].flags & IEEE80211_RATE_SHORT_PREAMBLE) 
     2976+                       mi->cck_supported_short |= BIT(i); 
     2977+       } 
     2978+ 
     2979+       mi->groups[MINSTREL_CCK_GROUP].supported = mi->cck_supported; 
     2980+} 
     2981+ 
     2982+static void 
     2983 minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, 
     2984                         struct ieee80211_sta *sta, void *priv_sta) 
     2985 { 
     2986@@ -706,7 +815,7 @@ minstrel_ht_update_caps(void *priv, stru 
     2987                goto use_legacy; 
     2988  
     2989        BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != 
     2990-               MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS); 
     2991+               MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1); 
     2992  
     2993        msp->is_ht = true; 
     2994        memset(mi, 0, sizeof(*mi)); 
     2995@@ -742,6 +851,11 @@ minstrel_ht_update_caps(void *priv, stru 
     2996                u16 req = 0; 
     2997  
     2998                mi->groups[i].supported = 0; 
     2999+               if (i == MINSTREL_CCK_GROUP) { 
     3000+                       minstrel_ht_update_cck(mp, mi, sband, sta); 
     3001+                       continue; 
     3002+               } 
     3003+ 
     3004                if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_SHORT_GI) { 
     3005                        if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 
     3006                                req |= IEEE80211_HT_CAP_SGI_40; 
     3007--- a/net/mac80211/rc80211_minstrel_ht.h 
     3008+++ b/net/mac80211/rc80211_minstrel_ht.h 
     3009@@ -107,8 +107,11 @@ struct minstrel_ht_sta { 
     3010        /* current MCS group to be sampled */ 
     3011        u8 sample_group; 
     3012  
     3013+       u8 cck_supported; 
     3014+       u8 cck_supported_short; 
     3015+ 
     3016        /* MCS rate group info and statistics */ 
     3017-       struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS]; 
     3018+       struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1]; 
     3019 }; 
     3020  
     3021 struct minstrel_ht_sta_priv { 
     3022--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c 
     3023+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c 
     3024@@ -15,13 +15,76 @@ 
     3025 #include "rc80211_minstrel.h" 
     3026 #include "rc80211_minstrel_ht.h" 
     3027  
     3028+static char * 
     3029+minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) 
     3030+{ 
     3031+       unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; 
     3032+       const struct mcs_group *mg; 
     3033+       unsigned int j, tp, prob, eprob; 
     3034+       char htmode = '2'; 
     3035+       char gimode = 'L'; 
     3036+ 
     3037+       if (!mi->groups[i].supported) 
     3038+               return p; 
     3039+ 
     3040+       mg = &minstrel_mcs_groups[i]; 
     3041+       if (mg->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 
     3042+               htmode = '4'; 
     3043+       if (mg->flags & IEEE80211_TX_RC_SHORT_GI) 
     3044+               gimode = 'S'; 
     3045+ 
     3046+       for (j = 0; j < MCS_GROUP_RATES; j++) { 
     3047+               struct minstrel_rate_stats *mr = &mi->groups[i].rates[j]; 
     3048+               static const int bitrates[4] = { 10, 20, 55, 110 }; 
     3049+               int idx = i * MCS_GROUP_RATES + j; 
     3050+ 
     3051+               if (!(mi->groups[i].supported & BIT(j))) 
     3052+                       continue; 
     3053+ 
     3054+               if (i == max_mcs) 
     3055+                       p += sprintf(p, "CCK/%cP   ", j < 4 ? 'L' : 'S'); 
     3056+               else 
     3057+                       p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); 
     3058+ 
     3059+               *(p++) = (idx == mi->max_tp_rate) ? 'T' : ' '; 
     3060+               *(p++) = (idx == mi->max_tp_rate2) ? 't' : ' '; 
     3061+               *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; 
     3062+ 
     3063+               if (i == max_mcs) { 
     3064+                       int r = bitrates[j % 4]; 
     3065+                       p += sprintf(p, " %2u.%1uM", r / 10, r % 10); 
     3066+               } else { 
     3067+                       p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 
     3068+                                        MCS_GROUP_RATES + j); 
     3069+               } 
     3070+ 
     3071+               tp = mr->cur_tp / 10; 
     3072+               prob = MINSTREL_TRUNC(mr->cur_prob * 1000); 
     3073+               eprob = MINSTREL_TRUNC(mr->probability * 1000); 
     3074+ 
     3075+               p += sprintf(p, "      %6u.%1u   %6u.%1u    %6u.%1u    " 
     3076+                               "%3u            %3u(%3u)  %8llu    %8llu\n", 
     3077+                               tp / 10, tp % 10, 
     3078+                               eprob / 10, eprob % 10, 
     3079+                               prob / 10, prob % 10, 
     3080+                               mr->retry_count, 
     3081+                               mr->last_success, 
     3082+                               mr->last_attempts, 
     3083+                               (unsigned long long)mr->succ_hist, 
     3084+                               (unsigned long long)mr->att_hist); 
     3085+       } 
     3086+ 
     3087+       return p; 
     3088+} 
     3089+ 
     3090 static int 
     3091 minstrel_ht_stats_open(struct inode *inode, struct file *file) 
     3092 { 
     3093        struct minstrel_ht_sta_priv *msp = inode->i_private; 
     3094        struct minstrel_ht_sta *mi = &msp->ht; 
     3095        struct minstrel_debugfs_info *ms; 
     3096-       unsigned int i, j, tp, prob, eprob; 
     3097+       unsigned int i; 
     3098+       unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; 
     3099        char *p; 
     3100        int ret; 
     3101  
     3102@@ -38,50 +101,13 @@ minstrel_ht_stats_open(struct inode *ino 
     3103  
     3104        file->private_data = ms; 
     3105        p = ms->buf; 
     3106-       p += sprintf(p, "type      rate     throughput  ewma prob   this prob  " 
     3107-                       "this succ/attempt   success    attempts\n"); 
     3108-       for (i = 0; i < MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; i++) { 
     3109-               char htmode = '2'; 
     3110-               char gimode = 'L'; 
     3111- 
     3112-               if (!mi->groups[i].supported) 
     3113-                       continue; 
     3114- 
     3115-               if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 
     3116-                       htmode = '4'; 
     3117-               if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_SHORT_GI) 
     3118-                       gimode = 'S'; 
     3119- 
     3120-               for (j = 0; j < MCS_GROUP_RATES; j++) { 
     3121-                       struct minstrel_rate_stats *mr = &mi->groups[i].rates[j]; 
     3122-                       int idx = i * MCS_GROUP_RATES + j; 
     3123+       p += sprintf(p, "type         rate     throughput  ewma prob   this prob  " 
     3124+                       "retry   this succ/attempt   success    attempts\n"); 
     3125  
     3126-                       if (!(mi->groups[i].supported & BIT(j))) 
     3127-                               continue; 
     3128+       p = minstrel_ht_stats_dump(mi, max_mcs, p); 
     3129+       for (i = 0; i < max_mcs; i++) 
     3130+               p = minstrel_ht_stats_dump(mi, i, p); 
     3131  
     3132-                       p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); 
     3133- 
     3134-                       *(p++) = (idx == mi->max_tp_rate) ? 'T' : ' '; 
     3135-                       *(p++) = (idx == mi->max_tp_rate2) ? 't' : ' '; 
     3136-                       *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; 
     3137-                       p += sprintf(p, "MCS%-2u", (minstrel_mcs_groups[i].streams - 1) * 
     3138-                                       MCS_GROUP_RATES + j); 
     3139- 
     3140-                       tp = mr->cur_tp / 10; 
     3141-                       prob = MINSTREL_TRUNC(mr->cur_prob * 1000); 
     3142-                       eprob = MINSTREL_TRUNC(mr->probability * 1000); 
     3143- 
     3144-                       p += sprintf(p, "  %6u.%1u   %6u.%1u   %6u.%1u        " 
     3145-                                       "%3u(%3u)   %8llu    %8llu\n", 
     3146-                                       tp / 10, tp % 10, 
     3147-                                       eprob / 10, eprob % 10, 
     3148-                                       prob / 10, prob % 10, 
     3149-                                       mr->last_success, 
     3150-                                       mr->last_attempts, 
     3151-                                       (unsigned long long)mr->succ_hist, 
     3152-                                       (unsigned long long)mr->att_hist); 
     3153-               } 
     3154-       } 
     3155        p += sprintf(p, "\nTotal packet count::    ideal %d      " 
     3156                        "lookaround %d\n", 
     3157                        max(0, (int) mi->total_packets - (int) mi->sample_packets), 
Note: See TracChangeset for help on using the changeset viewer.