~ubuntu-branches/ubuntu/hardy/linux-backports-modules-2.6.24/hardy-security

« back to all changes in this revision

Viewing changes to updates/wireless/iwlwifi/iwlwifi/origin/iwl-4965-rs.c

  • Committer: Bazaar Package Importer
  • Author(s): , Ben Collins
  • Date: 2008-04-02 06:59:04 UTC
  • Revision ID: james.westby@ubuntu.com-20080402065904-e5knh2gn2hms3xbb
Tags: 2.6.24-14.11
[Ben Collins]

* iwlwifi: Update to iwlwifi-1.2.25 and mac80211-10.0.4
  - LP: #200950
* ubuntu: Slight cleanups to module hiearchy and Makefiles
* mac80211: Enable LED triggers
* iwlwifi: Add LED trigger support (rx and tx only)
  - LP: #176090

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 *
 
3
 * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify it
 
6
 * under the terms of version 2 of the GNU General Public License as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but WITHOUT
 
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
12
 * more details.
 
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
 
19
 * file called LICENSE.
 
20
 *
 
21
 * Contact Information:
 
22
 * James P. Ketrenos <ipw2100-admin@linux.intel.com>
 
23
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
24
 *
 
25
 *****************************************************************************/
 
26
#include <linux/kernel.h>
 
27
#include <linux/init.h>
 
28
#include <linux/skbuff.h>
 
29
#include <linux/wireless.h>
 
30
#include <net/mac80211.h>
 
31
#include <net/ieee80211.h>
 
32
 
 
33
#include <linux/netdevice.h>
 
34
#include <linux/etherdevice.h>
 
35
#include <linux/delay.h>
 
36
 
 
37
#include <linux/workqueue.h>
 
38
 
 
39
#include <net/mac80211.h>
 
40
#include <linux/wireless.h>
 
41
 
 
42
#include "../net/mac80211/ieee80211_rate.h"
 
43
 
 
44
#include "iwl-4965.h"
 
45
#include "iwl-helpers.h"
 
46
 
 
47
#define RS_NAME "iwl-4965-rs"
 
48
 
 
49
#define NUM_TRY_BEFORE_ANTENNA_TOGGLE 1
 
50
#define IWL_NUMBER_TRY      1
 
51
#define IWL_HT_NUMBER_TRY   3
 
52
 
 
53
#define IWL_RATE_MAX_WINDOW             62      /* # tx in history window */
 
54
#define IWL_RATE_MIN_FAILURE_TH         6       /* min failures to calc tpt */
 
55
#define IWL_RATE_MIN_SUCCESS_TH         8       /* min successes to calc tpt */
 
56
 
 
57
/* max time to accum history 2 seconds */
 
58
#define IWL_RATE_SCALE_FLUSH_INTVL   (2*HZ)
 
59
 
 
60
static u8 rs_ht_to_legacy[] = {
 
61
        IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
 
62
        IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
 
63
        IWL_RATE_6M_INDEX,
 
64
        IWL_RATE_6M_INDEX, IWL_RATE_9M_INDEX,
 
65
        IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX,
 
66
        IWL_RATE_24M_INDEX, IWL_RATE_36M_INDEX,
 
67
        IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX
 
68
};
 
69
 
 
70
struct iwl4965_rate {
 
71
        u32 rate_n_flags;
 
72
} __attribute__ ((packed));
 
73
 
 
74
/**
 
75
 * struct iwl4965_rate_scale_data -- tx success history for one rate
 
76
 */
 
77
struct iwl4965_rate_scale_data {
 
78
        u64 data;               /* bitmap of successful frames */
 
79
        s32 success_counter;    /* number of frames successful */
 
80
        s32 success_ratio;      /* per-cent * 128  */
 
81
        s32 counter;            /* number of frames attempted */
 
82
        s32 average_tpt;        /* success ratio * expected throughput */
 
83
        unsigned long stamp;
 
84
};
 
85
 
 
86
/**
 
87
 * struct iwl4965_scale_tbl_info -- tx params and success history for all rates
 
88
 *
 
89
 * There are two of these in struct iwl_rate_scale_priv,
 
90
 * one for "active", and one for "search".
 
91
 */
 
92
struct iwl4965_scale_tbl_info {
 
93
        enum iwl4965_table_type lq_type;
 
94
        enum iwl4965_antenna_type antenna_type;
 
95
        u8 is_SGI;      /* 1 = short guard interval */
 
96
        u8 is_fat;      /* 1 = 40 MHz channel width */
 
97
        u8 is_dup;      /* 1 = duplicated data streams */
 
98
        u8 action;      /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
 
99
        s32 *expected_tpt;      /* throughput metrics; expected_tpt_G, etc. */
 
100
        struct iwl4965_rate current_rate;  /* rate_n_flags, uCode API format */
 
101
        struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
 
102
};
 
103
 
 
104
/**
 
105
 * struct iwl_rate_scale_priv -- driver's rate scaling private structure
 
106
 *
 
107
 * Pointer to this gets passed back and forth between driver and mac80211.
 
108
 */
 
109
struct iwl4965_lq_sta {
 
110
        u8 active_tbl;          /* index of active table, range 0-1 */
 
111
        u8 enable_counter;      /* indicates HT mode */
 
112
        u8 stay_in_tbl;         /* 1: disallow, 0: allow search for new mode */
 
113
        u8 search_better_tbl;   /* 1: currently trying alternate mode */
 
114
        s32 last_tpt;
 
115
 
 
116
        /* The following determine when to search for a new mode */
 
117
        u32 table_count_limit;
 
118
        u32 max_failure_limit;  /* # failed frames before new search */
 
119
        u32 max_success_limit;  /* # successful frames before new search */
 
120
        u32 table_count;
 
121
        u32 total_failed;       /* total failed frames, any/all rates */
 
122
        u32 total_success;      /* total successful frames, any/all rates */
 
123
        u32 flush_timer;        /* time staying in mode before new search */
 
124
 
 
125
        u8 action_counter;      /* # mode-switch actions tried */
 
126
        u8 antenna;
 
127
        u8 valid_antenna;
 
128
        u8 is_green;
 
129
        u8 is_dup;
 
130
        u8 phymode;
 
131
        u8 ibss_sta_added;
 
132
 
 
133
        /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
 
134
        u32 supp_rates;
 
135
        u16 active_rate;
 
136
        u16 active_siso_rate;
 
137
        u16 active_mimo_rate;
 
138
        u16 active_rate_basic;
 
139
 
 
140
        struct iwl4965_link_quality_cmd lq;
 
141
        struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
 
142
#ifdef CONFIG_MAC80211_DEBUGFS
 
143
        struct dentry *rs_sta_dbgfs_scale_table_file;
 
144
        struct dentry *rs_sta_dbgfs_stats_table_file;
 
145
        struct iwl4965_rate dbg_fixed;
 
146
        struct iwl4965_priv *drv;
 
147
#endif
 
148
};
 
149
 
 
150
static void rs_rate_scale_perform(struct iwl4965_priv *priv,
 
151
                                   struct net_device *dev,
 
152
                                   struct ieee80211_hdr *hdr,
 
153
                                   struct sta_info *sta);
 
154
static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
 
155
                             struct iwl4965_rate *tx_mcs,
 
156
                             struct iwl4965_link_quality_cmd *tbl);
 
157
 
 
158
 
 
159
#ifdef CONFIG_MAC80211_DEBUGFS
 
160
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
 
161
                                struct iwl4965_rate *mcs, int index);
 
162
#else
 
163
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
 
164
                                struct iwl4965_rate *mcs, int index)
 
165
{}
 
166
#endif
 
167
 
 
168
/*
 
169
 * Expected throughput metrics for following rates:
 
170
 * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
 
171
 * "G" is the only table that supports CCK (the first 4 rates).
 
172
 */
 
173
static s32 expected_tpt_A[IWL_RATE_COUNT] = {
 
174
        0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
 
175
};
 
176
 
 
177
static s32 expected_tpt_G[IWL_RATE_COUNT] = {
 
178
        7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 186
 
179
};
 
180
 
 
181
static s32 expected_tpt_siso20MHz[IWL_RATE_COUNT] = {
 
182
        0, 0, 0, 0, 42, 42, 76, 102, 124, 159, 183, 193, 202
 
183
};
 
184
 
 
185
static s32 expected_tpt_siso20MHzSGI[IWL_RATE_COUNT] = {
 
186
        0, 0, 0, 0, 46, 46, 82, 110, 132, 168, 192, 202, 211
 
187
};
 
188
 
 
189
static s32 expected_tpt_mimo20MHz[IWL_RATE_COUNT] = {
 
190
        0, 0, 0, 0, 74, 74, 123, 155, 179, 214, 236, 244, 251
 
191
};
 
192
 
 
193
static s32 expected_tpt_mimo20MHzSGI[IWL_RATE_COUNT] = {
 
194
        0, 0, 0, 0, 81, 81, 131, 164, 188, 222, 243, 251, 257
 
195
};
 
196
 
 
197
static s32 expected_tpt_siso40MHz[IWL_RATE_COUNT] = {
 
198
        0, 0, 0, 0, 77, 77, 127, 160, 184, 220, 242, 250, 257
 
199
};
 
200
 
 
201
static s32 expected_tpt_siso40MHzSGI[IWL_RATE_COUNT] = {
 
202
        0, 0, 0, 0, 83, 83, 135, 169, 193, 229, 250, 257, 264
 
203
};
 
204
 
 
205
static s32 expected_tpt_mimo40MHz[IWL_RATE_COUNT] = {
 
206
        0, 0, 0, 0, 123, 123, 182, 214, 235, 264, 279, 285, 289
 
207
};
 
208
 
 
209
static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = {
 
210
        0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293
 
211
};
 
212
 
 
213
static int iwl4965_lq_sync_callback(struct iwl4965_priv *priv,
 
214
                                struct iwl4965_cmd *cmd, struct sk_buff *skb)
 
215
{
 
216
        /*We didn't cache the SKB; let the caller free it */
 
217
        return 1;
 
218
}
 
219
 
 
220
static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags)
 
221
{
 
222
        return (u8)(rate_n_flags & 0xFF);
 
223
}
 
224
 
 
225
static int rs_send_lq_cmd(struct iwl4965_priv *priv,
 
226
                          struct iwl4965_link_quality_cmd *lq, u8 flags)
 
227
{
 
228
#ifdef CONFIG_IWL4965_DEBUG
 
229
        int i;
 
230
#endif
 
231
        struct iwl4965_host_cmd cmd = {
 
232
                .id = REPLY_TX_LINK_QUALITY_CMD,
 
233
                .len = sizeof(struct iwl4965_link_quality_cmd),
 
234
                .meta.flags = flags,
 
235
                .data = lq,
 
236
        };
 
237
 
 
238
        if ((lq->sta_id == 0xFF) &&
 
239
            (priv->iw_mode == IEEE80211_IF_TYPE_IBSS))
 
240
                return -EINVAL;
 
241
 
 
242
        if (lq->sta_id == 0xFF)
 
243
                lq->sta_id = IWL_AP_ID;
 
244
 
 
245
        IWL_DEBUG_RATE("lq station id 0x%x\n", lq->sta_id);
 
246
        IWL_DEBUG_RATE("lq dta 0x%X 0x%X\n",
 
247
                       lq->general_params.single_stream_ant_msk,
 
248
                       lq->general_params.dual_stream_ant_msk);
 
249
#ifdef CONFIG_IWL4965_DEBUG
 
250
        for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
 
251
                IWL_DEBUG_RATE("lq index %d 0x%X\n",
 
252
                                i, lq->rs_table[i].rate_n_flags);
 
253
#endif
 
254
 
 
255
        if (flags & CMD_ASYNC)
 
256
                cmd.meta.u.callback = iwl4965_lq_sync_callback;
 
257
 
 
258
        if (iwl4965_is_associated(priv) && priv->assoc_station_added &&
 
259
            priv->lq_mngr.lq_ready)
 
260
                return  iwl4965_send_cmd(priv, &cmd);
 
261
 
 
262
        return 0;
 
263
}
 
264
 
 
265
static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
 
266
{
 
267
        window->data = 0;
 
268
        window->success_counter = 0;
 
269
        window->success_ratio = IWL_INVALID_VALUE;
 
270
        window->counter = 0;
 
271
        window->average_tpt = IWL_INVALID_VALUE;
 
272
        window->stamp = 0;
 
273
}
 
274
 
 
275
/**
 
276
 * rs_collect_tx_data - Update the success/failure sliding window
 
277
 *
 
278
 * We keep a sliding window of the last 62 packets transmitted
 
279
 * at this rate.  window->data contains the bitmask of successful
 
280
 * packets.
 
281
 */
 
282
static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
 
283
                              int scale_index, s32 tpt, u32 status)
 
284
{
 
285
        struct iwl4965_rate_scale_data *window = NULL;
 
286
        u64 mask;
 
287
        u8 win_size = IWL_RATE_MAX_WINDOW;
 
288
        s32 fail_count;
 
289
 
 
290
        if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
 
291
                return -EINVAL;
 
292
 
 
293
        /* Select data for current tx bit rate */
 
294
        window = &(windows[scale_index]);
 
295
 
 
296
        /*
 
297
         * Keep track of only the latest 62 tx frame attempts in this rate's
 
298
         * history window; anything older isn't really relevant any more.
 
299
         * If we have filled up the sliding window, drop the oldest attempt;
 
300
         * if the oldest attempt (highest bit in bitmap) shows "success",
 
301
         * subtract "1" from the success counter (this is the main reason
 
302
         * we keep these bitmaps!).
 
303
         */
 
304
        if (window->counter >= win_size) {
 
305
                window->counter = win_size - 1;
 
306
                mask = 1;
 
307
                mask = (mask << (win_size - 1));
 
308
                if ((window->data & mask)) {
 
309
                        window->data &= ~mask;
 
310
                        window->success_counter = window->success_counter - 1;
 
311
                }
 
312
        }
 
313
 
 
314
        /* Increment frames-attempted counter */
 
315
        window->counter = window->counter + 1;
 
316
 
 
317
        /* Shift bitmap by one frame (throw away oldest history),
 
318
         * OR in "1", and increment "success" if this frame was successful. */
 
319
        mask = window->data;
 
320
        window->data = (mask << 1);
 
321
        if (status != 0) {
 
322
                window->success_counter = window->success_counter + 1;
 
323
                window->data |= 0x1;
 
324
        }
 
325
 
 
326
        /* Calculate current success ratio, avoid divide-by-0! */
 
327
        if (window->counter > 0)
 
328
                window->success_ratio = 128 * (100 * window->success_counter)
 
329
                                        / window->counter;
 
330
        else
 
331
                window->success_ratio = IWL_INVALID_VALUE;
 
332
 
 
333
        fail_count = window->counter - window->success_counter;
 
334
 
 
335
        /* Calculate average throughput, if we have enough history. */
 
336
        if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
 
337
            (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
 
338
                window->average_tpt = (window->success_ratio * tpt + 64) / 128;
 
339
        else
 
340
                window->average_tpt = IWL_INVALID_VALUE;
 
341
 
 
342
        /* Tag this window as having been updated */
 
343
        window->stamp = jiffies;
 
344
 
 
345
        return 0;
 
346
}
 
347
 
 
348
/*
 
349
 * Fill uCode API rate_n_flags field, based on "search" or "active" table.
 
350
 */
 
351
static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate,
 
352
                           struct iwl4965_scale_tbl_info *tbl,
 
353
                           int index, u8 use_green)
 
354
{
 
355
        if (is_legacy(tbl->lq_type)) {
 
356
                mcs_rate->rate_n_flags = iwl4965_rates[index].plcp;
 
357
                if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
 
358
                        mcs_rate->rate_n_flags |= RATE_MCS_CCK_MSK;
 
359
 
 
360
        } else if (is_siso(tbl->lq_type)) {
 
361
                if (index > IWL_LAST_OFDM_RATE)
 
362
                        index = IWL_LAST_OFDM_RATE;
 
363
                 mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_siso |
 
364
                                          RATE_MCS_HT_MSK;
 
365
        } else {
 
366
                if (index > IWL_LAST_OFDM_RATE)
 
367
                        index = IWL_LAST_OFDM_RATE;
 
368
                mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_mimo |
 
369
                                         RATE_MCS_HT_MSK;
 
370
        }
 
371
 
 
372
        switch (tbl->antenna_type) {
 
373
        case ANT_BOTH:
 
374
                mcs_rate->rate_n_flags |= RATE_MCS_ANT_AB_MSK;
 
375
                break;
 
376
        case ANT_MAIN:
 
377
                mcs_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK;
 
378
                break;
 
379
        case ANT_AUX:
 
380
                mcs_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK;
 
381
                break;
 
382
        case ANT_NONE:
 
383
                break;
 
384
        }
 
385
 
 
386
        if (is_legacy(tbl->lq_type))
 
387
                return;
 
388
 
 
389
        if (tbl->is_fat) {
 
390
                if (tbl->is_dup)
 
391
                        mcs_rate->rate_n_flags |= RATE_MCS_DUP_MSK;
 
392
                else
 
393
                        mcs_rate->rate_n_flags |= RATE_MCS_FAT_MSK;
 
394
        }
 
395
        if (tbl->is_SGI)
 
396
                mcs_rate->rate_n_flags |= RATE_MCS_SGI_MSK;
 
397
 
 
398
        if (use_green) {
 
399
                mcs_rate->rate_n_flags |= RATE_MCS_GF_MSK;
 
400
                if (is_siso(tbl->lq_type))
 
401
                        mcs_rate->rate_n_flags &= ~RATE_MCS_SGI_MSK;
 
402
        }
 
403
}
 
404
 
 
405
/*
 
406
 * Interpret uCode API's rate_n_flags format,
 
407
 * fill "search" or "active" tx mode table.
 
408
 */
 
409
static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
 
410
                                    int phymode, struct iwl4965_scale_tbl_info *tbl,
 
411
                                    int *rate_idx)
 
412
{
 
413
        int index;
 
414
        u32 ant_msk;
 
415
 
 
416
        index = iwl4965_rate_index_from_plcp(mcs_rate->rate_n_flags);
 
417
 
 
418
        if (index  == IWL_RATE_INVALID) {
 
419
                *rate_idx = -1;
 
420
                return -EINVAL;
 
421
        }
 
422
        tbl->is_SGI = 0;        /* default legacy setup */
 
423
        tbl->is_fat = 0;
 
424
        tbl->is_dup = 0;
 
425
        tbl->antenna_type = ANT_BOTH;   /* default MIMO setup */
 
426
 
 
427
        /* legacy rate format */
 
428
        if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) {
 
429
                ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK);
 
430
 
 
431
                if (ant_msk == RATE_MCS_ANT_AB_MSK)
 
432
                        tbl->lq_type = LQ_NONE;
 
433
                else {
 
434
 
 
435
                        if (phymode == MODE_IEEE80211A)
 
436
                                tbl->lq_type = LQ_A;
 
437
                        else
 
438
                                tbl->lq_type = LQ_G;
 
439
 
 
440
                        if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK)
 
441
                                tbl->antenna_type = ANT_MAIN;
 
442
                        else
 
443
                                tbl->antenna_type = ANT_AUX;
 
444
                }
 
445
                *rate_idx = index;
 
446
 
 
447
        /* HT rate format, SISO (might be 20 MHz legacy or 40 MHz fat width) */
 
448
        } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags)
 
449
                                        <= IWL_RATE_SISO_60M_PLCP) {
 
450
                tbl->lq_type = LQ_SISO;
 
451
 
 
452
                ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK);
 
453
                if (ant_msk == RATE_MCS_ANT_AB_MSK)
 
454
                        tbl->lq_type = LQ_NONE;
 
455
                else {
 
456
                        if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK)
 
457
                                tbl->antenna_type = ANT_MAIN;
 
458
                        else
 
459
                                tbl->antenna_type = ANT_AUX;
 
460
                }
 
461
                if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK)
 
462
                        tbl->is_SGI = 1;
 
463
 
 
464
                if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) ||
 
465
                    (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK))
 
466
                        tbl->is_fat = 1;
 
467
 
 
468
                if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)
 
469
                        tbl->is_dup = 1;
 
470
 
 
471
                *rate_idx = index;
 
472
 
 
473
        /* HT rate format, MIMO (might be 20 MHz legacy or 40 MHz fat width) */
 
474
        } else {
 
475
                tbl->lq_type = LQ_MIMO;
 
476
                if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK)
 
477
                        tbl->is_SGI = 1;
 
478
 
 
479
                if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) ||
 
480
                    (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK))
 
481
                        tbl->is_fat = 1;
 
482
 
 
483
                if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)
 
484
                        tbl->is_dup = 1;
 
485
                *rate_idx = index;
 
486
        }
 
487
        return 0;
 
488
}
 
489
 
 
490
static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate,
 
491
                                     struct iwl4965_scale_tbl_info *tbl)
 
492
{
 
493
        if (tbl->antenna_type == ANT_AUX) {
 
494
                tbl->antenna_type = ANT_MAIN;
 
495
                new_rate->rate_n_flags &= ~RATE_MCS_ANT_B_MSK;
 
496
                new_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK;
 
497
        } else {
 
498
                tbl->antenna_type = ANT_AUX;
 
499
                new_rate->rate_n_flags &= ~RATE_MCS_ANT_A_MSK;
 
500
                new_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK;
 
501
        }
 
502
}
 
503
 
 
504
static inline u8 rs_use_green(struct iwl4965_priv *priv)
 
505
{
 
506
#ifdef CONFIG_IWL4965_HT
 
507
        if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht)
 
508
                return 0;
 
509
 
 
510
        return ((priv->current_assoc_ht.is_green_field) &&
 
511
            !(priv->current_assoc_ht.operating_mode & 0x4));
 
512
#endif  /*CONFIG_IWL4965_HT */
 
513
        return 0;
 
514
}
 
515
 
 
516
/**
 
517
 * rs_get_supported_rates - get the available rates
 
518
 *
 
519
 * if management frame or broadcast frame only return
 
520
 * basic available rates.
 
521
 *
 
522
 */
 
523
static void rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
 
524
                                   struct ieee80211_hdr *hdr,
 
525
                                   enum iwl4965_table_type rate_type,
 
526
                                   u16 *data_rate)
 
527
{
 
528
        if (is_legacy(rate_type))
 
529
                *data_rate = lq_sta->active_rate;
 
530
        else {
 
531
                if (is_siso(rate_type))
 
532
                        *data_rate = lq_sta->active_siso_rate;
 
533
                else
 
534
                        *data_rate = lq_sta->active_mimo_rate;
 
535
        }
 
536
 
 
537
        if (hdr && is_multicast_ether_addr(hdr->addr1) &&
 
538
            lq_sta->active_rate_basic) {
 
539
                *data_rate = lq_sta->active_rate_basic;
 
540
        }
 
541
}
 
542
 
 
543
static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
 
544
{
 
545
        u8 high = IWL_RATE_INVALID;
 
546
        u8 low = IWL_RATE_INVALID;
 
547
 
 
548
        /* 802.11A or ht walks to the next literal adjacent rate in
 
549
         * the rate table */
 
550
        if (is_a_band(rate_type) || !is_legacy(rate_type)) {
 
551
                int i;
 
552
                u32 mask;
 
553
 
 
554
                /* Find the previous rate that is in the rate mask */
 
555
                i = index - 1;
 
556
                for (mask = (1 << i); i >= 0; i--, mask >>= 1) {
 
557
                        if (rate_mask & mask) {
 
558
                                low = i;
 
559
                                break;
 
560
                        }
 
561
                }
 
562
 
 
563
                /* Find the next rate that is in the rate mask */
 
564
                i = index + 1;
 
565
                for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
 
566
                        if (rate_mask & mask) {
 
567
                                high = i;
 
568
                                break;
 
569
                        }
 
570
                }
 
571
 
 
572
                return (high << 8) | low;
 
573
        }
 
574
 
 
575
        low = index;
 
576
        while (low != IWL_RATE_INVALID) {
 
577
                low = iwl4965_rates[low].prev_rs;
 
578
                if (low == IWL_RATE_INVALID)
 
579
                        break;
 
580
                if (rate_mask & (1 << low))
 
581
                        break;
 
582
                IWL_DEBUG_RATE("Skipping masked lower rate: %d\n", low);
 
583
        }
 
584
 
 
585
        high = index;
 
586
        while (high != IWL_RATE_INVALID) {
 
587
                high = iwl4965_rates[high].next_rs;
 
588
                if (high == IWL_RATE_INVALID)
 
589
                        break;
 
590
                if (rate_mask & (1 << high))
 
591
                        break;
 
592
                IWL_DEBUG_RATE("Skipping masked higher rate: %d\n", high);
 
593
        }
 
594
 
 
595
        return (high << 8) | low;
 
596
}
 
597
 
 
598
static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
 
599
                             struct iwl4965_scale_tbl_info *tbl, u8 scale_index,
 
600
                             u8 ht_possible, struct iwl4965_rate *mcs_rate)
 
601
{
 
602
        s32 low;
 
603
        u16 rate_mask;
 
604
        u16 high_low;
 
605
        u8 switch_to_legacy = 0;
 
606
        u8 is_green = lq_sta->is_green;
 
607
 
 
608
        /* check if we need to switch from HT to legacy rates.
 
609
         * assumption is that mandatory rates (1Mbps or 6Mbps)
 
610
         * are always supported (spec demand) */
 
611
        if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) {
 
612
                switch_to_legacy = 1;
 
613
                scale_index = rs_ht_to_legacy[scale_index];
 
614
                if (lq_sta->phymode == MODE_IEEE80211A)
 
615
                        tbl->lq_type = LQ_A;
 
616
                else
 
617
                        tbl->lq_type = LQ_G;
 
618
 
 
619
                if ((tbl->antenna_type == ANT_BOTH) ||
 
620
                    (tbl->antenna_type == ANT_NONE))
 
621
                        tbl->antenna_type = ANT_MAIN;
 
622
 
 
623
                tbl->is_fat = 0;
 
624
                tbl->is_SGI = 0;
 
625
        }
 
626
 
 
627
        rs_get_supported_rates(lq_sta, NULL, tbl->lq_type, &rate_mask);
 
628
 
 
629
        /* Mask with station rate restriction */
 
630
        if (is_legacy(tbl->lq_type)) {
 
631
                /* supp_rates has no CCK bits in A mode */
 
632
                if (lq_sta->phymode == (u8) MODE_IEEE80211A)
 
633
                        rate_mask  = (u16)(rate_mask &
 
634
                           (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
 
635
                else
 
636
                        rate_mask = (u16)(rate_mask & lq_sta->supp_rates);
 
637
        }
 
638
 
 
639
        /* If we switched from HT to legacy, check current rate */
 
640
        if (switch_to_legacy && (rate_mask & (1 << scale_index))) {
 
641
                rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
 
642
                return;
 
643
        }
 
644
 
 
645
        high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type);
 
646
        low = high_low & 0xff;
 
647
 
 
648
        if (low != IWL_RATE_INVALID)
 
649
                rs_mcs_from_tbl(mcs_rate, tbl, low, is_green);
 
650
        else
 
651
                rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
 
652
}
 
653
 
 
654
/*
 
655
 * mac80211 sends us Tx status
 
656
 */
 
657
static void rs_tx_status(void *priv_rate, struct net_device *dev,
 
658
                         struct sk_buff *skb,
 
659
                         struct iwlwifi_ieee80211_tx_status *tx_resp)
 
660
{
 
661
        int status;
 
662
        u8 retries;
 
663
        int rs_index, index = 0;
 
664
        struct iwl4965_lq_sta *lq_sta;
 
665
        struct iwl4965_link_quality_cmd *table;
 
666
        struct sta_info *sta;
 
667
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
668
        struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate;
 
669
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
670
        struct iwl4965_rate_scale_data *window = NULL;
 
671
        struct iwl4965_rate_scale_data *search_win = NULL;
 
672
        struct iwl4965_rate tx_mcs;
 
673
        struct iwl4965_scale_tbl_info tbl_type;
 
674
        struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;
 
675
        u8 active_index = 0;
 
676
        u16 fc = le16_to_cpu(hdr->frame_control);
 
677
        s32 tpt = 0;
 
678
 
 
679
        IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
 
680
 
 
681
        if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
 
682
                return;
 
683
 
 
684
        retries = tx_resp->retry_count;
 
685
 
 
686
        if (retries > 15)
 
687
                retries = 15;
 
688
 
 
689
 
 
690
        sta = iwlwifi_sta_info_get(local, hdr->addr1);
 
691
 
 
692
        if (!sta || !sta->rate_ctrl_priv) {
 
693
                if (sta)
 
694
                        iwlwifi_sta_info_put(sta);
 
695
                return;
 
696
        }
 
697
 
 
698
        lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
 
699
 
 
700
        if (!priv->lq_mngr.lq_ready)
 
701
                return;
 
702
 
 
703
        if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
 
704
            !lq_sta->ibss_sta_added)
 
705
                return;
 
706
 
 
707
        table = &lq_sta->lq;
 
708
        active_index = lq_sta->active_tbl;
 
709
 
 
710
        /* Get mac80211 antenna info */
 
711
        lq_sta->antenna =
 
712
                (lq_sta->valid_antenna & local->hw.conf.antenna_sel_tx);
 
713
        if (!lq_sta->antenna)
 
714
                lq_sta->antenna = lq_sta->valid_antenna;
 
715
 
 
716
        /* Ignore mac80211 antenna info for now */
 
717
        lq_sta->antenna = lq_sta->valid_antenna;
 
718
 
 
719
        curr_tbl = &(lq_sta->lq_info[active_index]);
 
720
        search_tbl = &(lq_sta->lq_info[(1 - active_index)]);
 
721
        window = (struct iwl4965_rate_scale_data *)
 
722
            &(curr_tbl->win[0]);
 
723
        search_win = (struct iwl4965_rate_scale_data *)
 
724
            &(search_tbl->win[0]);
 
725
 
 
726
        tx_mcs.rate_n_flags = tx_resp->control.tx_rate;
 
727
 
 
728
        rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
 
729
                                  &tbl_type, &rs_index);
 
730
        if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) {
 
731
                IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n",
 
732
                             rs_index, tx_mcs.rate_n_flags);
 
733
                iwlwifi_sta_info_put(sta);
 
734
                return;
 
735
        }
 
736
 
 
737
        /*
 
738
         * Ignore this Tx frame response if its initial rate doesn't match
 
739
         * that of latest Link Quality command.  There may be stragglers
 
740
         * from a previous Link Quality command, but we're no longer interested
 
741
         * in those; they're either from the "active" mode while we're trying
 
742
         * to check "search" mode, or a prior "search" mode after we've moved
 
743
         * to a new "search" mode (which might become the new "active" mode).
 
744
         */
 
745
        if (retries &&
 
746
            (tx_mcs.rate_n_flags !=
 
747
                                le32_to_cpu(table->rs_table[0].rate_n_flags))) {
 
748
                IWL_DEBUG_RATE("initial rate does not match 0x%x 0x%x\n",
 
749
                                tx_mcs.rate_n_flags,
 
750
                                le32_to_cpu(table->rs_table[0].rate_n_flags));
 
751
                iwlwifi_sta_info_put(sta);
 
752
                return;
 
753
        }
 
754
 
 
755
        /* Update frame history window with "failure" for each Tx retry. */
 
756
        while (retries) {
 
757
                /* Look up the rate and other info used for each tx attempt.
 
758
                 * Each tx attempt steps one entry deeper in the rate table. */
 
759
                tx_mcs.rate_n_flags =
 
760
                    le32_to_cpu(table->rs_table[index].rate_n_flags);
 
761
                rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
 
762
                                          &tbl_type, &rs_index);
 
763
 
 
764
                /* If type matches "search" table,
 
765
                 * add failure to "search" history */
 
766
                if ((tbl_type.lq_type == search_tbl->lq_type) &&
 
767
                    (tbl_type.antenna_type == search_tbl->antenna_type) &&
 
768
                    (tbl_type.is_SGI == search_tbl->is_SGI)) {
 
769
                        if (search_tbl->expected_tpt)
 
770
                                tpt = search_tbl->expected_tpt[rs_index];
 
771
                        else
 
772
                                tpt = 0;
 
773
                        rs_collect_tx_data(search_win, rs_index, tpt, 0);
 
774
 
 
775
                /* Else if type matches "current/active" table,
 
776
                 * add failure to "current/active" history */
 
777
                } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
 
778
                           (tbl_type.antenna_type == curr_tbl->antenna_type) &&
 
779
                           (tbl_type.is_SGI == curr_tbl->is_SGI)) {
 
780
                        if (curr_tbl->expected_tpt)
 
781
                                tpt = curr_tbl->expected_tpt[rs_index];
 
782
                        else
 
783
                                tpt = 0;
 
784
                        rs_collect_tx_data(window, rs_index, tpt, 0);
 
785
                }
 
786
 
 
787
                /* If not searching for a new mode, increment failed counter
 
788
                 * ... this helps determine when to start searching again */
 
789
                if (lq_sta->stay_in_tbl)
 
790
                        lq_sta->total_failed++;
 
791
                --retries;
 
792
                index++;
 
793
 
 
794
        }
 
795
 
 
796
        /*
 
797
         * Find (by rate) the history window to update with final Tx attempt;
 
798
         * if Tx was successful first try, use original rate,
 
799
         * else look up the rate that was, finally, successful.
 
800
         */
 
801
        if (!tx_resp->retry_count)
 
802
                tx_mcs.rate_n_flags = tx_resp->control.tx_rate;
 
803
        else
 
804
                tx_mcs.rate_n_flags =
 
805
                        le32_to_cpu(table->rs_table[index].rate_n_flags);
 
806
 
 
807
        rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
 
808
                                  &tbl_type, &rs_index);
 
809
 
 
810
        /* Update frame history window with "success" if Tx got ACKed ... */
 
811
        if (tx_resp->flags & IEEE80211_TX_STATUS_ACK)
 
812
                status = 1;
 
813
        else
 
814
                status = 0;
 
815
 
 
816
        /* If type matches "search" table,
 
817
         * add final tx status to "search" history */
 
818
        if ((tbl_type.lq_type == search_tbl->lq_type) &&
 
819
            (tbl_type.antenna_type == search_tbl->antenna_type) &&
 
820
            (tbl_type.is_SGI == search_tbl->is_SGI)) {
 
821
                if (search_tbl->expected_tpt)
 
822
                        tpt = search_tbl->expected_tpt[rs_index];
 
823
                else
 
824
                        tpt = 0;
 
825
                rs_collect_tx_data(search_win,
 
826
                                    rs_index, tpt, status);
 
827
 
 
828
        /* Else if type matches "current/active" table,
 
829
         * add final tx status to "current/active" history */
 
830
        } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
 
831
                   (tbl_type.antenna_type == curr_tbl->antenna_type) &&
 
832
                   (tbl_type.is_SGI == curr_tbl->is_SGI)) {
 
833
                if (curr_tbl->expected_tpt)
 
834
                        tpt = curr_tbl->expected_tpt[rs_index];
 
835
                else
 
836
                        tpt = 0;
 
837
                rs_collect_tx_data(window, rs_index, tpt, status);
 
838
        }
 
839
 
 
840
        /* If not searching for new mode, increment success/failed counter
 
841
         * ... these help determine when to start searching again */
 
842
        if (lq_sta->stay_in_tbl) {
 
843
                if (status)
 
844
                        lq_sta->total_success++;
 
845
                else
 
846
                        lq_sta->total_failed++;
 
847
        }
 
848
 
 
849
        /* See if there's a better rate or modulation mode to try. */
 
850
        rs_rate_scale_perform(priv, dev, hdr, sta);
 
851
        iwlwifi_sta_info_put(sta);
 
852
        return;
 
853
}
 
854
 
 
855
static u8 rs_is_ant_connected(u8 valid_antenna,
 
856
                              enum iwl4965_antenna_type antenna_type)
 
857
{
 
858
        if (antenna_type == ANT_AUX)
 
859
                return ((valid_antenna & 0x2) ? 1:0);
 
860
        else if (antenna_type == ANT_MAIN)
 
861
                return ((valid_antenna & 0x1) ? 1:0);
 
862
        else if (antenna_type == ANT_BOTH)
 
863
                return ((valid_antenna & 0x3) == 0x3);
 
864
 
 
865
        return 1;
 
866
}
 
867
 
 
868
static u8 rs_is_other_ant_connected(u8 valid_antenna,
 
869
                                    enum iwl4965_antenna_type antenna_type)
 
870
{
 
871
        if (antenna_type == ANT_AUX)
 
872
                return rs_is_ant_connected(valid_antenna, ANT_MAIN);
 
873
        else
 
874
                return rs_is_ant_connected(valid_antenna, ANT_AUX);
 
875
 
 
876
        return 0;
 
877
}
 
878
 
 
879
/*
 
880
 * Begin a period of staying with a selected modulation mode.
 
881
 * Set "stay_in_tbl" flag to prevent any mode switches.
 
882
 * Set frame tx success limits according to legacy vs. high-throughput,
 
883
 * and reset overall (spanning all rates) tx success history statistics.
 
884
 * These control how long we stay using same modulation mode before
 
885
 * searching for a new mode.
 
886
 */
 
887
static void rs_set_stay_in_table(u8 is_legacy,
 
888
                                 struct iwl4965_lq_sta *lq_sta)
 
889
{
 
890
        IWL_DEBUG_HT("we are staying in the same table\n");
 
891
        lq_sta->stay_in_tbl = 1;        /* only place this gets set */
 
892
        if (is_legacy) {
 
893
                lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
 
894
                lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
 
895
                lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT;
 
896
        } else {
 
897
                lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT;
 
898
                lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT;
 
899
                lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT;
 
900
        }
 
901
        lq_sta->table_count = 0;
 
902
        lq_sta->total_failed = 0;
 
903
        lq_sta->total_success = 0;
 
904
}
 
905
 
 
906
/*
 
907
 * Find correct throughput table for given mode of modulation
 
908
 */
 
909
static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
 
910
                                      struct iwl4965_scale_tbl_info *tbl)
 
911
{
 
912
        if (is_legacy(tbl->lq_type)) {
 
913
                if (!is_a_band(tbl->lq_type))
 
914
                        tbl->expected_tpt = expected_tpt_G;
 
915
                else
 
916
                        tbl->expected_tpt = expected_tpt_A;
 
917
        } else if (is_siso(tbl->lq_type)) {
 
918
                if (tbl->is_fat && !lq_sta->is_dup)
 
919
                        if (tbl->is_SGI)
 
920
                                tbl->expected_tpt = expected_tpt_siso40MHzSGI;
 
921
                        else
 
922
                                tbl->expected_tpt = expected_tpt_siso40MHz;
 
923
                else if (tbl->is_SGI)
 
924
                        tbl->expected_tpt = expected_tpt_siso20MHzSGI;
 
925
                else
 
926
                        tbl->expected_tpt = expected_tpt_siso20MHz;
 
927
 
 
928
        } else if (is_mimo(tbl->lq_type)) {
 
929
                if (tbl->is_fat && !lq_sta->is_dup)
 
930
                        if (tbl->is_SGI)
 
931
                                tbl->expected_tpt = expected_tpt_mimo40MHzSGI;
 
932
                        else
 
933
                                tbl->expected_tpt = expected_tpt_mimo40MHz;
 
934
                else if (tbl->is_SGI)
 
935
                        tbl->expected_tpt = expected_tpt_mimo20MHzSGI;
 
936
                else
 
937
                        tbl->expected_tpt = expected_tpt_mimo20MHz;
 
938
        } else
 
939
                tbl->expected_tpt = expected_tpt_G;
 
940
}
 
941
 
 
942
#ifdef CONFIG_IWL4965_HT
 
943
/*
 
944
 * Find starting rate for new "search" high-throughput mode of modulation.
 
945
 * Goal is to find lowest expected rate (under perfect conditions) that is
 
946
 * above the current measured throughput of "active" mode, to give new mode
 
947
 * a fair chance to prove itself without too many challenges.
 
948
 *
 
949
 * This gets called when transitioning to more aggressive modulation
 
950
 * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive
 
951
 * (i.e. MIMO to SISO).  When moving to MIMO, bit rate will typically need
 
952
 * to decrease to match "active" throughput.  When moving from MIMO to SISO,
 
953
 * bit rate will typically need to increase, but not if performance was bad.
 
954
 */
 
955
static s32 rs_get_best_rate(struct iwl4965_priv *priv,
 
956
                            struct iwl4965_lq_sta *lq_sta,
 
957
                            struct iwl4965_scale_tbl_info *tbl, /* "search" */
 
958
                            u16 rate_mask, s8 index, s8 rate)
 
959
{
 
960
        /* "active" values */
 
961
        struct iwl4965_scale_tbl_info *active_tbl =
 
962
            &(lq_sta->lq_info[lq_sta->active_tbl]);
 
963
        s32 active_sr = active_tbl->win[index].success_ratio;
 
964
        s32 active_tpt = active_tbl->expected_tpt[index];
 
965
 
 
966
        /* expected "search" throughput */
 
967
        s32 *tpt_tbl = tbl->expected_tpt;
 
968
 
 
969
        s32 new_rate, high, low, start_hi;
 
970
        u16 high_low;
 
971
 
 
972
        new_rate = high = low = start_hi = IWL_RATE_INVALID;
 
973
 
 
974
        for (; ;) {
 
975
                high_low = rs_get_adjacent_rate(rate, rate_mask, tbl->lq_type);
 
976
 
 
977
                low = high_low & 0xff;
 
978
                high = (high_low >> 8) & 0xff;
 
979
 
 
980
                /*
 
981
                 * Lower the "search" bit rate, to give new "search" mode
 
982
                 * approximately the same throughput as "active" if:
 
983
                 *
 
984
                 * 1) "Active" mode has been working modestly well (but not
 
985
                 *    great), and expected "search" throughput (under perfect
 
986
                 *    conditions) at candidate rate is above the actual
 
987
                 *    measured "active" throughput (but less than expected
 
988
                 *    "active" throughput under perfect conditions).
 
989
                 * OR
 
990
                 * 2) "Active" mode has been working perfectly or very well
 
991
                 *    and expected "search" throughput (under perfect
 
992
                 *    conditions) at candidate rate is above expected
 
993
                 *    "active" throughput (under perfect conditions).
 
994
                 */
 
995
                if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&
 
996
                     ((active_sr > IWL_RATE_DECREASE_TH) &&
 
997
                      (active_sr <= IWL_RATE_HIGH_TH) &&
 
998
                      (tpt_tbl[rate] <= active_tpt))) ||
 
999
                    ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
 
1000
                     (tpt_tbl[rate] > active_tpt))) {
 
1001
 
 
1002
                        /* (2nd or later pass)
 
1003
                         * If we've already tried to raise the rate, and are
 
1004
                         * now trying to lower it, use the higher rate. */
 
1005
                        if (start_hi != IWL_RATE_INVALID) {
 
1006
                                new_rate = start_hi;
 
1007
                                break;
 
1008
                        }
 
1009
 
 
1010
                        new_rate = rate;
 
1011
 
 
1012
                        /* Loop again with lower rate */
 
1013
                        if (low != IWL_RATE_INVALID)
 
1014
                                rate = low;
 
1015
 
 
1016
                        /* Lower rate not available, use the original */
 
1017
                        else
 
1018
                                break;
 
1019
 
 
1020
                /* Else try to raise the "search" rate to match "active" */
 
1021
                } else {
 
1022
                        /* (2nd or later pass)
 
1023
                         * If we've already tried to lower the rate, and are
 
1024
                         * now trying to raise it, use the lower rate. */
 
1025
                        if (new_rate != IWL_RATE_INVALID)
 
1026
                                break;
 
1027
 
 
1028
                        /* Loop again with higher rate */
 
1029
                        else if (high != IWL_RATE_INVALID) {
 
1030
                                start_hi = high;
 
1031
                                rate = high;
 
1032
 
 
1033
                        /* Higher rate not available, use the original */
 
1034
                        } else {
 
1035
                                new_rate = rate;
 
1036
                                break;
 
1037
                        }
 
1038
                }
 
1039
        }
 
1040
 
 
1041
        return new_rate;
 
1042
}
 
1043
#endif                          /* CONFIG_IWL4965_HT */
 
1044
 
 
1045
static inline u8 rs_is_both_ant_supp(u8 valid_antenna)
 
1046
{
 
1047
        return (rs_is_ant_connected(valid_antenna, ANT_BOTH));
 
1048
}
 
1049
 
 
1050
/*
 
1051
 * Set up search table for MIMO
 
1052
 */
 
1053
static int rs_switch_to_mimo(struct iwl4965_priv *priv,
 
1054
                             struct iwl4965_lq_sta *lq_sta,
 
1055
                             struct iwl4965_scale_tbl_info *tbl, int index)
 
1056
{
 
1057
#ifdef CONFIG_IWL4965_HT
 
1058
        u16 rate_mask;
 
1059
        s32 rate;
 
1060
        s8 is_green = lq_sta->is_green;
 
1061
 
 
1062
        if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht)
 
1063
                return -1;
 
1064
 
 
1065
        IWL_DEBUG_HT("LQ: try to switch to MIMO\n");
 
1066
        tbl->lq_type = LQ_MIMO;
 
1067
        rs_get_supported_rates(lq_sta, NULL, tbl->lq_type,
 
1068
                                &rate_mask);
 
1069
 
 
1070
        if (priv->current_assoc_ht.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC)
 
1071
                return -1;
 
1072
 
 
1073
        /* Need both Tx chains/antennas to support MIMO */
 
1074
        if (!rs_is_both_ant_supp(lq_sta->antenna))
 
1075
                return -1;
 
1076
 
 
1077
        tbl->is_dup = lq_sta->is_dup;
 
1078
        tbl->action = 0;
 
1079
        if (priv->current_channel_width == IWL_CHANNEL_WIDTH_40MHZ)
 
1080
                tbl->is_fat = 1;
 
1081
        else
 
1082
                tbl->is_fat = 0;
 
1083
 
 
1084
        if (tbl->is_fat) {
 
1085
                if (priv->current_assoc_ht.sgf & HT_SHORT_GI_40MHZ_ONLY)
 
1086
                        tbl->is_SGI = 1;
 
1087
                else
 
1088
                        tbl->is_SGI = 0;
 
1089
        } else if (priv->current_assoc_ht.sgf & HT_SHORT_GI_20MHZ_ONLY)
 
1090
                tbl->is_SGI = 1;
 
1091
        else
 
1092
                tbl->is_SGI = 0;
 
1093
 
 
1094
        rs_get_expected_tpt_table(lq_sta, tbl);
 
1095
 
 
1096
        rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index);
 
1097
 
 
1098
        IWL_DEBUG_HT("LQ: MIMO best rate %d mask %X\n", rate, rate_mask);
 
1099
        if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask))
 
1100
                return -1;
 
1101
        rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green);
 
1102
 
 
1103
        IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
 
1104
                     tbl->current_rate.rate_n_flags, is_green);
 
1105
        return 0;
 
1106
#else
 
1107
        return -1;
 
1108
#endif                          /*CONFIG_IWL4965_HT */
 
1109
}
 
1110
 
 
1111
/*
 
1112
 * Set up search table for SISO
 
1113
 */
 
1114
static int rs_switch_to_siso(struct iwl4965_priv *priv,
 
1115
                             struct iwl4965_lq_sta *lq_sta,
 
1116
                             struct iwl4965_scale_tbl_info *tbl, int index)
 
1117
{
 
1118
#ifdef CONFIG_IWL4965_HT
 
1119
        s32 rate;
 
1120
        u16 rate_mask;
 
1121
        u8 is_green = lq_sta->is_green;
 
1122
 
 
1123
        IWL_DEBUG_HT("LQ: try to switch to SISO\n");
 
1124
        if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht)
 
1125
                return -1;
 
1126
 
 
1127
        tbl->is_dup = lq_sta->is_dup;
 
1128
        tbl->lq_type = LQ_SISO;
 
1129
        tbl->action = 0;
 
1130
        rs_get_supported_rates(lq_sta, NULL, tbl->lq_type,
 
1131
                                &rate_mask);
 
1132
 
 
1133
        if (priv->current_channel_width == IWL_CHANNEL_WIDTH_40MHZ)
 
1134
                tbl->is_fat = 1;
 
1135
        else
 
1136
                tbl->is_fat = 0;
 
1137
 
 
1138
        if (tbl->is_fat) {
 
1139
                if (priv->current_assoc_ht.sgf & HT_SHORT_GI_40MHZ_ONLY)
 
1140
                        tbl->is_SGI = 1;
 
1141
                else
 
1142
                        tbl->is_SGI = 0;
 
1143
        } else if (priv->current_assoc_ht.sgf & HT_SHORT_GI_20MHZ_ONLY) {
 
1144
                tbl->is_SGI = 1;
 
1145
        } else {
 
1146
                tbl->is_SGI = 0;
 
1147
        }
 
1148
 
 
1149
        if (is_green)
 
1150
                tbl->is_SGI = 0;
 
1151
 
 
1152
        rs_get_expected_tpt_table(lq_sta, tbl);
 
1153
        rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index);
 
1154
 
 
1155
        IWL_DEBUG_HT("LQ: get best rate %d mask %X\n", rate, rate_mask);
 
1156
        if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
 
1157
                IWL_DEBUG_HT("can not switch with index %d rate mask %x\n",
 
1158
                             rate, rate_mask);
 
1159
                return -1;
 
1160
        }
 
1161
        rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green);
 
1162
        IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
 
1163
                     tbl->current_rate.rate_n_flags, is_green);
 
1164
        return 0;
 
1165
#else
 
1166
        return -1;
 
1167
 
 
1168
#endif                          /*CONFIG_IWL4965_HT */
 
1169
}
 
1170
 
 
1171
/*
 
1172
 * Try to switch to new modulation mode from legacy
 
1173
 */
 
1174
static int rs_move_legacy_other(struct iwl4965_priv *priv,
 
1175
                                struct iwl4965_lq_sta *lq_sta,
 
1176
                                int index)
 
1177
{
 
1178
        int ret = 0;
 
1179
        struct iwl4965_scale_tbl_info *tbl =
 
1180
                &(lq_sta->lq_info[lq_sta->active_tbl]);
 
1181
        struct iwl4965_scale_tbl_info *search_tbl =
 
1182
                &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
 
1183
        struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
 
1184
        u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
 
1185
                  (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
 
1186
        u8 start_action = tbl->action;
 
1187
 
 
1188
        for (; ;) {
 
1189
                switch (tbl->action) {
 
1190
                case IWL_LEGACY_SWITCH_ANTENNA:
 
1191
                        IWL_DEBUG_HT("LQ Legacy switch Antenna\n");
 
1192
 
 
1193
                        search_tbl->lq_type = LQ_NONE;
 
1194
                        lq_sta->action_counter++;
 
1195
 
 
1196
                        /* Don't change antenna if success has been great */
 
1197
                        if (window->success_ratio >= IWL_RS_GOOD_RATIO)
 
1198
                                break;
 
1199
 
 
1200
                        /* Don't change antenna if other one is not connected */
 
1201
                        if (!rs_is_other_ant_connected(lq_sta->antenna,
 
1202
                                                        tbl->antenna_type))
 
1203
                                break;
 
1204
 
 
1205
                        /* Set up search table to try other antenna */
 
1206
                        memcpy(search_tbl, tbl, sz);
 
1207
 
 
1208
                        rs_toggle_antenna(&(search_tbl->current_rate),
 
1209
                                           search_tbl);
 
1210
                        rs_get_expected_tpt_table(lq_sta, search_tbl);
 
1211
                        lq_sta->search_better_tbl = 1;
 
1212
                        goto out;
 
1213
 
 
1214
                case IWL_LEGACY_SWITCH_SISO:
 
1215
                        IWL_DEBUG_HT("LQ: Legacy switch to SISO\n");
 
1216
 
 
1217
                        /* Set up search table to try SISO */
 
1218
                        memcpy(search_tbl, tbl, sz);
 
1219
                        search_tbl->lq_type = LQ_SISO;
 
1220
                        search_tbl->is_SGI = 0;
 
1221
                        search_tbl->is_fat = 0;
 
1222
                        ret = rs_switch_to_siso(priv, lq_sta, search_tbl,
 
1223
                                               index);
 
1224
                        if (!ret) {
 
1225
                                lq_sta->search_better_tbl = 1;
 
1226
                                lq_sta->action_counter = 0;
 
1227
                                goto out;
 
1228
                        }
 
1229
 
 
1230
                        break;
 
1231
                case IWL_LEGACY_SWITCH_MIMO:
 
1232
                        IWL_DEBUG_HT("LQ: Legacy switch MIMO\n");
 
1233
 
 
1234
                        /* Set up search table to try MIMO */
 
1235
                        memcpy(search_tbl, tbl, sz);
 
1236
                        search_tbl->lq_type = LQ_MIMO;
 
1237
                        search_tbl->is_SGI = 0;
 
1238
                        search_tbl->is_fat = 0;
 
1239
                        search_tbl->antenna_type = ANT_BOTH;
 
1240
                        ret = rs_switch_to_mimo(priv, lq_sta, search_tbl,
 
1241
                                               index);
 
1242
                        if (!ret) {
 
1243
                                lq_sta->search_better_tbl = 1;
 
1244
                                lq_sta->action_counter = 0;
 
1245
                                goto out;
 
1246
                        }
 
1247
                        break;
 
1248
                }
 
1249
                tbl->action++;
 
1250
                if (tbl->action > IWL_LEGACY_SWITCH_MIMO)
 
1251
                        tbl->action = IWL_LEGACY_SWITCH_ANTENNA;
 
1252
 
 
1253
                if (tbl->action == start_action)
 
1254
                        break;
 
1255
 
 
1256
        }
 
1257
        return 0;
 
1258
 
 
1259
 out:
 
1260
        tbl->action++;
 
1261
        if (tbl->action > IWL_LEGACY_SWITCH_MIMO)
 
1262
                tbl->action = IWL_LEGACY_SWITCH_ANTENNA;
 
1263
        return 0;
 
1264
 
 
1265
}
 
1266
 
 
1267
/*
 
1268
 * Try to switch to new modulation mode from SISO
 
1269
 */
 
1270
static int rs_move_siso_to_other(struct iwl4965_priv *priv,
 
1271
                                 struct iwl4965_lq_sta *lq_sta,
 
1272
                                 int index)
 
1273
{
 
1274
        int ret;
 
1275
        u8 is_green = lq_sta->is_green;
 
1276
        struct iwl4965_scale_tbl_info *tbl =
 
1277
            &(lq_sta->lq_info[lq_sta->active_tbl]);
 
1278
        struct iwl4965_scale_tbl_info *search_tbl =
 
1279
            &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
 
1280
        struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
 
1281
        u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
 
1282
                  (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
 
1283
        u8 start_action = tbl->action;
 
1284
 
 
1285
        for (;;) {
 
1286
                lq_sta->action_counter++;
 
1287
                switch (tbl->action) {
 
1288
                case IWL_SISO_SWITCH_ANTENNA:
 
1289
                        IWL_DEBUG_HT("LQ: SISO SWITCH ANTENNA SISO\n");
 
1290
                        search_tbl->lq_type = LQ_NONE;
 
1291
                        if (window->success_ratio >= IWL_RS_GOOD_RATIO)
 
1292
                                break;
 
1293
                        if (!rs_is_other_ant_connected(lq_sta->antenna,
 
1294
                                                       tbl->antenna_type))
 
1295
                                break;
 
1296
 
 
1297
                        memcpy(search_tbl, tbl, sz);
 
1298
                        search_tbl->action = IWL_SISO_SWITCH_MIMO;
 
1299
                        rs_toggle_antenna(&(search_tbl->current_rate),
 
1300
                                           search_tbl);
 
1301
                        lq_sta->search_better_tbl = 1;
 
1302
 
 
1303
                        goto out;
 
1304
 
 
1305
                case IWL_SISO_SWITCH_MIMO:
 
1306
                        IWL_DEBUG_HT("LQ: SISO SWITCH TO MIMO FROM SISO\n");
 
1307
                        memcpy(search_tbl, tbl, sz);
 
1308
                        search_tbl->lq_type = LQ_MIMO;
 
1309
                        search_tbl->is_SGI = 0;
 
1310
                        search_tbl->is_fat = 0;
 
1311
                        search_tbl->antenna_type = ANT_BOTH;
 
1312
                        ret = rs_switch_to_mimo(priv, lq_sta, search_tbl,
 
1313
                                               index);
 
1314
                        if (!ret) {
 
1315
                                lq_sta->search_better_tbl = 1;
 
1316
                                goto out;
 
1317
                        }
 
1318
                        break;
 
1319
                case IWL_SISO_SWITCH_GI:
 
1320
                        IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n");
 
1321
                        memcpy(search_tbl, tbl, sz);
 
1322
                        search_tbl->action = 0;
 
1323
                        if (search_tbl->is_SGI)
 
1324
                                search_tbl->is_SGI = 0;
 
1325
                        else if (!is_green)
 
1326
                                search_tbl->is_SGI = 1;
 
1327
                        else
 
1328
                                break;
 
1329
                        lq_sta->search_better_tbl = 1;
 
1330
                        if ((tbl->lq_type == LQ_SISO) &&
 
1331
                            (tbl->is_SGI)) {
 
1332
                                s32 tpt = lq_sta->last_tpt / 100;
 
1333
                                if (((!tbl->is_fat) &&
 
1334
                                     (tpt >= expected_tpt_siso20MHz[index])) ||
 
1335
                                    ((tbl->is_fat) &&
 
1336
                                     (tpt >= expected_tpt_siso40MHz[index])))
 
1337
                                        lq_sta->search_better_tbl = 0;
 
1338
                        }
 
1339
                        rs_get_expected_tpt_table(lq_sta, search_tbl);
 
1340
                        rs_mcs_from_tbl(&search_tbl->current_rate,
 
1341
                                             search_tbl, index, is_green);
 
1342
                        goto out;
 
1343
                }
 
1344
                tbl->action++;
 
1345
                if (tbl->action > IWL_SISO_SWITCH_GI)
 
1346
                        tbl->action = IWL_SISO_SWITCH_ANTENNA;
 
1347
 
 
1348
                if (tbl->action == start_action)
 
1349
                        break;
 
1350
        }
 
1351
        return 0;
 
1352
 
 
1353
 out:
 
1354
        tbl->action++;
 
1355
        if (tbl->action > IWL_SISO_SWITCH_GI)
 
1356
                tbl->action = IWL_SISO_SWITCH_ANTENNA;
 
1357
        return 0;
 
1358
}
 
1359
 
 
1360
/*
 
1361
 * Try to switch to new modulation mode from MIMO
 
1362
 */
 
1363
static int rs_move_mimo_to_other(struct iwl4965_priv *priv,
 
1364
                                 struct iwl4965_lq_sta *lq_sta,
 
1365
                                 int index)
 
1366
{
 
1367
        int ret;
 
1368
        s8 is_green = lq_sta->is_green;
 
1369
        struct iwl4965_scale_tbl_info *tbl =
 
1370
            &(lq_sta->lq_info[lq_sta->active_tbl]);
 
1371
        struct iwl4965_scale_tbl_info *search_tbl =
 
1372
            &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
 
1373
        u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
 
1374
                  (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
 
1375
        u8 start_action = tbl->action;
 
1376
 
 
1377
        for (;;) {
 
1378
                lq_sta->action_counter++;
 
1379
                switch (tbl->action) {
 
1380
                case IWL_MIMO_SWITCH_ANTENNA_A:
 
1381
                case IWL_MIMO_SWITCH_ANTENNA_B:
 
1382
                        IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n");
 
1383
 
 
1384
                        /* Set up new search table for SISO */
 
1385
                        memcpy(search_tbl, tbl, sz);
 
1386
                        search_tbl->lq_type = LQ_SISO;
 
1387
                        search_tbl->is_SGI = 0;
 
1388
                        search_tbl->is_fat = 0;
 
1389
                        if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A)
 
1390
                                search_tbl->antenna_type = ANT_MAIN;
 
1391
                        else
 
1392
                                search_tbl->antenna_type = ANT_AUX;
 
1393
 
 
1394
                        ret = rs_switch_to_siso(priv, lq_sta, search_tbl,
 
1395
                                               index);
 
1396
                        if (!ret) {
 
1397
                                lq_sta->search_better_tbl = 1;
 
1398
                                goto out;
 
1399
                        }
 
1400
                        break;
 
1401
 
 
1402
                case IWL_MIMO_SWITCH_GI:
 
1403
                        IWL_DEBUG_HT("LQ: MIMO SWITCH TO GI\n");
 
1404
 
 
1405
                        /* Set up new search table for MIMO */
 
1406
                        memcpy(search_tbl, tbl, sz);
 
1407
                        search_tbl->lq_type = LQ_MIMO;
 
1408
                        search_tbl->antenna_type = ANT_BOTH;
 
1409
                        search_tbl->action = 0;
 
1410
                        if (search_tbl->is_SGI)
 
1411
                                search_tbl->is_SGI = 0;
 
1412
                        else
 
1413
                                search_tbl->is_SGI = 1;
 
1414
                        lq_sta->search_better_tbl = 1;
 
1415
 
 
1416
                        /*
 
1417
                         * If active table already uses the fastest possible
 
1418
                         * modulation (dual stream with short guard interval),
 
1419
                         * and it's working well, there's no need to look
 
1420
                         * for a better type of modulation!
 
1421
                         */
 
1422
                        if ((tbl->lq_type == LQ_MIMO) &&
 
1423
                            (tbl->is_SGI)) {
 
1424
                                s32 tpt = lq_sta->last_tpt / 100;
 
1425
                                if (((!tbl->is_fat) &&
 
1426
                                     (tpt >= expected_tpt_mimo20MHz[index])) ||
 
1427
                                    ((tbl->is_fat) &&
 
1428
                                     (tpt >= expected_tpt_mimo40MHz[index])))
 
1429
                                        lq_sta->search_better_tbl = 0;
 
1430
                        }
 
1431
                        rs_get_expected_tpt_table(lq_sta, search_tbl);
 
1432
                        rs_mcs_from_tbl(&search_tbl->current_rate,
 
1433
                                             search_tbl, index, is_green);
 
1434
                        goto out;
 
1435
 
 
1436
                }
 
1437
                tbl->action++;
 
1438
                if (tbl->action > IWL_MIMO_SWITCH_GI)
 
1439
                        tbl->action = IWL_MIMO_SWITCH_ANTENNA_A;
 
1440
 
 
1441
                if (tbl->action == start_action)
 
1442
                        break;
 
1443
        }
 
1444
 
 
1445
        return 0;
 
1446
 out:
 
1447
        tbl->action++;
 
1448
        if (tbl->action > IWL_MIMO_SWITCH_GI)
 
1449
                tbl->action = IWL_MIMO_SWITCH_ANTENNA_A;
 
1450
        return 0;
 
1451
 
 
1452
}
 
1453
 
 
1454
/*
 
1455
 * Check whether we should continue using same modulation mode, or
 
1456
 * begin search for a new mode, based on:
 
1457
 * 1) # tx successes or failures while using this mode
 
1458
 * 2) # times calling this function
 
1459
 * 3) elapsed time in this mode (not used, for now)
 
1460
 */
 
1461
static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta)
 
1462
{
 
1463
        struct iwl4965_scale_tbl_info *tbl;
 
1464
        int i;
 
1465
        int active_tbl;
 
1466
        int flush_interval_passed = 0;
 
1467
 
 
1468
        active_tbl = lq_sta->active_tbl;
 
1469
 
 
1470
        tbl = &(lq_sta->lq_info[active_tbl]);
 
1471
 
 
1472
        /* If we've been disallowing search, see if we should now allow it */
 
1473
        if (lq_sta->stay_in_tbl) {
 
1474
 
 
1475
                /* Elapsed time using current modulation mode */
 
1476
                if (lq_sta->flush_timer)
 
1477
                        flush_interval_passed =
 
1478
                            time_after(jiffies,
 
1479
                                       (unsigned long)(lq_sta->flush_timer +
 
1480
                                        IWL_RATE_SCALE_FLUSH_INTVL));
 
1481
 
 
1482
                /* For now, disable the elapsed time criterion */
 
1483
                flush_interval_passed = 0;
 
1484
 
 
1485
                /*
 
1486
                 * Check if we should allow search for new modulation mode.
 
1487
                 * If many frames have failed or succeeded, or we've used
 
1488
                 * this same modulation for a long time, allow search, and
 
1489
                 * reset history stats that keep track of whether we should
 
1490
                 * allow a new search.  Also (below) reset all bitmaps and
 
1491
                 * stats in active history.
 
1492
                 */
 
1493
                if ((lq_sta->total_failed > lq_sta->max_failure_limit) ||
 
1494
                    (lq_sta->total_success > lq_sta->max_success_limit) ||
 
1495
                    ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
 
1496
                     && (flush_interval_passed))) {
 
1497
                        IWL_DEBUG_HT("LQ: stay is expired %d %d %d\n:",
 
1498
                                     lq_sta->total_failed,
 
1499
                                     lq_sta->total_success,
 
1500
                                     flush_interval_passed);
 
1501
 
 
1502
                        /* Allow search for new mode */
 
1503
                        lq_sta->stay_in_tbl = 0;        /* only place reset */
 
1504
                        lq_sta->total_failed = 0;
 
1505
                        lq_sta->total_success = 0;
 
1506
                        lq_sta->flush_timer = 0;
 
1507
 
 
1508
                /*
 
1509
                 * Else if we've used this modulation mode enough repetitions
 
1510
                 * (regardless of elapsed time or success/failure), reset
 
1511
                 * history bitmaps and rate-specific stats for all rates in
 
1512
                 * active table.
 
1513
                 */
 
1514
                } else {
 
1515
                        lq_sta->table_count++;
 
1516
                        if (lq_sta->table_count >=
 
1517
                            lq_sta->table_count_limit) {
 
1518
                                lq_sta->table_count = 0;
 
1519
 
 
1520
                                IWL_DEBUG_HT("LQ: stay in table clear win\n");
 
1521
                                for (i = 0; i < IWL_RATE_COUNT; i++)
 
1522
                                        rs_rate_scale_clear_window(
 
1523
                                                &(tbl->win[i]));
 
1524
                        }
 
1525
                }
 
1526
 
 
1527
                /* If transitioning to allow "search", reset all history
 
1528
                 * bitmaps and stats in active table (this will become the new
 
1529
                 * "search" table). */
 
1530
                if (!lq_sta->stay_in_tbl) {
 
1531
                        for (i = 0; i < IWL_RATE_COUNT; i++)
 
1532
                                rs_rate_scale_clear_window(&(tbl->win[i]));
 
1533
                }
 
1534
        }
 
1535
}
 
1536
 
 
1537
/*
 
1538
 * Do rate scaling and search for new modulation mode.
 
1539
 */
 
1540
static void rs_rate_scale_perform(struct iwl4965_priv *priv,
 
1541
                                  struct net_device *dev,
 
1542
                                  struct ieee80211_hdr *hdr,
 
1543
                                  struct sta_info *sta)
 
1544
{
 
1545
        int low = IWL_RATE_INVALID;
 
1546
        int high = IWL_RATE_INVALID;
 
1547
        int index;
 
1548
        int i;
 
1549
        struct iwl4965_rate_scale_data *window = NULL;
 
1550
        int current_tpt = IWL_INVALID_VALUE;
 
1551
        int low_tpt = IWL_INVALID_VALUE;
 
1552
        int high_tpt = IWL_INVALID_VALUE;
 
1553
        u32 fail_count;
 
1554
        s8 scale_action = 0;
 
1555
        u16 fc, rate_mask;
 
1556
        u8 update_lq = 0;
 
1557
        struct iwl4965_lq_sta *lq_sta;
 
1558
        struct iwl4965_scale_tbl_info *tbl, *tbl1;
 
1559
        u16 rate_scale_index_msk = 0;
 
1560
        struct iwl4965_rate mcs_rate;
 
1561
        u8 is_green = 0;
 
1562
        u8 active_tbl = 0;
 
1563
        u8 done_search = 0;
 
1564
        u16 high_low;
 
1565
 
 
1566
        IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
 
1567
 
 
1568
        fc = le16_to_cpu(hdr->frame_control);
 
1569
        if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
 
1570
                /* Send management frames and broadcast/multicast data using
 
1571
                 * lowest rate. */
 
1572
                /* TODO: this could probably be improved.. */
 
1573
                return;
 
1574
        }
 
1575
 
 
1576
        if (!sta || !sta->rate_ctrl_priv)
 
1577
                return;
 
1578
 
 
1579
        if (!priv->lq_mngr.lq_ready) {
 
1580
                IWL_DEBUG_RATE("still rate scaling not ready\n");
 
1581
                return;
 
1582
        }
 
1583
        lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
 
1584
 
 
1585
        /*
 
1586
         * Select rate-scale / modulation-mode table to work with in
 
1587
         * the rest of this function:  "search" if searching for better
 
1588
         * modulation mode, or "active" if doing rate scaling within a mode.
 
1589
         */
 
1590
        if (!lq_sta->search_better_tbl)
 
1591
                active_tbl = lq_sta->active_tbl;
 
1592
        else
 
1593
                active_tbl = 1 - lq_sta->active_tbl;
 
1594
 
 
1595
        tbl = &(lq_sta->lq_info[active_tbl]);
 
1596
        is_green = lq_sta->is_green;
 
1597
 
 
1598
        /* current tx rate */
 
1599
        index = sta->last_txrate;
 
1600
 
 
1601
        IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index,
 
1602
                       tbl->lq_type);
 
1603
 
 
1604
        /* rates available for this association, and for modulation mode */
 
1605
        rs_get_supported_rates(lq_sta, hdr, tbl->lq_type,
 
1606
                                &rate_mask);
 
1607
 
 
1608
        IWL_DEBUG_RATE("mask 0x%04X \n", rate_mask);
 
1609
 
 
1610
        /* mask with station rate restriction */
 
1611
        if (is_legacy(tbl->lq_type)) {
 
1612
                if (lq_sta->phymode == (u8) MODE_IEEE80211A)
 
1613
                        /* supp_rates has no CCK bits in A mode */
 
1614
                        rate_scale_index_msk = (u16) (rate_mask &
 
1615
                                (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
 
1616
                else
 
1617
                        rate_scale_index_msk = (u16) (rate_mask &
 
1618
                                                      lq_sta->supp_rates);
 
1619
 
 
1620
        } else
 
1621
                rate_scale_index_msk = rate_mask;
 
1622
 
 
1623
        if (!rate_scale_index_msk)
 
1624
                rate_scale_index_msk = rate_mask;
 
1625
 
 
1626
        /* If current rate is no longer supported on current association,
 
1627
         * or user changed preferences for rates, find a new supported rate. */
 
1628
        if (index < 0 || !((1 << index) & rate_scale_index_msk)) {
 
1629
                index = IWL_INVALID_VALUE;
 
1630
                update_lq = 1;
 
1631
 
 
1632
                /* get the highest available rate */
 
1633
                for (i = 0; i <= IWL_RATE_COUNT; i++) {
 
1634
                        if ((1 << i) & rate_scale_index_msk)
 
1635
                                index = i;
 
1636
                }
 
1637
 
 
1638
                if (index == IWL_INVALID_VALUE) {
 
1639
                        IWL_WARNING("Can not find a suitable rate\n");
 
1640
                        return;
 
1641
                }
 
1642
        }
 
1643
 
 
1644
        /* Get expected throughput table and history window for current rate */
 
1645
        if (!tbl->expected_tpt)
 
1646
                rs_get_expected_tpt_table(lq_sta, tbl);
 
1647
 
 
1648
        window = &(tbl->win[index]);
 
1649
 
 
1650
        /*
 
1651
         * If there is not enough history to calculate actual average
 
1652
         * throughput, keep analyzing results of more tx frames, without
 
1653
         * changing rate or mode (bypass most of the rest of this function).
 
1654
         * Set up new rate table in uCode only if old rate is not supported
 
1655
         * in current association (use new rate found above).
 
1656
         */
 
1657
        fail_count = window->counter - window->success_counter;
 
1658
        if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
 
1659
             (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))
 
1660
            || (tbl->expected_tpt == NULL)) {
 
1661
                IWL_DEBUG_RATE("LQ: still below TH succ %d total %d "
 
1662
                               "for index %d\n",
 
1663
                               window->success_counter, window->counter, index);
 
1664
 
 
1665
                /* Can't calculate this yet; not enough history */
 
1666
                window->average_tpt = IWL_INVALID_VALUE;
 
1667
 
 
1668
                /* Should we stay with this modulation mode,
 
1669
                 * or search for a new one? */
 
1670
                rs_stay_in_table(lq_sta);
 
1671
 
 
1672
                /* Set up new rate table in uCode, if needed */
 
1673
                if (update_lq) {
 
1674
                        rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
 
1675
                        rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq);
 
1676
                        rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
 
1677
                }
 
1678
                goto out;
 
1679
 
 
1680
        /* Else we have enough samples; calculate estimate of
 
1681
         * actual average throughput */
 
1682
        } else
 
1683
                window->average_tpt = ((window->success_ratio *
 
1684
                                        tbl->expected_tpt[index] + 64) / 128);
 
1685
 
 
1686
        /* If we are searching for better modulation mode, check success. */
 
1687
        if (lq_sta->search_better_tbl) {
 
1688
                int success_limit = IWL_RATE_SCALE_SWITCH;
 
1689
 
 
1690
                /* If good success, continue using the "search" mode;
 
1691
                 * no need to send new link quality command, since we're
 
1692
                 * continuing to use the setup that we've been trying. */
 
1693
                if ((window->success_ratio > success_limit) ||
 
1694
                    (window->average_tpt > lq_sta->last_tpt)) {
 
1695
                        if (!is_legacy(tbl->lq_type)) {
 
1696
                                IWL_DEBUG_HT("LQ: we are switching to HT"
 
1697
                                             " rate suc %d current tpt %d"
 
1698
                                             " old tpt %d\n",
 
1699
                                             window->success_ratio,
 
1700
                                             window->average_tpt,
 
1701
                                             lq_sta->last_tpt);
 
1702
                                lq_sta->enable_counter = 1;
 
1703
                        }
 
1704
                        /* Swap tables; "search" becomes "active" */
 
1705
                        lq_sta->active_tbl = active_tbl;
 
1706
                        current_tpt = window->average_tpt;
 
1707
 
 
1708
                /* Else poor success; go back to mode in "active" table */
 
1709
                } else {
 
1710
                        /* Nullify "search" table */
 
1711
                        tbl->lq_type = LQ_NONE;
 
1712
 
 
1713
                        /* Revert to "active" table */
 
1714
                        active_tbl = lq_sta->active_tbl;
 
1715
                        tbl = &(lq_sta->lq_info[active_tbl]);
 
1716
 
 
1717
                        /* Revert to "active" rate and throughput info */
 
1718
                        index = iwl4965_rate_index_from_plcp(
 
1719
                                tbl->current_rate.rate_n_flags);
 
1720
                        current_tpt = lq_sta->last_tpt;
 
1721
 
 
1722
                        /* Need to set up a new rate table in uCode */
 
1723
                        update_lq = 1;
 
1724
                        IWL_DEBUG_HT("XXY GO BACK TO OLD TABLE\n");
 
1725
                }
 
1726
 
 
1727
                /* Either way, we've made a decision; modulation mode
 
1728
                 * search is done, allow rate adjustment next time. */
 
1729
                lq_sta->search_better_tbl = 0;
 
1730
                done_search = 1;        /* Don't switch modes below! */
 
1731
                goto lq_update;
 
1732
        }
 
1733
 
 
1734
        /* (Else) not in search of better modulation mode, try for better
 
1735
         * starting rate, while staying in this mode. */
 
1736
        high_low = rs_get_adjacent_rate(index, rate_scale_index_msk,
 
1737
                                        tbl->lq_type);
 
1738
        low = high_low & 0xff;
 
1739
        high = (high_low >> 8) & 0xff;
 
1740
 
 
1741
        /* Collect measured throughputs for current and adjacent rates */
 
1742
        current_tpt = window->average_tpt;
 
1743
        if (low != IWL_RATE_INVALID)
 
1744
                low_tpt = tbl->win[low].average_tpt;
 
1745
        if (high != IWL_RATE_INVALID)
 
1746
                high_tpt = tbl->win[high].average_tpt;
 
1747
 
 
1748
        /* Assume rate increase */
 
1749
        scale_action = 1;
 
1750
 
 
1751
        /* Too many failures, decrease rate */
 
1752
        if ((window->success_ratio <= IWL_RATE_DECREASE_TH) ||
 
1753
            (current_tpt == 0)) {
 
1754
                IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
 
1755
                scale_action = -1;
 
1756
 
 
1757
        /* No throughput measured yet for adjacent rates; try increase. */
 
1758
        } else if ((low_tpt == IWL_INVALID_VALUE) &&
 
1759
                   (high_tpt == IWL_INVALID_VALUE))
 
1760
                scale_action = 1;
 
1761
 
 
1762
        /* Both adjacent throughputs are measured, but neither one has better
 
1763
         * throughput; we're using the best rate, don't change it! */
 
1764
        else if ((low_tpt != IWL_INVALID_VALUE) &&
 
1765
                 (high_tpt != IWL_INVALID_VALUE) &&
 
1766
                 (low_tpt < current_tpt) &&
 
1767
                 (high_tpt < current_tpt))
 
1768
                scale_action = 0;
 
1769
 
 
1770
        /* At least one adjacent rate's throughput is measured,
 
1771
         * and may have better performance. */
 
1772
        else {
 
1773
                /* Higher adjacent rate's throughput is measured */
 
1774
                if (high_tpt != IWL_INVALID_VALUE) {
 
1775
                        /* Higher rate has better throughput */
 
1776
                        if (high_tpt > current_tpt)
 
1777
                                scale_action = 1;
 
1778
                        else {
 
1779
                                IWL_DEBUG_RATE
 
1780
                                    ("decrease rate because of high tpt\n");
 
1781
                                scale_action = -1;
 
1782
                        }
 
1783
 
 
1784
                /* Lower adjacent rate's throughput is measured */
 
1785
                } else if (low_tpt != IWL_INVALID_VALUE) {
 
1786
                        /* Lower rate has better throughput */
 
1787
                        if (low_tpt > current_tpt) {
 
1788
                                IWL_DEBUG_RATE
 
1789
                                    ("decrease rate because of low tpt\n");
 
1790
                                scale_action = -1;
 
1791
                        } else
 
1792
                                scale_action = 1;
 
1793
                }
 
1794
        }
 
1795
 
 
1796
        /* Sanity check; asked for decrease, but success rate or throughput
 
1797
         * has been good at old rate.  Don't change it. */
 
1798
        if (scale_action == -1) {
 
1799
                if ((low != IWL_RATE_INVALID) &&
 
1800
                    ((window->success_ratio > IWL_RATE_HIGH_TH) ||
 
1801
                     (current_tpt > (100 * tbl->expected_tpt[low]))))
 
1802
                        scale_action = 0;
 
1803
 
 
1804
        /* Sanity check; asked for increase, but success rate has not been great
 
1805
         * even at old rate, higher rate will be worse.  Don't change it. */
 
1806
        } else if ((scale_action == 1) &&
 
1807
                   (window->success_ratio < IWL_RATE_INCREASE_TH))
 
1808
                scale_action = 0;
 
1809
 
 
1810
        switch (scale_action) {
 
1811
        case -1:
 
1812
                /* Decrease starting rate, update uCode's rate table */
 
1813
                if (low != IWL_RATE_INVALID) {
 
1814
                        update_lq = 1;
 
1815
                        index = low;
 
1816
                }
 
1817
                break;
 
1818
        case 1:
 
1819
                /* Increase starting rate, update uCode's rate table */
 
1820
                if (high != IWL_RATE_INVALID) {
 
1821
                        update_lq = 1;
 
1822
                        index = high;
 
1823
                }
 
1824
 
 
1825
                break;
 
1826
        case 0:
 
1827
                /* No change */
 
1828
        default:
 
1829
                break;
 
1830
        }
 
1831
 
 
1832
        IWL_DEBUG_HT("choose rate scale index %d action %d low %d "
 
1833
                    "high %d type %d\n",
 
1834
                     index, scale_action, low, high, tbl->lq_type);
 
1835
 
 
1836
 lq_update:
 
1837
        /* Replace uCode's rate table for the destination station. */
 
1838
        if (update_lq) {
 
1839
                rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
 
1840
                rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq);
 
1841
                rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
 
1842
        }
 
1843
 
 
1844
        /* Should we stay with this modulation mode, or search for a new one? */
 
1845
        rs_stay_in_table(lq_sta);
 
1846
 
 
1847
        /*
 
1848
         * Search for new modulation mode if we're:
 
1849
         * 1)  Not changing rates right now
 
1850
         * 2)  Not just finishing up a search
 
1851
         * 3)  Allowing a new search
 
1852
         */
 
1853
        if (!update_lq && !done_search && !lq_sta->stay_in_tbl) {
 
1854
                /* Save current throughput to compare with "search" throughput*/
 
1855
                lq_sta->last_tpt = current_tpt;
 
1856
 
 
1857
                /* Select a new "search" modulation mode to try.
 
1858
                 * If one is found, set up the new "search" table. */
 
1859
                if (is_legacy(tbl->lq_type))
 
1860
                        rs_move_legacy_other(priv, lq_sta, index);
 
1861
                else if (is_siso(tbl->lq_type))
 
1862
                        rs_move_siso_to_other(priv, lq_sta, index);
 
1863
                else
 
1864
                        rs_move_mimo_to_other(priv, lq_sta, index);
 
1865
 
 
1866
                /* If new "search" mode was selected, set up in uCode table */
 
1867
                if (lq_sta->search_better_tbl) {
 
1868
                        /* Access the "search" table, clear its history. */
 
1869
                        tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
 
1870
                        for (i = 0; i < IWL_RATE_COUNT; i++)
 
1871
                                rs_rate_scale_clear_window(&(tbl->win[i]));
 
1872
 
 
1873
                        /* Use new "search" start rate */
 
1874
                        index = iwl4965_rate_index_from_plcp(
 
1875
                                        tbl->current_rate.rate_n_flags);
 
1876
 
 
1877
                        IWL_DEBUG_HT("Switch current  mcs: %X index: %d\n",
 
1878
                                     tbl->current_rate.rate_n_flags, index);
 
1879
                        rs_fill_link_cmd(lq_sta, &tbl->current_rate,
 
1880
                                         &lq_sta->lq);
 
1881
                        rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
 
1882
                }
 
1883
 
 
1884
                /* If the "active" (non-search) mode was legacy,
 
1885
                 * and we've tried switching antennas,
 
1886
                 * but we haven't been able to try HT modes (not available),
 
1887
                 * stay with best antenna legacy modulation for a while
 
1888
                 * before next round of mode comparisons. */
 
1889
                tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
 
1890
                if (is_legacy(tbl1->lq_type) &&
 
1891
#ifdef CONFIG_IWL4965_HT
 
1892
                    !priv->current_assoc_ht.is_ht &&
 
1893
#endif
 
1894
                    (lq_sta->action_counter >= 1)) {
 
1895
                        lq_sta->action_counter = 0;
 
1896
                        IWL_DEBUG_HT("LQ: STAY in legacy table\n");
 
1897
                        rs_set_stay_in_table(1, lq_sta);
 
1898
                }
 
1899
 
 
1900
                /* If we're in an HT mode, and all 3 mode switch actions
 
1901
                 * have been tried and compared, stay in this best modulation
 
1902
                 * mode for a while before next round of mode comparisons. */
 
1903
                if (lq_sta->enable_counter &&
 
1904
                    (lq_sta->action_counter >= IWL_ACTION_LIMIT)) {
 
1905
#ifdef CONFIG_IWL4965_HT_AGG
 
1906
                        /* If appropriate, set up aggregation! */
 
1907
                        if ((lq_sta->last_tpt > TID_AGG_TPT_THREHOLD) &&
 
1908
                            (priv->lq_mngr.agg_ctrl.auto_agg)) {
 
1909
                                priv->lq_mngr.agg_ctrl.tid_retry =
 
1910
                                    TID_ALL_SPECIFIED;
 
1911
                                schedule_work(&priv->agg_work);
 
1912
                        }
 
1913
#endif /*CONFIG_IWL4965_HT_AGG */
 
1914
                        lq_sta->action_counter = 0;
 
1915
                        rs_set_stay_in_table(0, lq_sta);
 
1916
                }
 
1917
 
 
1918
        /*
 
1919
         * Else, don't search for a new modulation mode.
 
1920
         * Put new timestamp in stay-in-modulation-mode flush timer if:
 
1921
         * 1)  Not changing rates right now
 
1922
         * 2)  Not just finishing up a search
 
1923
         * 3)  flush timer is empty
 
1924
         */
 
1925
        } else {
 
1926
                if ((!update_lq) && (!done_search) && (!lq_sta->flush_timer))
 
1927
                        lq_sta->flush_timer = jiffies;
 
1928
        }
 
1929
 
 
1930
out:
 
1931
        rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green);
 
1932
        i = index;
 
1933
        sta->last_txrate = i;
 
1934
 
 
1935
        /* sta->txrate is an index to A mode rates which start
 
1936
         * at IWL_FIRST_OFDM_RATE
 
1937
         */
 
1938
        if (lq_sta->phymode == (u8) MODE_IEEE80211A)
 
1939
                sta->txrate = i - IWL_FIRST_OFDM_RATE;
 
1940
        else
 
1941
                sta->txrate = i;
 
1942
 
 
1943
        sta->antenna_sel_tx = tbl->lq_type;
 
1944
 
 
1945
        return;
 
1946
}
 
1947
 
 
1948
 
 
1949
static void rs_initialize_lq(struct iwl4965_priv *priv,
 
1950
                             struct sta_info *sta)
 
1951
{
 
1952
        int i;
 
1953
        struct iwl4965_lq_sta *lq_sta;
 
1954
        struct iwl4965_scale_tbl_info *tbl;
 
1955
        u8 active_tbl = 0;
 
1956
        int rate_idx;
 
1957
        u8 use_green = rs_use_green(priv);
 
1958
        struct iwl4965_rate mcs_rate;
 
1959
 
 
1960
        if (!sta || !sta->rate_ctrl_priv)
 
1961
                goto out;
 
1962
 
 
1963
        lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
 
1964
        i = sta->last_txrate;
 
1965
 
 
1966
        if ((lq_sta->lq.sta_id == 0xff) &&
 
1967
            (priv->iw_mode == IEEE80211_IF_TYPE_IBSS))
 
1968
                goto out;
 
1969
 
 
1970
        if (!lq_sta->search_better_tbl)
 
1971
                active_tbl = lq_sta->active_tbl;
 
1972
        else
 
1973
                active_tbl = 1 - lq_sta->active_tbl;
 
1974
 
 
1975
        tbl = &(lq_sta->lq_info[active_tbl]);
 
1976
 
 
1977
        if ((i < 0) || (i >= IWL_RATE_COUNT))
 
1978
                i = 0;
 
1979
 
 
1980
        mcs_rate.rate_n_flags = iwl4965_rates[i].plcp ;
 
1981
        mcs_rate.rate_n_flags |= RATE_MCS_ANT_B_MSK;
 
1982
        mcs_rate.rate_n_flags &= ~RATE_MCS_ANT_A_MSK;
 
1983
 
 
1984
        if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
 
1985
                mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK;
 
1986
 
 
1987
        tbl->antenna_type = ANT_AUX;
 
1988
        rs_get_tbl_info_from_mcs(&mcs_rate, priv->phymode, tbl, &rate_idx);
 
1989
        if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type))
 
1990
            rs_toggle_antenna(&mcs_rate, tbl);
 
1991
 
 
1992
        rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green);
 
1993
        tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags;
 
1994
        rs_get_expected_tpt_table(lq_sta, tbl);
 
1995
        rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq);
 
1996
        rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
 
1997
 out:
 
1998
        return;
 
1999
}
 
2000
 
 
2001
static struct ieee80211_rate *rs_get_lowest_rate(struct ieee80211_local
 
2002
                                                 *local)
 
2003
{
 
2004
        struct ieee80211_hw_mode *mode = local->oper_hw_mode;
 
2005
        int i;
 
2006
 
 
2007
        for (i = 0; i < mode->num_rates; i++) {
 
2008
                struct ieee80211_rate *rate = &mode->rates[i];
 
2009
 
 
2010
                if (rate->flags & IEEE80211_RATE_SUPPORTED)
 
2011
                        return rate;
 
2012
        }
 
2013
 
 
2014
        return &mode->rates[0];
 
2015
}
 
2016
 
 
2017
static struct ieee80211_rate *rs_get_rate(void *priv_rate,
 
2018
                                               struct net_device *dev,
 
2019
                                               struct sk_buff *skb,
 
2020
                                               struct rate_control_extra
 
2021
                                               *extra)
 
2022
{
 
2023
 
 
2024
        int i;
 
2025
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
2026
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
2027
        struct sta_info *sta;
 
2028
        u16 fc;
 
2029
        struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate;
 
2030
        struct iwl4965_lq_sta *lq_sta;
 
2031
 
 
2032
        IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 
2033
 
 
2034
        memset(extra, 0, sizeof(*extra));
 
2035
 
 
2036
        fc = le16_to_cpu(hdr->frame_control);
 
2037
        if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
 
2038
                /* Send management frames and broadcast/multicast data using
 
2039
                 * lowest rate. */
 
2040
                /* TODO: this could probably be improved.. */
 
2041
                return rs_get_lowest_rate(local);
 
2042
        }
 
2043
 
 
2044
        sta = iwlwifi_sta_info_get(local, hdr->addr1);
 
2045
 
 
2046
        if (!sta || !sta->rate_ctrl_priv) {
 
2047
                if (sta)
 
2048
                        iwlwifi_sta_info_put(sta);
 
2049
                return rs_get_lowest_rate(local);
 
2050
        }
 
2051
 
 
2052
        lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
 
2053
        i = sta->last_txrate;
 
2054
 
 
2055
        if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
 
2056
            !lq_sta->ibss_sta_added) {
 
2057
                u8 sta_id = iwl4965_hw_find_station(priv, hdr->addr1);
 
2058
 
 
2059
                if (sta_id == IWL_INVALID_STATION) {
 
2060
                        IWL_DEBUG_RATE("LQ: ADD station " MAC_FMT "\n",
 
2061
                                        MAC_ARG(hdr->addr1));
 
2062
                        sta_id = iwl4965_add_station_flags(priv,
 
2063
                                                 hdr->addr1, 0, CMD_ASYNC);
 
2064
                }
 
2065
                if ((sta_id != IWL_INVALID_STATION)) {
 
2066
                        lq_sta->lq.sta_id = sta_id;
 
2067
                        lq_sta->lq.rs_table[0].rate_n_flags = 0;
 
2068
                        lq_sta->ibss_sta_added = 1;
 
2069
                        rs_initialize_lq(priv, sta);
 
2070
                }
 
2071
                if (!lq_sta->ibss_sta_added)
 
2072
                        goto done;
 
2073
        }
 
2074
 
 
2075
 done:
 
2076
        iwlwifi_sta_info_put(sta);
 
2077
        if ((i < 0) || (i > IWL_RATE_COUNT))
 
2078
                return rs_get_lowest_rate(local);
 
2079
 
 
2080
        return &priv->ieee_rates[i];
 
2081
}
 
2082
 
 
2083
static void *rs_alloc_sta(void *priv, gfp_t gfp)
 
2084
{
 
2085
        struct iwl4965_lq_sta *lq_sta;
 
2086
        int i, j;
 
2087
 
 
2088
        IWL_DEBUG_RATE("create station rate scale window\n");
 
2089
 
 
2090
        lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp);
 
2091
 
 
2092
        if (lq_sta == NULL)
 
2093
                return NULL;
 
2094
        lq_sta->lq.sta_id = 0xff;
 
2095
 
 
2096
 
 
2097
        for (j = 0; j < LQ_SIZE; j++)
 
2098
                for (i = 0; i < IWL_RATE_COUNT; i++)
 
2099
                        rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
 
2100
 
 
2101
        return lq_sta;
 
2102
}
 
2103
 
 
2104
static void rs_rate_init(void *priv_rate, void *priv_sta,
 
2105
                         struct ieee80211_local *local,
 
2106
                         struct sta_info *sta)
 
2107
{
 
2108
        int i, j;
 
2109
        struct ieee80211_hw_mode *mode = local->oper_hw_mode;
 
2110
        struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate;
 
2111
        struct iwl4965_lq_sta *lq_sta = priv_sta;
 
2112
 
 
2113
        lq_sta->flush_timer = 0;
 
2114
        lq_sta->supp_rates = sta->supp_rates;
 
2115
        sta->txrate = 3;
 
2116
        for (j = 0; j < LQ_SIZE; j++)
 
2117
                for (i = 0; i < IWL_RATE_COUNT; i++)
 
2118
                        rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
 
2119
 
 
2120
        IWL_DEBUG_RATE("rate scale global init\n");
 
2121
        /* TODO: what is a good starting rate for STA? About middle? Maybe not
 
2122
         * the lowest or the highest rate.. Could consider using RSSI from
 
2123
         * previous packets? Need to have IEEE 802.1X auth succeed immediately
 
2124
         * after assoc.. */
 
2125
 
 
2126
        lq_sta->ibss_sta_added = 0;
 
2127
        if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
 
2128
                u8 sta_id = iwl4965_hw_find_station(priv, sta->addr);
 
2129
                /* for IBSS the call are from tasklet */
 
2130
                IWL_DEBUG_HT("LQ: ADD station " MAC_FMT " \n",
 
2131
                             MAC_ARG(sta->addr));
 
2132
 
 
2133
                if (sta_id == IWL_INVALID_STATION) {
 
2134
                        IWL_DEBUG_RATE("LQ: ADD station " MAC_FMT "\n",
 
2135
                                        MAC_ARG(sta->addr));
 
2136
                                        sta_id = iwl4965_add_station_flags(priv,
 
2137
                                                 sta->addr, 0, CMD_ASYNC);
 
2138
                }
 
2139
                if ((sta_id != IWL_INVALID_STATION)) {
 
2140
                        lq_sta->lq.sta_id = sta_id;
 
2141
                        lq_sta->lq.rs_table[0].rate_n_flags = 0;
 
2142
                }
 
2143
                /* FIXME: this is w/a remove it later */
 
2144
                priv->assoc_station_added = 1;
 
2145
        }
 
2146
 
 
2147
        /* Find highest tx rate supported by hardware and destination station */
 
2148
        for (i = 0; i < mode->num_rates; i++) {
 
2149
                if ((sta->supp_rates & BIT(i)) &&
 
2150
                    (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED))
 
2151
                        sta->txrate = i;
 
2152
        }
 
2153
        sta->last_txrate = sta->txrate;
 
2154
        /* For MODE_IEEE80211A, cck rates are at end of rate table */
 
2155
        if (local->hw.conf.phymode == MODE_IEEE80211A)
 
2156
                sta->last_txrate += IWL_FIRST_OFDM_RATE;
 
2157
 
 
2158
        lq_sta->is_dup = priv->is_dup;
 
2159
        lq_sta->valid_antenna = priv->valid_antenna;
 
2160
        lq_sta->antenna = priv->antenna;
 
2161
        lq_sta->is_green = rs_use_green(priv);
 
2162
        lq_sta->active_rate = priv->active_rate;
 
2163
        lq_sta->active_rate &= ~(0x1000);
 
2164
        lq_sta->active_rate_basic = priv->active_rate_basic;
 
2165
        lq_sta->phymode = priv->phymode;
 
2166
#ifdef CONFIG_IWL4965_HT
 
2167
        /*
 
2168
         * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
 
2169
         * supp_rates[] does not; shift to convert format, force 9 MBits off.
 
2170
         */
 
2171
        lq_sta->active_siso_rate = (priv->current_assoc_ht.supp_rates[0] << 1);
 
2172
        lq_sta->active_siso_rate |=
 
2173
                                (priv->current_assoc_ht.supp_rates[0] & 0x1);
 
2174
        lq_sta->active_siso_rate &= ~((u16)0x2);
 
2175
        lq_sta->active_siso_rate =
 
2176
                        lq_sta->active_siso_rate << IWL_FIRST_OFDM_RATE;
 
2177
 
 
2178
        /* Same here */
 
2179
        lq_sta->active_mimo_rate = (priv->current_assoc_ht.supp_rates[1] << 1);
 
2180
        lq_sta->active_mimo_rate |=
 
2181
                                (priv->current_assoc_ht.supp_rates[1] & 0x1);
 
2182
        lq_sta->active_mimo_rate &= ~((u16)0x2);
 
2183
        lq_sta->active_mimo_rate =
 
2184
                        lq_sta->active_mimo_rate << IWL_FIRST_OFDM_RATE;
 
2185
        IWL_DEBUG_HT("SISO RATE 0x%X MIM0 RATE 0x%X\n",
 
2186
                     lq_sta->active_siso_rate,
 
2187
                     lq_sta->active_mimo_rate);
 
2188
#endif /*CONFIG_IWL4965_HT*/
 
2189
#ifdef CONFIG_MAC80211_DEBUGFS
 
2190
        lq_sta->drv = priv;
 
2191
#endif
 
2192
 
 
2193
        if (priv->assoc_station_added)
 
2194
                priv->lq_mngr.lq_ready = 1;
 
2195
 
 
2196
        rs_initialize_lq(priv, sta);
 
2197
}
 
2198
 
 
2199
static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
 
2200
                            struct iwl4965_rate *tx_mcs,
 
2201
                            struct iwl4965_link_quality_cmd *lq_cmd)
 
2202
{
 
2203
        int index = 0;
 
2204
        int rate_idx;
 
2205
        int repeat_rate = 0;
 
2206
        u8 ant_toggle_count = 0;
 
2207
        u8 use_ht_possible = 1;
 
2208
        struct iwl4965_rate new_rate;
 
2209
        struct iwl4965_scale_tbl_info tbl_type = { 0 };
 
2210
 
 
2211
        /* Override starting rate (index 0) if needed for debug purposes */
 
2212
        rs_dbgfs_set_mcs(lq_sta, tx_mcs, index);
 
2213
 
 
2214
        /* Interpret rate_n_flags */
 
2215
        rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->phymode,
 
2216
                                  &tbl_type, &rate_idx);
 
2217
 
 
2218
        /* How many times should we repeat the initial rate? */
 
2219
        if (is_legacy(tbl_type.lq_type)) {
 
2220
                ant_toggle_count = 1;
 
2221
                repeat_rate = IWL_NUMBER_TRY;
 
2222
        } else
 
2223
                repeat_rate = IWL_HT_NUMBER_TRY;
 
2224
 
 
2225
        lq_cmd->general_params.mimo_delimiter =
 
2226
                        is_mimo(tbl_type.lq_type) ? 1 : 0;
 
2227
 
 
2228
        /* Fill 1st table entry (index 0) */
 
2229
        lq_cmd->rs_table[index].rate_n_flags =
 
2230
                        cpu_to_le32(tx_mcs->rate_n_flags);
 
2231
        new_rate.rate_n_flags = tx_mcs->rate_n_flags;
 
2232
 
 
2233
        if (is_mimo(tbl_type.lq_type) || (tbl_type.antenna_type == ANT_MAIN))
 
2234
                lq_cmd->general_params.single_stream_ant_msk
 
2235
                        = LINK_QUAL_ANT_A_MSK;
 
2236
        else
 
2237
                lq_cmd->general_params.single_stream_ant_msk
 
2238
                        = LINK_QUAL_ANT_B_MSK;
 
2239
 
 
2240
        index++;
 
2241
        repeat_rate--;
 
2242
 
 
2243
        /* Fill rest of rate table */
 
2244
        while (index < LINK_QUAL_MAX_RETRY_NUM) {
 
2245
                /* Repeat initial/next rate.
 
2246
                 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
 
2247
                 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
 
2248
                while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
 
2249
                        if (is_legacy(tbl_type.lq_type)) {
 
2250
                                if (ant_toggle_count <
 
2251
                                    NUM_TRY_BEFORE_ANTENNA_TOGGLE)
 
2252
                                        ant_toggle_count++;
 
2253
                                else {
 
2254
                                        rs_toggle_antenna(&new_rate, &tbl_type);
 
2255
                                        ant_toggle_count = 1;
 
2256
                                }
 
2257
                        }
 
2258
 
 
2259
                        /* Override next rate if needed for debug purposes */
 
2260
                        rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
 
2261
 
 
2262
                        /* Fill next table entry */
 
2263
                        lq_cmd->rs_table[index].rate_n_flags =
 
2264
                                        cpu_to_le32(new_rate.rate_n_flags);
 
2265
                        repeat_rate--;
 
2266
                        index++;
 
2267
                }
 
2268
 
 
2269
                rs_get_tbl_info_from_mcs(&new_rate, lq_sta->phymode, &tbl_type,
 
2270
                                                &rate_idx);
 
2271
 
 
2272
                /* Indicate to uCode which entries might be MIMO.
 
2273
                 * If initial rate was MIMO, this will finally end up
 
2274
                 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
 
2275
                if (is_mimo(tbl_type.lq_type))
 
2276
                        lq_cmd->general_params.mimo_delimiter = index;
 
2277
 
 
2278
                /* Get next rate */
 
2279
                rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
 
2280
                                  use_ht_possible, &new_rate);
 
2281
 
 
2282
                /* How many times should we repeat the next rate? */
 
2283
                if (is_legacy(tbl_type.lq_type)) {
 
2284
                        if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE)
 
2285
                                ant_toggle_count++;
 
2286
                        else {
 
2287
                                rs_toggle_antenna(&new_rate, &tbl_type);
 
2288
                                ant_toggle_count = 1;
 
2289
                        }
 
2290
                        repeat_rate = IWL_NUMBER_TRY;
 
2291
                } else
 
2292
                        repeat_rate = IWL_HT_NUMBER_TRY;
 
2293
 
 
2294
                /* Don't allow HT rates after next pass.
 
2295
                 * rs_get_lower_rate() will change type to LQ_A or LQ_G. */
 
2296
                use_ht_possible = 0;
 
2297
 
 
2298
                /* Override next rate if needed for debug purposes */
 
2299
                rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
 
2300
 
 
2301
                /* Fill next table entry */
 
2302
                lq_cmd->rs_table[index].rate_n_flags =
 
2303
                                cpu_to_le32(new_rate.rate_n_flags);
 
2304
 
 
2305
                index++;
 
2306
                repeat_rate--;
 
2307
        }
 
2308
 
 
2309
        lq_cmd->general_params.dual_stream_ant_msk = 3;
 
2310
        lq_cmd->agg_params.agg_dis_start_th = 3;
 
2311
        lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
 
2312
}
 
2313
 
 
2314
static void *rs_alloc(struct ieee80211_local *local)
 
2315
{
 
2316
        return local->hw.priv;
 
2317
}
 
2318
/* rate scale requires free function to be implemented */
 
2319
static void rs_free(void *priv_rate)
 
2320
{
 
2321
        return;
 
2322
}
 
2323
 
 
2324
static void rs_clear(void *priv_rate)
 
2325
{
 
2326
        struct iwl4965_priv *priv = (struct iwl4965_priv *) priv_rate;
 
2327
 
 
2328
        IWL_DEBUG_RATE("enter\n");
 
2329
 
 
2330
        priv->lq_mngr.lq_ready = 0;
 
2331
#ifdef CONFIG_IWL4965_HT
 
2332
#ifdef CONFIG_IWL4965_HT_AGG
 
2333
        if (priv->lq_mngr.agg_ctrl.granted_ba)
 
2334
                iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED);
 
2335
#endif /*CONFIG_IWL4965_HT_AGG */
 
2336
#endif /* CONFIG_IWL4965_HT */
 
2337
 
 
2338
        IWL_DEBUG_RATE("leave\n");
 
2339
}
 
2340
 
 
2341
static void rs_free_sta(void *priv, void *priv_sta)
 
2342
{
 
2343
        struct iwl4965_lq_sta *lq_sta = priv_sta;
 
2344
 
 
2345
        IWL_DEBUG_RATE("enter\n");
 
2346
        kfree(lq_sta);
 
2347
        IWL_DEBUG_RATE("leave\n");
 
2348
}
 
2349
 
 
2350
 
 
2351
#ifdef CONFIG_MAC80211_DEBUGFS
 
2352
static int open_file_generic(struct inode *inode, struct file *file)
 
2353
{
 
2354
        file->private_data = inode->i_private;
 
2355
        return 0;
 
2356
}
 
2357
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
 
2358
                                struct iwl4965_rate *mcs, int index)
 
2359
{
 
2360
        u32 base_rate;
 
2361
 
 
2362
        if (lq_sta->phymode == (u8) MODE_IEEE80211A)
 
2363
                base_rate = 0x800D;
 
2364
        else
 
2365
                base_rate = 0x820A;
 
2366
 
 
2367
        if (lq_sta->dbg_fixed.rate_n_flags) {
 
2368
                if (index < 12)
 
2369
                        mcs->rate_n_flags = lq_sta->dbg_fixed.rate_n_flags;
 
2370
                else
 
2371
                        mcs->rate_n_flags = base_rate;
 
2372
                IWL_DEBUG_RATE("Fixed rate ON\n");
 
2373
                return;
 
2374
        }
 
2375
 
 
2376
        IWL_DEBUG_RATE("Fixed rate OFF\n");
 
2377
}
 
2378
 
 
2379
static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
 
2380
                        const char __user *user_buf, size_t count, loff_t *ppos)
 
2381
{
 
2382
        struct iwl4965_lq_sta *lq_sta = file->private_data;
 
2383
        char buf[64];
 
2384
        int buf_size;
 
2385
        u32 parsed_rate;
 
2386
 
 
2387
        memset(buf, 0, sizeof(buf));
 
2388
        buf_size = min(count, sizeof(buf) -  1);
 
2389
        if (copy_from_user(buf, user_buf, buf_size))
 
2390
                return -EFAULT;
 
2391
 
 
2392
        if (sscanf(buf, "%x", &parsed_rate) == 1)
 
2393
                lq_sta->dbg_fixed.rate_n_flags = parsed_rate;
 
2394
        else
 
2395
                lq_sta->dbg_fixed.rate_n_flags = 0;
 
2396
 
 
2397
        lq_sta->active_rate = 0x0FFF;   /* 1 - 54 MBits, includes CCK */
 
2398
        lq_sta->active_siso_rate = 0x1FD0;      /* 6 - 60 MBits, no 9, no CCK */
 
2399
        lq_sta->active_mimo_rate = 0x1FD0;      /* 6 - 60 MBits, no 9, no CCK */
 
2400
 
 
2401
        IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
 
2402
                lq_sta->lq.sta_id, lq_sta->dbg_fixed.rate_n_flags);
 
2403
 
 
2404
        if (lq_sta->dbg_fixed.rate_n_flags) {
 
2405
                rs_fill_link_cmd(lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq);
 
2406
                rs_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC);
 
2407
        }
 
2408
 
 
2409
        return count;
 
2410
}
 
2411
 
 
2412
static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 
2413
                        char __user *user_buf, size_t count, loff_t *ppos)
 
2414
{
 
2415
        char buff[1024];
 
2416
        int desc = 0;
 
2417
        int i = 0;
 
2418
 
 
2419
        struct iwl4965_lq_sta *lq_sta = file->private_data;
 
2420
 
 
2421
        desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
 
2422
        desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
 
2423
                        lq_sta->total_failed, lq_sta->total_success,
 
2424
                        lq_sta->active_rate);
 
2425
        desc += sprintf(buff+desc, "fixed rate 0x%X\n",
 
2426
                        lq_sta->dbg_fixed.rate_n_flags);
 
2427
        desc += sprintf(buff+desc, "general:"
 
2428
                "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
 
2429
                lq_sta->lq.general_params.flags,
 
2430
                lq_sta->lq.general_params.mimo_delimiter,
 
2431
                lq_sta->lq.general_params.single_stream_ant_msk,
 
2432
                lq_sta->lq.general_params.dual_stream_ant_msk);
 
2433
 
 
2434
        desc += sprintf(buff+desc, "agg:"
 
2435
                        "time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",
 
2436
                        le16_to_cpu(lq_sta->lq.agg_params.agg_time_limit),
 
2437
                        lq_sta->lq.agg_params.agg_dis_start_th,
 
2438
                        lq_sta->lq.agg_params.agg_frame_cnt_limit);
 
2439
 
 
2440
        desc += sprintf(buff+desc,
 
2441
                        "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
 
2442
                        lq_sta->lq.general_params.start_rate_index[0],
 
2443
                        lq_sta->lq.general_params.start_rate_index[1],
 
2444
                        lq_sta->lq.general_params.start_rate_index[2],
 
2445
                        lq_sta->lq.general_params.start_rate_index[3]);
 
2446
 
 
2447
 
 
2448
        for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
 
2449
                desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
 
2450
                        i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
 
2451
 
 
2452
        return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
 
2453
}
 
2454
 
 
2455
static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
 
2456
        .write = rs_sta_dbgfs_scale_table_write,
 
2457
        .read = rs_sta_dbgfs_scale_table_read,
 
2458
        .open = open_file_generic,
 
2459
};
 
2460
static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
 
2461
                        char __user *user_buf, size_t count, loff_t *ppos)
 
2462
{
 
2463
        char buff[1024];
 
2464
        int desc = 0;
 
2465
        int i, j;
 
2466
 
 
2467
        struct iwl4965_lq_sta *lq_sta = file->private_data;
 
2468
        for (i = 0; i < LQ_SIZE; i++) {
 
2469
                desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
 
2470
                                "rate=0x%X\n",
 
2471
                                lq_sta->active_tbl == i?"*":"x",
 
2472
                                lq_sta->lq_info[i].lq_type,
 
2473
                                lq_sta->lq_info[i].is_SGI,
 
2474
                                lq_sta->lq_info[i].is_fat,
 
2475
                                lq_sta->lq_info[i].is_dup,
 
2476
                                lq_sta->lq_info[i].current_rate.rate_n_flags);
 
2477
                for (j = 0; j < IWL_RATE_COUNT; j++) {
 
2478
                        desc += sprintf(buff+desc,
 
2479
                                "counter=%d success=%d %%=%d\n",
 
2480
                                lq_sta->lq_info[i].win[j].counter,
 
2481
                                lq_sta->lq_info[i].win[j].success_counter,
 
2482
                                lq_sta->lq_info[i].win[j].success_ratio);
 
2483
                }
 
2484
        }
 
2485
        return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
 
2486
}
 
2487
 
 
2488
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
 
2489
        .read = rs_sta_dbgfs_stats_table_read,
 
2490
        .open = open_file_generic,
 
2491
};
 
2492
 
 
2493
static void rs_add_debugfs(void *priv, void *priv_sta,
 
2494
                                        struct dentry *dir)
 
2495
{
 
2496
        struct iwl4965_lq_sta *lq_sta = priv_sta;
 
2497
        lq_sta->rs_sta_dbgfs_scale_table_file =
 
2498
                debugfs_create_file("rate_scale_table", 0600, dir,
 
2499
                                lq_sta, &rs_sta_dbgfs_scale_table_ops);
 
2500
        lq_sta->rs_sta_dbgfs_stats_table_file =
 
2501
                debugfs_create_file("rate_stats_table", 0600, dir,
 
2502
                        lq_sta, &rs_sta_dbgfs_stats_table_ops);
 
2503
}
 
2504
 
 
2505
static void rs_remove_debugfs(void *priv, void *priv_sta)
 
2506
{
 
2507
        struct iwl4965_lq_sta *lq_sta = priv_sta;
 
2508
        debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
 
2509
        debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
 
2510
}
 
2511
#endif
 
2512
 
 
2513
static struct rate_control_ops rs_ops = {
 
2514
        .module = NULL,
 
2515
        .name = RS_NAME,
 
2516
        .tx_status = rs_tx_status,
 
2517
        .get_rate = rs_get_rate,
 
2518
        .rate_init = rs_rate_init,
 
2519
        .clear = rs_clear,
 
2520
        .alloc = rs_alloc,
 
2521
        .free = rs_free,
 
2522
        .alloc_sta = rs_alloc_sta,
 
2523
        .free_sta = rs_free_sta,
 
2524
#ifdef CONFIG_MAC80211_DEBUGFS
 
2525
        .add_sta_debugfs = rs_add_debugfs,
 
2526
        .remove_sta_debugfs = rs_remove_debugfs,
 
2527
#endif
 
2528
};
 
2529
 
 
2530
int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
 
2531
{
 
2532
        struct ieee80211_local *local = hw_to_local(hw);
 
2533
        struct iwl4965_priv *priv = hw->priv;
 
2534
        struct iwl4965_lq_sta *lq_sta;
 
2535
        struct sta_info *sta;
 
2536
        int cnt = 0, i;
 
2537
        u32 samples = 0, success = 0, good = 0;
 
2538
        unsigned long now = jiffies;
 
2539
        u32 max_time = 0;
 
2540
        u8 lq_type, antenna;
 
2541
 
 
2542
        sta = iwlwifi_sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
 
2543
        if (!sta || !sta->rate_ctrl_priv) {
 
2544
                if (sta) {
 
2545
                        iwlwifi_sta_info_put(sta);
 
2546
                        IWL_DEBUG_RATE("leave - no private rate data!\n");
 
2547
                } else
 
2548
                        IWL_DEBUG_RATE("leave - no station!\n");
 
2549
                return sprintf(buf, "station %d not found\n", sta_id);
 
2550
        }
 
2551
 
 
2552
        lq_sta = (void *)sta->rate_ctrl_priv;
 
2553
 
 
2554
        lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type;
 
2555
        antenna = lq_sta->lq_info[lq_sta->active_tbl].antenna_type;
 
2556
 
 
2557
        if (is_legacy(lq_type))
 
2558
                i = IWL_RATE_54M_INDEX;
 
2559
        else
 
2560
                i = IWL_RATE_60M_INDEX;
 
2561
        while (1) {
 
2562
                u64 mask;
 
2563
                int j;
 
2564
                int active = lq_sta->active_tbl;
 
2565
 
 
2566
                cnt +=
 
2567
                    sprintf(&buf[cnt], " %2dMbs: ", iwl4965_rates[i].ieee / 2);
 
2568
 
 
2569
                mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
 
2570
                for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
 
2571
                        buf[cnt++] =
 
2572
                                (lq_sta->lq_info[active].win[i].data & mask)
 
2573
                                ? '1' : '0';
 
2574
 
 
2575
                samples += lq_sta->lq_info[active].win[i].counter;
 
2576
                good += lq_sta->lq_info[active].win[i].success_counter;
 
2577
                success += lq_sta->lq_info[active].win[i].success_counter *
 
2578
                           iwl4965_rates[i].ieee;
 
2579
 
 
2580
                if (lq_sta->lq_info[active].win[i].stamp) {
 
2581
                        int delta =
 
2582
                                   jiffies_to_msecs(now -
 
2583
                                   lq_sta->lq_info[active].win[i].stamp);
 
2584
 
 
2585
                        if (delta > max_time)
 
2586
                                max_time = delta;
 
2587
 
 
2588
                        cnt += sprintf(&buf[cnt], "%5dms\n", delta);
 
2589
                } else
 
2590
                        buf[cnt++] = '\n';
 
2591
 
 
2592
                j = iwl4965_get_prev_ieee_rate(i);
 
2593
                if (j == i)
 
2594
                        break;
 
2595
                i = j;
 
2596
        }
 
2597
 
 
2598
        /* Display the average rate of all samples taken.
 
2599
         *
 
2600
         * NOTE:  We multiply # of samples by 2 since the IEEE measurement
 
2601
         * added from iwl4965_rates is actually 2X the rate */
 
2602
        if (samples)
 
2603
                cnt += sprintf(&buf[cnt],
 
2604
                         "\nAverage rate is %3d.%02dMbs over last %4dms\n"
 
2605
                         "%3d%% success (%d good packets over %d tries)\n",
 
2606
                         success / (2 * samples), (success * 5 / samples) % 10,
 
2607
                         max_time, good * 100 / samples, good, samples);
 
2608
        else
 
2609
                cnt += sprintf(&buf[cnt], "\nAverage rate: 0Mbs\n");
 
2610
 
 
2611
        cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d "
 
2612
                         "active_search %d rate index %d\n", lq_type, antenna,
 
2613
                         lq_sta->search_better_tbl, sta->last_txrate);
 
2614
 
 
2615
        iwlwifi_sta_info_put(sta);
 
2616
        return cnt;
 
2617
}
 
2618
 
 
2619
void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 
2620
{
 
2621
        struct iwl4965_priv *priv = hw->priv;
 
2622
 
 
2623
        priv->lq_mngr.lq_ready = 1;
 
2624
}
 
2625
 
 
2626
void iwl4965_rate_control_register(struct ieee80211_hw *hw)
 
2627
{
 
2628
        iwlwifi_ieee80211_rate_control_register(&rs_ops);
 
2629
}
 
2630
 
 
2631
void iwl4965_rate_control_unregister(struct ieee80211_hw *hw)
 
2632
{
 
2633
        iwlwifi_ieee80211_rate_control_unregister(&rs_ops);
 
2634
}
 
2635