~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/mac80211/compatible/net/mac80211/iwlwifi_rc80211_simple.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
 * Copyright 2002-2005, Instant802 Networks, Inc.
 
3
 * Copyright 2005, Devicescape Software, Inc.
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 */
 
9
 
 
10
#include <linux/module.h>
 
11
#include <linux/init.h>
 
12
#include <linux/netdevice.h>
 
13
#include <linux/types.h>
 
14
#include <linux/slab.h>
 
15
#include <linux/skbuff.h>
 
16
#include <linux/compiler.h>
 
17
 
 
18
#include <net/mac80211.h>
 
19
#include "ieee80211_i.h"
 
20
#include "ieee80211_rate.h"
 
21
#include "debugfs.h"
 
22
 
 
23
 
 
24
/* This is a minimal implementation of TX rate controlling that can be used
 
25
 * as the default when no improved mechanisms are available. */
 
26
 
 
27
 
 
28
#define RATE_CONTROL_EMERG_DEC 2
 
29
#define RATE_CONTROL_INTERVAL (HZ / 20)
 
30
#define RATE_CONTROL_MIN_TX 10
 
31
 
 
32
MODULE_ALIAS("rc80211_default");
 
33
 
 
34
static void rate_control_rate_inc(struct ieee80211_local *local,
 
35
                                  struct sta_info *sta)
 
36
{
 
37
        struct ieee80211_sub_if_data *sdata;
 
38
        struct ieee80211_hw_mode *mode;
 
39
        int i = sta->txrate;
 
40
        int maxrate;
 
41
 
 
42
        sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
 
43
        if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) {
 
44
                /* forced unicast rate - do not change STA rate */
 
45
                return;
 
46
        }
 
47
 
 
48
        mode = local->oper_hw_mode;
 
49
        maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1;
 
50
 
 
51
        if (i > mode->num_rates)
 
52
                i = mode->num_rates - 2;
 
53
 
 
54
        while (i + 1 < mode->num_rates) {
 
55
                i++;
 
56
                if (sta->supp_rates & BIT(i) &&
 
57
                    mode->rates[i].flags & IEEE80211_RATE_SUPPORTED &&
 
58
                    (maxrate < 0 || i <= maxrate)) {
 
59
                        sta->txrate = i;
 
60
                        break;
 
61
                }
 
62
        }
 
63
}
 
64
 
 
65
 
 
66
static void rate_control_rate_dec(struct ieee80211_local *local,
 
67
                                  struct sta_info *sta)
 
68
{
 
69
        struct ieee80211_sub_if_data *sdata;
 
70
        struct ieee80211_hw_mode *mode;
 
71
        int i = sta->txrate;
 
72
 
 
73
        sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
 
74
        if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) {
 
75
                /* forced unicast rate - do not change STA rate */
 
76
                return;
 
77
        }
 
78
 
 
79
        mode = local->oper_hw_mode;
 
80
        if (i > mode->num_rates)
 
81
                i = mode->num_rates;
 
82
 
 
83
        while (i > 0) {
 
84
                i--;
 
85
                if (sta->supp_rates & BIT(i) &&
 
86
                    mode->rates[i].flags & IEEE80211_RATE_SUPPORTED) {
 
87
                        sta->txrate = i;
 
88
                        break;
 
89
                }
 
90
        }
 
91
}
 
92
 
 
93
 
 
94
static struct ieee80211_rate *
 
95
rate_control_lowest_rate(struct ieee80211_local *local,
 
96
                         struct ieee80211_hw_mode *mode)
 
97
{
 
98
        int i;
 
99
 
 
100
        for (i = 0; i < mode->num_rates; i++) {
 
101
                struct ieee80211_rate *rate = &mode->rates[i];
 
102
 
 
103
                if (rate->flags & IEEE80211_RATE_SUPPORTED)
 
104
                        return rate;
 
105
        }
 
106
 
 
107
        printk(KERN_DEBUG "rate_control_lowest_rate - no supported rates "
 
108
               "found\n");
 
109
        return &mode->rates[0];
 
110
}
 
111
 
 
112
 
 
113
struct global_rate_control {
 
114
        int dummy;
 
115
};
 
116
 
 
117
struct sta_rate_control {
 
118
        unsigned long last_rate_change;
 
119
        u32 tx_num_failures;
 
120
        u32 tx_num_xmit;
 
121
 
 
122
        unsigned long avg_rate_update;
 
123
        u32 tx_avg_rate_sum;
 
124
        u32 tx_avg_rate_num;
 
125
 
 
126
#ifdef CONFIG_MAC80211_DEBUGFS
 
127
        struct dentry *tx_avg_rate_sum_dentry;
 
128
        struct dentry *tx_avg_rate_num_dentry;
 
129
#endif
 
130
};
 
131
 
 
132
 
 
133
static void rate_control_simple_tx_status(void *priv, struct net_device *dev,
 
134
                                          struct sk_buff *skb,
 
135
                                          struct iwlwifi_ieee80211_tx_status *status)
 
136
{
 
137
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
138
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 
139
        struct sta_info *sta;
 
140
        struct sta_rate_control *srctrl;
 
141
 
 
142
        sta = iwlwifi_sta_info_get(local, hdr->addr1);
 
143
 
 
144
        if (!sta)
 
145
            return;
 
146
 
 
147
        srctrl = sta->rate_ctrl_priv;
 
148
        srctrl->tx_num_xmit++;
 
149
        if (status->excessive_retries) {
 
150
                sta->antenna_sel_tx = sta->antenna_sel_tx == 1 ? 2 : 1;
 
151
                sta->antenna_sel_rx = sta->antenna_sel_rx == 1 ? 2 : 1;
 
152
                if (local->sta_antenna_sel == STA_ANTENNA_SEL_SW_CTRL_DEBUG) {
 
153
                        printk(KERN_DEBUG "%s: " MAC_FMT " TX antenna --> %d "
 
154
                               "RX antenna --> %d (@%lu)\n",
 
155
                               dev->name, MAC_ARG(hdr->addr1),
 
156
                               sta->antenna_sel_tx, sta->antenna_sel_rx, jiffies);
 
157
                }
 
158
                srctrl->tx_num_failures++;
 
159
                sta->tx_retry_failed++;
 
160
                sta->tx_num_consecutive_failures++;
 
161
                sta->tx_num_mpdu_fail++;
 
162
        } else {
 
163
                sta->last_ack_rssi[0] = sta->last_ack_rssi[1];
 
164
                sta->last_ack_rssi[1] = sta->last_ack_rssi[2];
 
165
                sta->last_ack_rssi[2] = status->ack_signal;
 
166
                sta->tx_num_consecutive_failures = 0;
 
167
                sta->tx_num_mpdu_ok++;
 
168
        }
 
169
        sta->tx_retry_count += status->retry_count;
 
170
        sta->tx_num_mpdu_fail += status->retry_count;
 
171
 
 
172
        if (time_after(jiffies,
 
173
                       srctrl->last_rate_change + RATE_CONTROL_INTERVAL) &&
 
174
                srctrl->tx_num_xmit > RATE_CONTROL_MIN_TX) {
 
175
                u32 per_failed;
 
176
                srctrl->last_rate_change = jiffies;
 
177
 
 
178
                per_failed = (100 * sta->tx_num_mpdu_fail) /
 
179
                        (sta->tx_num_mpdu_fail + sta->tx_num_mpdu_ok);
 
180
                /* TODO: calculate average per_failed to make adjusting
 
181
                 * parameters easier */
 
182
#if 0
 
183
                if (net_ratelimit()) {
 
184
                        printk(KERN_DEBUG "MPDU fail=%d ok=%d per_failed=%d\n",
 
185
                               sta->tx_num_mpdu_fail, sta->tx_num_mpdu_ok,
 
186
                               per_failed);
 
187
                }
 
188
#endif
 
189
 
 
190
                /*
 
191
                 * XXX: Make these configurable once we have an
 
192
                 * interface to the rate control algorithms
 
193
                 */
 
194
                if (per_failed > RATE_CONTROL_NUM_DOWN) {
 
195
                        rate_control_rate_dec(local, sta);
 
196
                } else if (per_failed < RATE_CONTROL_NUM_UP) {
 
197
                        rate_control_rate_inc(local, sta);
 
198
                }
 
199
                srctrl->tx_avg_rate_sum += status->control.rate->rate;
 
200
                srctrl->tx_avg_rate_num++;
 
201
                srctrl->tx_num_failures = 0;
 
202
                srctrl->tx_num_xmit = 0;
 
203
        } else if (sta->tx_num_consecutive_failures >=
 
204
                   RATE_CONTROL_EMERG_DEC) {
 
205
                rate_control_rate_dec(local, sta);
 
206
        }
 
207
 
 
208
        if (srctrl->avg_rate_update + 60 * HZ < jiffies) {
 
209
                srctrl->avg_rate_update = jiffies;
 
210
                if (srctrl->tx_avg_rate_num > 0) {
 
211
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 
212
                        printk(KERN_DEBUG "%s: STA " MAC_FMT " Average rate: "
 
213
                               "%d (%d/%d)\n",
 
214
                               dev->name, MAC_ARG(sta->addr),
 
215
                               srctrl->tx_avg_rate_sum /
 
216
                               srctrl->tx_avg_rate_num,
 
217
                               srctrl->tx_avg_rate_sum,
 
218
                               srctrl->tx_avg_rate_num);
 
219
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
220
                        srctrl->tx_avg_rate_sum = 0;
 
221
                        srctrl->tx_avg_rate_num = 0;
 
222
                }
 
223
        }
 
224
 
 
225
        iwlwifi_sta_info_put(sta);
 
226
}
 
227
 
 
228
 
 
229
static struct ieee80211_rate *
 
230
rate_control_simple_get_rate(void *priv, struct net_device *dev,
 
231
                             struct sk_buff *skb,
 
232
                             struct rate_control_extra *extra)
 
233
{
 
234
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
235
        struct ieee80211_sub_if_data *sdata;
 
236
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 
237
        struct ieee80211_hw_mode *mode = extra->mode;
 
238
        struct sta_info *sta;
 
239
        int rateidx, nonerp_idx;
 
240
        u16 fc;
 
241
 
 
242
        memset(extra, 0, sizeof(*extra));
 
243
 
 
244
        fc = le16_to_cpu(hdr->frame_control);
 
245
        if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
 
246
            (hdr->addr1[0] & 0x01)) {
 
247
                /* Send management frames and broadcast/multicast data using
 
248
                 * lowest rate. */
 
249
                /* TODO: this could probably be improved.. */
 
250
                return rate_control_lowest_rate(local, mode);
 
251
        }
 
252
 
 
253
        sta = iwlwifi_sta_info_get(local, hdr->addr1);
 
254
 
 
255
        if (!sta)
 
256
                return rate_control_lowest_rate(local, mode);
 
257
 
 
258
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
259
        if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
 
260
                sta->txrate = sdata->bss->force_unicast_rateidx;
 
261
 
 
262
        rateidx = sta->txrate;
 
263
 
 
264
        if (rateidx >= mode->num_rates)
 
265
                rateidx = mode->num_rates - 1;
 
266
 
 
267
        sta->last_txrate = rateidx;
 
268
        nonerp_idx = rateidx;
 
269
        while (nonerp_idx > 0 &&
 
270
               ((mode->rates[nonerp_idx].flags & IEEE80211_RATE_ERP) ||
 
271
                !(mode->rates[nonerp_idx].flags & IEEE80211_RATE_SUPPORTED) ||
 
272
                !(sta->supp_rates & BIT(nonerp_idx))))
 
273
                nonerp_idx--;
 
274
        extra->nonerp = &mode->rates[nonerp_idx];
 
275
 
 
276
        iwlwifi_sta_info_put(sta);
 
277
 
 
278
        return &mode->rates[rateidx];
 
279
}
 
280
 
 
281
 
 
282
static void rate_control_simple_rate_init(void *priv, void *priv_sta,
 
283
                                          struct ieee80211_local *local,
 
284
                                          struct sta_info *sta)
 
285
{
 
286
        struct ieee80211_hw_mode *mode;
 
287
        int i;
 
288
        sta->txrate = 0;
 
289
        mode = local->oper_hw_mode;
 
290
        /* TODO: This routine should consider using RSSI from previous packets
 
291
         * as we need to have IEEE 802.1X auth succeed immediately after assoc..
 
292
         * Until that method is implemented, we will use the lowest supported rate
 
293
         * as a workaround, */
 
294
        for (i = 0; i < mode->num_rates; i++) {
 
295
                if ((sta->supp_rates & BIT(i)) &&
 
296
                    (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) {
 
297
                        sta->txrate = i;
 
298
                        break;
 
299
                }
 
300
        }
 
301
}
 
302
 
 
303
 
 
304
static void * rate_control_simple_alloc(struct ieee80211_local *local)
 
305
{
 
306
        struct global_rate_control *rctrl;
 
307
 
 
308
        rctrl = kzalloc(sizeof(*rctrl), GFP_ATOMIC);
 
309
 
 
310
        return rctrl;
 
311
}
 
312
 
 
313
 
 
314
static void rate_control_simple_free(void *priv)
 
315
{
 
316
        struct global_rate_control *rctrl = priv;
 
317
        kfree(rctrl);
 
318
}
 
319
 
 
320
 
 
321
static void rate_control_simple_clear(void *priv)
 
322
{
 
323
}
 
324
 
 
325
 
 
326
static void * rate_control_simple_alloc_sta(void *priv, gfp_t gfp)
 
327
{
 
328
        struct sta_rate_control *rctrl;
 
329
 
 
330
        rctrl = kzalloc(sizeof(*rctrl), gfp);
 
331
 
 
332
        return rctrl;
 
333
}
 
334
 
 
335
 
 
336
static void rate_control_simple_free_sta(void *priv, void *priv_sta)
 
337
{
 
338
        struct sta_rate_control *rctrl = priv_sta;
 
339
        kfree(rctrl);
 
340
}
 
341
 
 
342
#ifdef CONFIG_MAC80211_DEBUGFS
 
343
 
 
344
static int open_file_generic(struct inode *inode, struct file *file)
 
345
{
 
346
        file->private_data = inode->i_private;
 
347
        return 0;
 
348
}
 
349
 
 
350
static ssize_t sta_tx_avg_rate_sum_read(struct file *file,
 
351
                                        char __user *userbuf,
 
352
                                        size_t count, loff_t *ppos)
 
353
{
 
354
        struct sta_rate_control *srctrl = file->private_data;
 
355
        char buf[20];
 
356
 
 
357
        sprintf(buf, "%d\n", srctrl->tx_avg_rate_sum);
 
358
        return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
 
359
}
 
360
 
 
361
static const struct file_operations sta_tx_avg_rate_sum_ops = {
 
362
        .read = sta_tx_avg_rate_sum_read,
 
363
        .open = open_file_generic,
 
364
};
 
365
 
 
366
static ssize_t sta_tx_avg_rate_num_read(struct file *file,
 
367
                                        char __user *userbuf,
 
368
                                        size_t count, loff_t *ppos)
 
369
{
 
370
        struct sta_rate_control *srctrl = file->private_data;
 
371
        char buf[20];
 
372
 
 
373
        sprintf(buf, "%d\n", srctrl->tx_avg_rate_num);
 
374
        return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
 
375
}
 
376
 
 
377
static const struct file_operations sta_tx_avg_rate_num_ops = {
 
378
        .read = sta_tx_avg_rate_num_read,
 
379
        .open = open_file_generic,
 
380
};
 
381
 
 
382
static void rate_control_simple_add_sta_debugfs(void *priv, void *priv_sta,
 
383
                                                struct dentry *dir)
 
384
{
 
385
        struct sta_rate_control *srctrl = priv_sta;
 
386
 
 
387
        srctrl->tx_avg_rate_num_dentry =
 
388
                debugfs_create_file("rc_simple_sta_tx_avg_rate_num", 0400,
 
389
                                    dir, srctrl, &sta_tx_avg_rate_num_ops);
 
390
        srctrl->tx_avg_rate_sum_dentry =
 
391
                debugfs_create_file("rc_simple_sta_tx_avg_rate_sum", 0400,
 
392
                                    dir, srctrl, &sta_tx_avg_rate_sum_ops);
 
393
}
 
394
 
 
395
static void rate_control_simple_remove_sta_debugfs(void *priv, void *priv_sta)
 
396
{
 
397
        struct sta_rate_control *srctrl = priv_sta;
 
398
 
 
399
        debugfs_remove(srctrl->tx_avg_rate_sum_dentry);
 
400
        debugfs_remove(srctrl->tx_avg_rate_num_dentry);
 
401
}
 
402
#endif
 
403
 
 
404
static struct rate_control_ops rate_control_simple = {
 
405
        .module = THIS_MODULE,
 
406
        .name = "simple",
 
407
        .tx_status = rate_control_simple_tx_status,
 
408
        .get_rate = rate_control_simple_get_rate,
 
409
        .rate_init = rate_control_simple_rate_init,
 
410
        .clear = rate_control_simple_clear,
 
411
        .alloc = rate_control_simple_alloc,
 
412
        .free = rate_control_simple_free,
 
413
        .alloc_sta = rate_control_simple_alloc_sta,
 
414
        .free_sta = rate_control_simple_free_sta,
 
415
#ifdef CONFIG_MAC80211_DEBUGFS
 
416
        .add_sta_debugfs = rate_control_simple_add_sta_debugfs,
 
417
        .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs,
 
418
#endif
 
419
};
 
420
 
 
421
 
 
422
static int __init rate_control_simple_init(void)
 
423
{
 
424
        return iwlwifi_ieee80211_rate_control_register(&rate_control_simple);
 
425
}
 
426
 
 
427
 
 
428
static void __exit rate_control_simple_exit(void)
 
429
{
 
430
        iwlwifi_ieee80211_rate_control_unregister(&rate_control_simple);
 
431
}
 
432
 
 
433
 
 
434
module_init(rate_control_simple_init);
 
435
module_exit(rate_control_simple_exit);
 
436
 
 
437
MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211");
 
438
MODULE_LICENSE("GPL");