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