OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [wireless/] [iwlwifi/] [iwl-3945-rs.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/******************************************************************************
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
 
27
#include <linux/kernel.h>
28
#include <linux/init.h>
29
#include <linux/skbuff.h>
30
#include <linux/wireless.h>
31
#include <net/mac80211.h>
32
#include <net/ieee80211.h>
33
 
34
#include <linux/netdevice.h>
35
#include <linux/etherdevice.h>
36
#include <linux/delay.h>
37
 
38
#include <linux/workqueue.h>
39
 
40
#define IWL 3945
41
 
42
#include "../net/mac80211/ieee80211_rate.h"
43
 
44
#include "iwlwifi.h"
45
 
46
#define RS_NAME "iwl-3945-rs"
47
 
48
struct iwl_rate_scale_data {
49
        u64 data;
50
        s32 success_counter;
51
        s32 success_ratio;
52
        s32 counter;
53
        s32 average_tpt;
54
        unsigned long stamp;
55
};
56
 
57
struct iwl_rate_scale_priv {
58
        spinlock_t lock;
59
        s32 *expected_tpt;
60
        unsigned long last_partial_flush;
61
        unsigned long last_flush;
62
        u32 flush_time;
63
        u32 last_tx_packets;
64
        u32 tx_packets;
65
        u8 tgg;
66
        u8 flush_pending;
67
        u8 start_rate;
68
        u8 ibss_sta_added;
69
        struct timer_list rate_scale_flush;
70
        struct iwl_rate_scale_data win[IWL_RATE_COUNT];
71
};
72
 
73
static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = {
74
        7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
75
};
76
 
77
static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = {
78
        7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
79
};
80
 
81
static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = {
82
        0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
83
};
84
 
85
static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = {
86
        7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
87
};
88
 
89
struct iwl_tpt_entry {
90
        s8 min_rssi;
91
        u8 index;
92
};
93
 
94
static struct iwl_tpt_entry iwl_tpt_table_a[] = {
95
        {-60, IWL_RATE_54M_INDEX},
96
        {-64, IWL_RATE_48M_INDEX},
97
        {-72, IWL_RATE_36M_INDEX},
98
        {-80, IWL_RATE_24M_INDEX},
99
        {-84, IWL_RATE_18M_INDEX},
100
        {-85, IWL_RATE_12M_INDEX},
101
        {-87, IWL_RATE_9M_INDEX},
102
        {-89, IWL_RATE_6M_INDEX}
103
};
104
 
105
static struct iwl_tpt_entry iwl_tpt_table_b[] = {
106
        {-86, IWL_RATE_11M_INDEX},
107
        {-88, IWL_RATE_5M_INDEX},
108
        {-90, IWL_RATE_2M_INDEX},
109
        {-92, IWL_RATE_1M_INDEX}
110
 
111
};
112
 
113
static struct iwl_tpt_entry iwl_tpt_table_g[] = {
114
        {-60, IWL_RATE_54M_INDEX},
115
        {-64, IWL_RATE_48M_INDEX},
116
        {-68, IWL_RATE_36M_INDEX},
117
        {-80, IWL_RATE_24M_INDEX},
118
        {-84, IWL_RATE_18M_INDEX},
119
        {-85, IWL_RATE_12M_INDEX},
120
        {-86, IWL_RATE_11M_INDEX},
121
        {-88, IWL_RATE_5M_INDEX},
122
        {-90, IWL_RATE_2M_INDEX},
123
        {-92, IWL_RATE_1M_INDEX}
124
};
125
 
126
#define IWL_RATE_MAX_WINDOW          62
127
#define IWL_RATE_FLUSH        (3*HZ/10)
128
#define IWL_RATE_WIN_FLUSH       (HZ/2)
129
#define IWL_RATE_HIGH_TH          11520
130
#define IWL_RATE_MIN_FAILURE_TH       8
131
#define IWL_RATE_MIN_SUCCESS_TH       8
132
#define IWL_RATE_DECREASE_TH       1920
133
 
134
static u8 iwl_get_rate_index_by_rssi(s32 rssi, u8 mode)
135
{
136
        u32 index = 0;
137
        u32 table_size = 0;
138
        struct iwl_tpt_entry *tpt_table = NULL;
139
 
140
        if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL))
141
                rssi = IWL_MIN_RSSI_VAL;
142
 
143
        switch (mode) {
144
        case MODE_IEEE80211G:
145
                tpt_table = iwl_tpt_table_g;
146
                table_size = ARRAY_SIZE(iwl_tpt_table_g);
147
                break;
148
 
149
        case MODE_IEEE80211A:
150
                tpt_table = iwl_tpt_table_a;
151
                table_size = ARRAY_SIZE(iwl_tpt_table_a);
152
                break;
153
 
154
        default:
155
        case MODE_IEEE80211B:
156
                tpt_table = iwl_tpt_table_b;
157
                table_size = ARRAY_SIZE(iwl_tpt_table_b);
158
                break;
159
        }
160
 
161
        while ((index < table_size) && (rssi < tpt_table[index].min_rssi))
162
                index++;
163
 
164
        index = min(index, (table_size - 1));
165
 
166
        return tpt_table[index].index;
167
}
168
 
169
static void iwl_clear_window(struct iwl_rate_scale_data *window)
170
{
171
        window->data = 0;
172
        window->success_counter = 0;
173
        window->success_ratio = IWL_INVALID_VALUE;
174
        window->counter = 0;
175
        window->average_tpt = IWL_INVALID_VALUE;
176
        window->stamp = 0;
177
}
178
 
179
/**
180
 * iwl_rate_scale_flush_windows - flush out the rate scale windows
181
 *
182
 * Returns the number of windows that have gathered data but were
183
 * not flushed.  If there were any that were not flushed, then
184
 * reschedule the rate flushing routine.
185
 */
186
static int iwl_rate_scale_flush_windows(struct iwl_rate_scale_priv *rs_priv)
187
{
188
        int unflushed = 0;
189
        int i;
190
        unsigned long flags;
191
 
192
        /*
193
         * For each rate, if we have collected data on that rate
194
         * and it has been more than IWL_RATE_WIN_FLUSH
195
         * since we flushed, clear out the gathered statistics
196
         */
197
        for (i = 0; i < IWL_RATE_COUNT; i++) {
198
                if (!rs_priv->win[i].counter)
199
                        continue;
200
 
201
                spin_lock_irqsave(&rs_priv->lock, flags);
202
                if (time_after(jiffies, rs_priv->win[i].stamp +
203
                               IWL_RATE_WIN_FLUSH)) {
204
                        IWL_DEBUG_RATE("flushing %d samples of rate "
205
                                       "index %d\n",
206
                                       rs_priv->win[i].counter, i);
207
                        iwl_clear_window(&rs_priv->win[i]);
208
                } else
209
                        unflushed++;
210
                spin_unlock_irqrestore(&rs_priv->lock, flags);
211
        }
212
 
213
        return unflushed;
214
}
215
 
216
#define IWL_RATE_FLUSH_MAX              5000    /* msec */
217
#define IWL_RATE_FLUSH_MIN              50      /* msec */
218
 
219
static void iwl_bg_rate_scale_flush(unsigned long data)
220
{
221
        struct iwl_rate_scale_priv *rs_priv = (void *)data;
222
        int unflushed = 0;
223
        unsigned long flags;
224
        u32 packet_count, duration, pps;
225
 
226
        IWL_DEBUG_RATE("enter\n");
227
 
228
        unflushed = iwl_rate_scale_flush_windows(rs_priv);
229
 
230
        spin_lock_irqsave(&rs_priv->lock, flags);
231
 
232
        rs_priv->flush_pending = 0;
233
 
234
        /* Number of packets Rx'd since last time this timer ran */
235
        packet_count = (rs_priv->tx_packets - rs_priv->last_tx_packets) + 1;
236
 
237
        rs_priv->last_tx_packets = rs_priv->tx_packets + 1;
238
 
239
        if (unflushed) {
240
                duration =
241
                    jiffies_to_msecs(jiffies - rs_priv->last_partial_flush);
242
/*              duration = jiffies_to_msecs(rs_priv->flush_time); */
243
 
244
                IWL_DEBUG_RATE("Tx'd %d packets in %dms\n",
245
                               packet_count, duration);
246
 
247
                /* Determine packets per second */
248
                if (duration)
249
                        pps = (packet_count * 1000) / duration;
250
                else
251
                        pps = 0;
252
 
253
                if (pps) {
254
                        duration = IWL_RATE_FLUSH_MAX / pps;
255
                        if (duration < IWL_RATE_FLUSH_MIN)
256
                                duration = IWL_RATE_FLUSH_MIN;
257
                } else
258
                        duration = IWL_RATE_FLUSH_MAX;
259
 
260
                rs_priv->flush_time = msecs_to_jiffies(duration);
261
 
262
                IWL_DEBUG_RATE("new flush period: %d msec ave %d\n",
263
                               duration, packet_count);
264
 
265
                mod_timer(&rs_priv->rate_scale_flush, jiffies +
266
                          rs_priv->flush_time);
267
 
268
                rs_priv->last_partial_flush = jiffies;
269
        }
270
 
271
        /* If there weren't any unflushed entries, we don't schedule the timer
272
         * to run again */
273
 
274
        rs_priv->last_flush = jiffies;
275
 
276
        spin_unlock_irqrestore(&rs_priv->lock, flags);
277
 
278
        IWL_DEBUG_RATE("leave\n");
279
}
280
 
281
/**
282
 * iwl_collect_tx_data - Update the success/failure sliding window
283
 *
284
 * We keep a sliding window of the last 64 packets transmitted
285
 * at this rate.  window->data contains the bitmask of successful
286
 * packets.
287
 */
288
static void iwl_collect_tx_data(struct iwl_rate_scale_priv *rs_priv,
289
                                struct iwl_rate_scale_data *window,
290
                                int success, int retries)
291
{
292
        unsigned long flags;
293
 
294
        if (!retries) {
295
                IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n");
296
                return;
297
        }
298
 
299
        while (retries--) {
300
                spin_lock_irqsave(&rs_priv->lock, flags);
301
 
302
                /* If we have filled up the window then subtract one from the
303
                 * success counter if the high-bit is counting toward
304
                 * success */
305
                if (window->counter == IWL_RATE_MAX_WINDOW) {
306
                        if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1)))
307
                                window->success_counter--;
308
                } else
309
                        window->counter++;
310
 
311
                /* Slide the window to the left one bit */
312
                window->data = (window->data << 1);
313
 
314
                /* If this packet was a success then set the low bit high */
315
                if (success) {
316
                        window->success_counter++;
317
                        window->data |= 1;
318
                }
319
 
320
                /* window->counter can't be 0 -- it is either >0 or
321
                 * IWL_RATE_MAX_WINDOW */
322
                window->success_ratio = 12800 * window->success_counter /
323
                    window->counter;
324
 
325
                /* Tag this window as having been updated */
326
                window->stamp = jiffies;
327
 
328
                spin_unlock_irqrestore(&rs_priv->lock, flags);
329
        }
330
}
331
 
332
static void rs_rate_init(void *priv_rate, void *priv_sta,
333
                         struct ieee80211_local *local, struct sta_info *sta)
334
{
335
        int i;
336
 
337
        IWL_DEBUG_RATE("enter\n");
338
 
339
        /* TODO: what is a good starting rate for STA? About middle? Maybe not
340
         * the lowest or the highest rate.. Could consider using RSSI from
341
         * previous packets? Need to have IEEE 802.1X auth succeed immediately
342
         * after assoc.. */
343
 
344
        for (i = IWL_RATE_COUNT - 1; i >= 0; i--) {
345
                if (sta->supp_rates & (1 << i)) {
346
                        sta->txrate = i;
347
                        break;
348
                }
349
        }
350
 
351
        sta->last_txrate = sta->txrate;
352
 
353
        /* For MODE_IEEE80211A mode it start at IWL_FIRST_OFDM_RATE */
354
        if (local->hw.conf.phymode == MODE_IEEE80211A)
355
                sta->last_txrate += IWL_FIRST_OFDM_RATE;
356
 
357
        IWL_DEBUG_RATE("leave\n");
358
}
359
 
360
static void *rs_alloc(struct ieee80211_local *local)
361
{
362
        return local->hw.priv;
363
}
364
 
365
/* rate scale requires free function to be implmented */
366
static void rs_free(void *priv)
367
{
368
        return;
369
}
370
static void rs_clear(void *priv)
371
{
372
        return;
373
}
374
 
375
 
376
static void *rs_alloc_sta(void *priv, gfp_t gfp)
377
{
378
        struct iwl_rate_scale_priv *rs_priv;
379
        int i;
380
 
381
        IWL_DEBUG_RATE("enter\n");
382
 
383
        rs_priv = kzalloc(sizeof(struct iwl_rate_scale_priv), gfp);
384
        if (!rs_priv) {
385
                IWL_DEBUG_RATE("leave: ENOMEM\n");
386
                return NULL;
387
        }
388
 
389
        spin_lock_init(&rs_priv->lock);
390
 
391
        rs_priv->start_rate = IWL_RATE_INVALID;
392
 
393
        /* default to just 802.11b */
394
        rs_priv->expected_tpt = iwl_expected_tpt_b;
395
 
396
        rs_priv->last_partial_flush = jiffies;
397
        rs_priv->last_flush = jiffies;
398
        rs_priv->flush_time = IWL_RATE_FLUSH;
399
        rs_priv->last_tx_packets = 0;
400
        rs_priv->ibss_sta_added = 0;
401
 
402
        init_timer(&rs_priv->rate_scale_flush);
403
        rs_priv->rate_scale_flush.data = (unsigned long)rs_priv;
404
        rs_priv->rate_scale_flush.function = &iwl_bg_rate_scale_flush;
405
 
406
        for (i = 0; i < IWL_RATE_COUNT; i++)
407
                iwl_clear_window(&rs_priv->win[i]);
408
 
409
        IWL_DEBUG_RATE("leave\n");
410
 
411
        return rs_priv;
412
}
413
 
414
static void rs_free_sta(void *priv, void *priv_sta)
415
{
416
        struct iwl_rate_scale_priv *rs_priv = priv_sta;
417
 
418
        IWL_DEBUG_RATE("enter\n");
419
        del_timer_sync(&rs_priv->rate_scale_flush);
420
        kfree(rs_priv);
421
        IWL_DEBUG_RATE("leave\n");
422
}
423
 
424
 
425
/*
426
 * get ieee prev rate from rate scale table.
427
 * for A and B mode we need to overright prev
428
 * value
429
 */
430
static int rs_adjust_next_rate(struct iwl_priv *priv, int rate)
431
{
432
        int next_rate = iwl_get_prev_ieee_rate(rate);
433
 
434
        switch (priv->phymode) {
435
        case MODE_IEEE80211A:
436
                if (rate == IWL_RATE_12M_INDEX)
437
                        next_rate = IWL_RATE_9M_INDEX;
438
                else if (rate == IWL_RATE_6M_INDEX)
439
                        next_rate = IWL_RATE_6M_INDEX;
440
                break;
441
        case MODE_IEEE80211B:
442
                if (rate == IWL_RATE_11M_INDEX_TABLE)
443
                        next_rate = IWL_RATE_5M_INDEX_TABLE;
444
                break;
445
        default:
446
                break;
447
        }
448
 
449
        return next_rate;
450
}
451
/**
452
 * rs_tx_status - Update rate control values based on Tx results
453
 *
454
 * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by
455
 * the hardware for each rate.
456
 */
457
static void rs_tx_status(void *priv_rate,
458
                         struct net_device *dev,
459
                         struct sk_buff *skb,
460
                         struct ieee80211_tx_status *tx_resp)
461
{
462
        u8 retries, current_count;
463
        int scale_rate_index, first_index, last_index;
464
        unsigned long flags;
465
        struct sta_info *sta;
466
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
467
        struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
468
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
469
        struct iwl_rate_scale_priv *rs_priv;
470
 
471
        IWL_DEBUG_RATE("enter\n");
472
 
473
        retries = tx_resp->retry_count;
474
 
475
        first_index = tx_resp->control.tx_rate;
476
        if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
477
                IWL_DEBUG_RATE("leave: Rate out of bounds: %0x for %d\n",
478
                               tx_resp->control.tx_rate, first_index);
479
                return;
480
        }
481
 
482
        sta = sta_info_get(local, hdr->addr1);
483
        if (!sta || !sta->rate_ctrl_priv) {
484
                if (sta)
485
                        sta_info_put(sta);
486
                IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
487
                return;
488
        }
489
 
490
        rs_priv = (void *)sta->rate_ctrl_priv;
491
 
492
        rs_priv->tx_packets++;
493
 
494
        scale_rate_index = first_index;
495
        last_index = first_index;
496
 
497
        /*
498
         * Update the window for each rate.  We determine which rates
499
         * were Tx'd based on the total number of retries vs. the number
500
         * of retries configured for each rate -- currently set to the
501
         * priv value 'retry_rate' vs. rate specific
502
         *
503
         * On exit from this while loop last_index indicates the rate
504
         * at which the frame was finally transmitted (or failed if no
505
         * ACK)
506
         */
507
        while (retries > 0) {
508
                if (retries < priv->retry_rate) {
509
                        current_count = retries;
510
                        last_index = scale_rate_index;
511
                } else {
512
                        current_count = priv->retry_rate;
513
                        last_index = rs_adjust_next_rate(priv,
514
                                                         scale_rate_index);
515
                }
516
 
517
                /* Update this rate accounting for as many retries
518
                 * as was used for it (per current_count) */
519
                iwl_collect_tx_data(rs_priv,
520
                                    &rs_priv->win[scale_rate_index],
521
                                    0, current_count);
522
                IWL_DEBUG_RATE("Update rate %d for %d retries.\n",
523
                               scale_rate_index, current_count);
524
 
525
                retries -= current_count;
526
 
527
                if (retries)
528
                        scale_rate_index =
529
                            rs_adjust_next_rate(priv, scale_rate_index);
530
        }
531
 
532
 
533
        /* Update the last index window with success/failure based on ACK */
534
        IWL_DEBUG_RATE("Update rate %d with %s.\n",
535
                       last_index,
536
                       (tx_resp->flags & IEEE80211_TX_STATUS_ACK) ?
537
                       "success" : "failure");
538
        iwl_collect_tx_data(rs_priv,
539
                            &rs_priv->win[last_index],
540
                            tx_resp->flags & IEEE80211_TX_STATUS_ACK, 1);
541
 
542
        /* We updated the rate scale window -- if its been more than
543
         * flush_time since the last run, schedule the flush
544
         * again */
545
        spin_lock_irqsave(&rs_priv->lock, flags);
546
 
547
        if (!rs_priv->flush_pending &&
548
            time_after(jiffies, rs_priv->last_partial_flush +
549
                       rs_priv->flush_time)) {
550
 
551
                rs_priv->flush_pending = 1;
552
                mod_timer(&rs_priv->rate_scale_flush,
553
                          jiffies + rs_priv->flush_time);
554
        }
555
 
556
        spin_unlock_irqrestore(&rs_priv->lock, flags);
557
 
558
        sta_info_put(sta);
559
 
560
        IWL_DEBUG_RATE("leave\n");
561
 
562
        return;
563
}
564
 
565
static struct ieee80211_rate *iwl_get_lowest_rate(struct ieee80211_local
566
                                                  *local)
567
{
568
        struct ieee80211_hw_mode *mode = local->oper_hw_mode;
569
        int i;
570
 
571
        for (i = 0; i < mode->num_rates; i++) {
572
                struct ieee80211_rate *rate = &mode->rates[i];
573
 
574
                if (rate->flags & IEEE80211_RATE_SUPPORTED)
575
                        return rate;
576
        }
577
 
578
        return &mode->rates[0];
579
}
580
 
581
static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
582
                                 u8 index, u16 rate_mask, int phymode)
583
{
584
        u8 high = IWL_RATE_INVALID;
585
        u8 low = IWL_RATE_INVALID;
586
 
587
        /* 802.11A walks to the next literal adjascent rate in
588
         * the rate table */
589
        if (unlikely(phymode == MODE_IEEE80211A)) {
590
                int i;
591
                u32 mask;
592
 
593
                /* Find the previous rate that is in the rate mask */
594
                i = index - 1;
595
                for (mask = (1 << i); i >= 0; i--, mask >>= 1) {
596
                        if (rate_mask & mask) {
597
                                low = i;
598
                                break;
599
                        }
600
                }
601
 
602
                /* Find the next rate that is in the rate mask */
603
                i = index + 1;
604
                for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
605
                        if (rate_mask & mask) {
606
                                high = i;
607
                                break;
608
                        }
609
                }
610
 
611
                return (high << 8) | low;
612
        }
613
 
614
        low = index;
615
        while (low != IWL_RATE_INVALID) {
616
                if (rs_priv->tgg)
617
                        low = iwl_rates[low].prev_rs_tgg;
618
                else
619
                        low = iwl_rates[low].prev_rs;
620
                if (low == IWL_RATE_INVALID)
621
                        break;
622
                if (rate_mask & (1 << low))
623
                        break;
624
                IWL_DEBUG_RATE("Skipping masked lower rate: %d\n", low);
625
        }
626
 
627
        high = index;
628
        while (high != IWL_RATE_INVALID) {
629
                if (rs_priv->tgg)
630
                        high = iwl_rates[high].next_rs_tgg;
631
                else
632
                        high = iwl_rates[high].next_rs;
633
                if (high == IWL_RATE_INVALID)
634
                        break;
635
                if (rate_mask & (1 << high))
636
                        break;
637
                IWL_DEBUG_RATE("Skipping masked higher rate: %d\n", high);
638
        }
639
 
640
        return (high << 8) | low;
641
}
642
 
643
/**
644
 * rs_get_rate - find the rate for the requested packet
645
 *
646
 * Returns the ieee80211_rate structure allocated by the driver.
647
 *
648
 * The rate control algorithm has no internal mapping between hw_mode's
649
 * rate ordering and the rate ordering used by the rate control algorithm.
650
 *
651
 * The rate control algorithm uses a single table of rates that goes across
652
 * the entire A/B/G spectrum vs. being limited to just one particular
653
 * hw_mode.
654
 *
655
 * As such, we can't convert the index obtained below into the hw_mode's
656
 * rate table and must reference the driver allocated rate table
657
 *
658
 */
659
static struct ieee80211_rate *rs_get_rate(void *priv_rate,
660
                                          struct net_device *dev,
661
                                          struct sk_buff *skb,
662
                                          struct rate_control_extra *extra)
663
{
664
        u8 low = IWL_RATE_INVALID;
665
        u8 high = IWL_RATE_INVALID;
666
        u16 high_low;
667
        int index;
668
        struct iwl_rate_scale_priv *rs_priv;
669
        struct iwl_rate_scale_data *window = NULL;
670
        int current_tpt = IWL_INVALID_VALUE;
671
        int low_tpt = IWL_INVALID_VALUE;
672
        int high_tpt = IWL_INVALID_VALUE;
673
        u32 fail_count;
674
        s8 scale_action = 0;
675
        unsigned long flags;
676
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
677
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
678
        struct sta_info *sta;
679
        u16 fc, rate_mask;
680
        struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
681
        DECLARE_MAC_BUF(mac);
682
 
683
        IWL_DEBUG_RATE("enter\n");
684
 
685
        memset(extra, 0, sizeof(*extra));
686
 
687
        fc = le16_to_cpu(hdr->frame_control);
688
        if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
689
            (is_multicast_ether_addr(hdr->addr1))) {
690
                /* Send management frames and broadcast/multicast data using
691
                 * lowest rate. */
692
                /* TODO: this could probably be improved.. */
693
                IWL_DEBUG_RATE("leave: lowest rate (not data or is "
694
                               "multicast)\n");
695
 
696
                return iwl_get_lowest_rate(local);
697
        }
698
 
699
        sta = sta_info_get(local, hdr->addr1);
700
        if (!sta || !sta->rate_ctrl_priv) {
701
                IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
702
                if (sta)
703
                        sta_info_put(sta);
704
                return NULL;
705
        }
706
 
707
        rate_mask = sta->supp_rates;
708
        index = min(sta->last_txrate & 0xffff, IWL_RATE_COUNT - 1);
709
 
710
        if (priv->phymode == (u8) MODE_IEEE80211A)
711
                rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
712
 
713
        rs_priv = (void *)sta->rate_ctrl_priv;
714
 
715
        if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
716
            !rs_priv->ibss_sta_added) {
717
                u8 sta_id = iwl_hw_find_station(priv, hdr->addr1);
718
 
719
                if (sta_id == IWL_INVALID_STATION) {
720
                        IWL_DEBUG_RATE("LQ: ADD station %s\n",
721
                                       print_mac(mac, hdr->addr1));
722
                        sta_id = iwl_add_station(priv,
723
                                    hdr->addr1, 0, CMD_ASYNC);
724
                }
725
                if (sta_id != IWL_INVALID_STATION)
726
                        rs_priv->ibss_sta_added = 1;
727
        }
728
 
729
        spin_lock_irqsave(&rs_priv->lock, flags);
730
 
731
        if (rs_priv->start_rate != IWL_RATE_INVALID) {
732
                index = rs_priv->start_rate;
733
                rs_priv->start_rate = IWL_RATE_INVALID;
734
        }
735
 
736
        window = &(rs_priv->win[index]);
737
 
738
        fail_count = window->counter - window->success_counter;
739
 
740
        if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) &&
741
             (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) {
742
                window->average_tpt = IWL_INVALID_VALUE;
743
                spin_unlock_irqrestore(&rs_priv->lock, flags);
744
 
745
                IWL_DEBUG_RATE("Invalid average_tpt on rate %d: "
746
                               "counter: %d, success_counter: %d, "
747
                               "expected_tpt is %sNULL\n",
748
                               index,
749
                               window->counter,
750
                               window->success_counter,
751
                               rs_priv->expected_tpt ? "not " : "");
752
                goto out;
753
 
754
        }
755
 
756
        window->average_tpt = ((window->success_ratio *
757
                                rs_priv->expected_tpt[index] + 64) / 128);
758
        current_tpt = window->average_tpt;
759
 
760
        high_low = iwl_get_adjacent_rate(rs_priv, index, rate_mask,
761
                                         local->hw.conf.phymode);
762
        low = high_low & 0xff;
763
        high = (high_low >> 8) & 0xff;
764
 
765
        if (low != IWL_RATE_INVALID)
766
                low_tpt = rs_priv->win[low].average_tpt;
767
 
768
        if (high != IWL_RATE_INVALID)
769
                high_tpt = rs_priv->win[high].average_tpt;
770
 
771
        spin_unlock_irqrestore(&rs_priv->lock, flags);
772
 
773
        scale_action = 1;
774
 
775
        if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) {
776
                IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
777
                scale_action = -1;
778
        } else if ((low_tpt == IWL_INVALID_VALUE) &&
779
                   (high_tpt == IWL_INVALID_VALUE))
780
                scale_action = 1;
781
        else if ((low_tpt != IWL_INVALID_VALUE) &&
782
                   (high_tpt != IWL_INVALID_VALUE)
783
                   && (low_tpt < current_tpt)
784
                   && (high_tpt < current_tpt)) {
785
                IWL_DEBUG_RATE("No action -- low [%d] & high [%d] < "
786
                               "current_tpt [%d]\n",
787
                               low_tpt, high_tpt, current_tpt);
788
                scale_action = 0;
789
        } else {
790
                if (high_tpt != IWL_INVALID_VALUE) {
791
                        if (high_tpt > current_tpt)
792
                                scale_action = 1;
793
                        else {
794
                                IWL_DEBUG_RATE
795
                                    ("decrease rate because of high tpt\n");
796
                                scale_action = -1;
797
                        }
798
                } else if (low_tpt != IWL_INVALID_VALUE) {
799
                        if (low_tpt > current_tpt) {
800
                                IWL_DEBUG_RATE
801
                                    ("decrease rate because of low tpt\n");
802
                                scale_action = -1;
803
                        } else
804
                                scale_action = 1;
805
                }
806
        }
807
 
808
        if ((window->success_ratio > IWL_RATE_HIGH_TH) ||
809
            (current_tpt > window->average_tpt)) {
810
                IWL_DEBUG_RATE("No action -- success_ratio [%d] > HIGH_TH or "
811
                               "current_tpt [%d] > average_tpt [%d]\n",
812
                               window->success_ratio,
813
                               current_tpt, window->average_tpt);
814
                scale_action = 0;
815
        }
816
 
817
        switch (scale_action) {
818
        case -1:
819
                if (low != IWL_RATE_INVALID)
820
                        index = low;
821
                break;
822
 
823
        case 1:
824
                if (high != IWL_RATE_INVALID)
825
                        index = high;
826
 
827
                break;
828
 
829
        case 0:
830
        default:
831
                break;
832
        }
833
 
834
        IWL_DEBUG_RATE("Selected %d (action %d) - low %d high %d\n",
835
                       index, scale_action, low, high);
836
 
837
 out:
838
 
839
        sta->last_txrate = index;
840
        if (priv->phymode == (u8) MODE_IEEE80211A)
841
                sta->txrate = sta->last_txrate - IWL_FIRST_OFDM_RATE;
842
        else
843
                sta->txrate = sta->last_txrate;
844
 
845
        sta_info_put(sta);
846
 
847
        IWL_DEBUG_RATE("leave: %d\n", index);
848
 
849
        return &priv->ieee_rates[index];
850
}
851
 
852
static struct rate_control_ops rs_ops = {
853
        .module = NULL,
854
        .name = RS_NAME,
855
        .tx_status = rs_tx_status,
856
        .get_rate = rs_get_rate,
857
        .rate_init = rs_rate_init,
858
        .clear = rs_clear,
859
        .alloc = rs_alloc,
860
        .free = rs_free,
861
        .alloc_sta = rs_alloc_sta,
862
        .free_sta = rs_free_sta,
863
};
864
 
865
int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
866
{
867
        struct ieee80211_local *local = hw_to_local(hw);
868
        struct iwl_priv *priv = hw->priv;
869
        struct iwl_rate_scale_priv *rs_priv;
870
        struct sta_info *sta;
871
        unsigned long flags;
872
        int count = 0, i;
873
        u32 samples = 0, success = 0, good = 0;
874
        unsigned long now = jiffies;
875
        u32 max_time = 0;
876
 
877
        sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
878
        if (!sta || !sta->rate_ctrl_priv) {
879
                if (sta) {
880
                        sta_info_put(sta);
881
                        IWL_DEBUG_RATE("leave - no private rate data!\n");
882
                } else
883
                        IWL_DEBUG_RATE("leave - no station!\n");
884
                return sprintf(buf, "station %d not found\n", sta_id);
885
        }
886
 
887
        rs_priv = (void *)sta->rate_ctrl_priv;
888
        spin_lock_irqsave(&rs_priv->lock, flags);
889
        i = IWL_RATE_54M_INDEX;
890
        while (1) {
891
                u64 mask;
892
                int j;
893
 
894
                count +=
895
                    sprintf(&buf[count], " %2dMbs: ", iwl_rates[i].ieee / 2);
896
 
897
                mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
898
                for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
899
                        buf[count++] =
900
                            (rs_priv->win[i].data & mask) ? '1' : '0';
901
 
902
                samples += rs_priv->win[i].counter;
903
                good += rs_priv->win[i].success_counter;
904
                success += rs_priv->win[i].success_counter * iwl_rates[i].ieee;
905
 
906
                if (rs_priv->win[i].stamp) {
907
                        int delta =
908
                            jiffies_to_msecs(now - rs_priv->win[i].stamp);
909
 
910
                        if (delta > max_time)
911
                                max_time = delta;
912
 
913
                        count += sprintf(&buf[count], "%5dms\n", delta);
914
                } else
915
                        buf[count++] = '\n';
916
 
917
                j = iwl_get_prev_ieee_rate(i);
918
                if (j == i)
919
                        break;
920
                i = j;
921
        }
922
        spin_unlock_irqrestore(&rs_priv->lock, flags);
923
        sta_info_put(sta);
924
 
925
        /* Display the average rate of all samples taken.
926
         *
927
         * NOTE:  We multiple # of samples by 2 since the IEEE measurement
928
         * added from iwl_rates is actually 2X the rate */
929
        if (samples)
930
                count += sprintf(
931
                        &buf[count],
932
                        "\nAverage rate is %3d.%02dMbs over last %4dms\n"
933
                        "%3d%% success (%d good packets over %d tries)\n",
934
                        success / (2 * samples), (success * 5 / samples) % 10,
935
                        max_time, good * 100 / samples, good, samples);
936
        else
937
                count += sprintf(&buf[count], "\nAverage rate: 0Mbs\n");
938
 
939
        return count;
940
}
941
 
942
void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
943
{
944
        struct iwl_priv *priv = hw->priv;
945
        s32 rssi = 0;
946
        unsigned long flags;
947
        struct ieee80211_local *local = hw_to_local(hw);
948
        struct iwl_rate_scale_priv *rs_priv;
949
        struct sta_info *sta;
950
 
951
        IWL_DEBUG_RATE("enter\n");
952
 
953
        if (!local->rate_ctrl->ops->name ||
954
            strcmp(local->rate_ctrl->ops->name, RS_NAME)) {
955
                IWL_WARNING("iwl-3945-rs not selected as rate control algo!\n");
956
                IWL_DEBUG_RATE("leave - mac80211 picked the wrong RC algo.\n");
957
                return;
958
        }
959
 
960
        sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
961
        if (!sta || !sta->rate_ctrl_priv) {
962
                if (sta)
963
                        sta_info_put(sta);
964
                IWL_DEBUG_RATE("leave - no private rate data!\n");
965
                return;
966
        }
967
 
968
        rs_priv = (void *)sta->rate_ctrl_priv;
969
 
970
        spin_lock_irqsave(&rs_priv->lock, flags);
971
 
972
        rs_priv->tgg = 0;
973
        switch (priv->phymode) {
974
        case MODE_IEEE80211G:
975
                if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) {
976
                        rs_priv->tgg = 1;
977
                        rs_priv->expected_tpt = iwl_expected_tpt_g_prot;
978
                } else
979
                        rs_priv->expected_tpt = iwl_expected_tpt_g;
980
                break;
981
 
982
        case MODE_IEEE80211A:
983
                rs_priv->expected_tpt = iwl_expected_tpt_a;
984
                break;
985
 
986
        default:
987
                IWL_WARNING("Invalid phymode.  Defaulting to 802.11b\n");
988
        case MODE_IEEE80211B:
989
                rs_priv->expected_tpt = iwl_expected_tpt_b;
990
                break;
991
        }
992
 
993
        sta_info_put(sta);
994
        spin_unlock_irqrestore(&rs_priv->lock, flags);
995
 
996
        rssi = priv->last_rx_rssi;
997
        if (rssi == 0)
998
                rssi = IWL_MIN_RSSI_VAL;
999
 
1000
        IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi);
1001
 
1002
        rs_priv->start_rate = iwl_get_rate_index_by_rssi(rssi, priv->phymode);
1003
 
1004
        IWL_DEBUG_RATE("leave: rssi %d assign rate index: "
1005
                       "%d (plcp 0x%x)\n", rssi, rs_priv->start_rate,
1006
                       iwl_rates[rs_priv->start_rate].plcp);
1007
}
1008
 
1009
void iwl_rate_control_register(struct ieee80211_hw *hw)
1010
{
1011
        ieee80211_rate_control_register(&rs_ops);
1012
}
1013
 
1014
void iwl_rate_control_unregister(struct ieee80211_hw *hw)
1015
{
1016
        ieee80211_rate_control_unregister(&rs_ops);
1017
}
1018
 
1019
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.