linux/net/mac80211/rate.c
<<
>>
Prefs
   1/*
   2 * Copyright 2002-2005, Instant802 Networks, Inc.
   3 * Copyright 2005-2006, Devicescape Software, Inc.
   4 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/rtnetlink.h>
  13#include "rate.h"
  14#include "ieee80211_i.h"
  15#include "debugfs.h"
  16
  17struct rate_control_alg {
  18        struct list_head list;
  19        struct rate_control_ops *ops;
  20};
  21
  22static LIST_HEAD(rate_ctrl_algs);
  23static DEFINE_MUTEX(rate_ctrl_mutex);
  24
  25static char *ieee80211_default_rc_algo = CONFIG_MAC80211_RC_DEFAULT;
  26module_param(ieee80211_default_rc_algo, charp, 0644);
  27MODULE_PARM_DESC(ieee80211_default_rc_algo,
  28                 "Default rate control algorithm for mac80211 to use");
  29
  30int ieee80211_rate_control_register(struct rate_control_ops *ops)
  31{
  32        struct rate_control_alg *alg;
  33
  34        if (!ops->name)
  35                return -EINVAL;
  36
  37        mutex_lock(&rate_ctrl_mutex);
  38        list_for_each_entry(alg, &rate_ctrl_algs, list) {
  39                if (!strcmp(alg->ops->name, ops->name)) {
  40                        /* don't register an algorithm twice */
  41                        WARN_ON(1);
  42                        mutex_unlock(&rate_ctrl_mutex);
  43                        return -EALREADY;
  44                }
  45        }
  46
  47        alg = kzalloc(sizeof(*alg), GFP_KERNEL);
  48        if (alg == NULL) {
  49                mutex_unlock(&rate_ctrl_mutex);
  50                return -ENOMEM;
  51        }
  52        alg->ops = ops;
  53
  54        list_add_tail(&alg->list, &rate_ctrl_algs);
  55        mutex_unlock(&rate_ctrl_mutex);
  56
  57        return 0;
  58}
  59EXPORT_SYMBOL(ieee80211_rate_control_register);
  60
  61void ieee80211_rate_control_unregister(struct rate_control_ops *ops)
  62{
  63        struct rate_control_alg *alg;
  64
  65        mutex_lock(&rate_ctrl_mutex);
  66        list_for_each_entry(alg, &rate_ctrl_algs, list) {
  67                if (alg->ops == ops) {
  68                        list_del(&alg->list);
  69                        kfree(alg);
  70                        break;
  71                }
  72        }
  73        mutex_unlock(&rate_ctrl_mutex);
  74}
  75EXPORT_SYMBOL(ieee80211_rate_control_unregister);
  76
  77static struct rate_control_ops *
  78ieee80211_try_rate_control_ops_get(const char *name)
  79{
  80        struct rate_control_alg *alg;
  81        struct rate_control_ops *ops = NULL;
  82
  83        if (!name)
  84                return NULL;
  85
  86        mutex_lock(&rate_ctrl_mutex);
  87        list_for_each_entry(alg, &rate_ctrl_algs, list) {
  88                if (!strcmp(alg->ops->name, name))
  89                        if (try_module_get(alg->ops->module)) {
  90                                ops = alg->ops;
  91                                break;
  92                        }
  93        }
  94        mutex_unlock(&rate_ctrl_mutex);
  95        return ops;
  96}
  97
  98/* Get the rate control algorithm. */
  99static struct rate_control_ops *
 100ieee80211_rate_control_ops_get(const char *name)
 101{
 102        struct rate_control_ops *ops;
 103        const char *alg_name;
 104
 105        if (!name)
 106                alg_name = ieee80211_default_rc_algo;
 107        else
 108                alg_name = name;
 109
 110        ops = ieee80211_try_rate_control_ops_get(alg_name);
 111        if (!ops) {
 112                request_module("rc80211_%s", alg_name);
 113                ops = ieee80211_try_rate_control_ops_get(alg_name);
 114        }
 115        if (!ops && name)
 116                /* try default if specific alg requested but not found */
 117                ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo);
 118
 119        /* try built-in one if specific alg requested but not found */
 120        if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT))
 121                ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
 122
 123        return ops;
 124}
 125
 126static void ieee80211_rate_control_ops_put(struct rate_control_ops *ops)
 127{
 128        module_put(ops->module);
 129}
 130
 131#ifdef CONFIG_MAC80211_DEBUGFS
 132static ssize_t rcname_read(struct file *file, char __user *userbuf,
 133                           size_t count, loff_t *ppos)
 134{
 135        struct rate_control_ref *ref = file->private_data;
 136        int len = strlen(ref->ops->name);
 137
 138        return simple_read_from_buffer(userbuf, count, ppos,
 139                                       ref->ops->name, len);
 140}
 141
 142static const struct file_operations rcname_ops = {
 143        .read = rcname_read,
 144        .open = mac80211_open_file_generic,
 145};
 146#endif
 147
 148struct rate_control_ref *rate_control_alloc(const char *name,
 149                                            struct ieee80211_local *local)
 150{
 151        struct dentry *debugfsdir = NULL;
 152        struct rate_control_ref *ref;
 153
 154        ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
 155        if (!ref)
 156                goto fail_ref;
 157        kref_init(&ref->kref);
 158        ref->local = local;
 159        ref->ops = ieee80211_rate_control_ops_get(name);
 160        if (!ref->ops)
 161                goto fail_ops;
 162
 163#ifdef CONFIG_MAC80211_DEBUGFS
 164        debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir);
 165        local->debugfs.rcdir = debugfsdir;
 166        local->debugfs.rcname = debugfs_create_file("name", 0400, debugfsdir,
 167                                                    ref, &rcname_ops);
 168#endif
 169
 170        ref->priv = ref->ops->alloc(&local->hw, debugfsdir);
 171        if (!ref->priv)
 172                goto fail_priv;
 173        return ref;
 174
 175fail_priv:
 176        ieee80211_rate_control_ops_put(ref->ops);
 177fail_ops:
 178        kfree(ref);
 179fail_ref:
 180        return NULL;
 181}
 182
 183static void rate_control_release(struct kref *kref)
 184{
 185        struct rate_control_ref *ctrl_ref;
 186
 187        ctrl_ref = container_of(kref, struct rate_control_ref, kref);
 188        ctrl_ref->ops->free(ctrl_ref->priv);
 189
 190#ifdef CONFIG_MAC80211_DEBUGFS
 191        debugfs_remove(ctrl_ref->local->debugfs.rcname);
 192        ctrl_ref->local->debugfs.rcname = NULL;
 193        debugfs_remove(ctrl_ref->local->debugfs.rcdir);
 194        ctrl_ref->local->debugfs.rcdir = NULL;
 195#endif
 196
 197        ieee80211_rate_control_ops_put(ctrl_ref->ops);
 198        kfree(ctrl_ref);
 199}
 200
 201void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 202                           struct sta_info *sta,
 203                           struct ieee80211_tx_rate_control *txrc)
 204{
 205        struct rate_control_ref *ref = sdata->local->rate_ctrl;
 206        void *priv_sta = NULL;
 207        struct ieee80211_sta *ista = NULL;
 208        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
 209        int i;
 210
 211        if (sta) {
 212                ista = &sta->sta;
 213                priv_sta = sta->rate_ctrl_priv;
 214        }
 215
 216        for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
 217                info->control.rates[i].idx = -1;
 218                info->control.rates[i].flags = 0;
 219                info->control.rates[i].count = 1;
 220        }
 221
 222        if (sta && sdata->force_unicast_rateidx > -1) {
 223                info->control.rates[0].idx = sdata->force_unicast_rateidx;
 224        } else {
 225                ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
 226                info->flags |= IEEE80211_TX_INTFL_RCALGO;
 227        }
 228
 229        /*
 230         * try to enforce the maximum rate the user wanted
 231         */
 232        if (sdata->max_ratectrl_rateidx > -1)
 233                for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
 234                        if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS)
 235                                continue;
 236                        info->control.rates[i].idx =
 237                                min_t(s8, info->control.rates[i].idx,
 238                                      sdata->max_ratectrl_rateidx);
 239        }
 240
 241        BUG_ON(info->control.rates[0].idx < 0);
 242}
 243
 244struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
 245{
 246        kref_get(&ref->kref);
 247        return ref;
 248}
 249
 250void rate_control_put(struct rate_control_ref *ref)
 251{
 252        kref_put(&ref->kref, rate_control_release);
 253}
 254
 255int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
 256                                 const char *name)
 257{
 258        struct rate_control_ref *ref, *old;
 259
 260        ASSERT_RTNL();
 261        if (local->open_count || netif_running(local->mdev))
 262                return -EBUSY;
 263
 264        ref = rate_control_alloc(name, local);
 265        if (!ref) {
 266                printk(KERN_WARNING "%s: Failed to select rate control "
 267                       "algorithm\n", wiphy_name(local->hw.wiphy));
 268                return -ENOENT;
 269        }
 270
 271        old = local->rate_ctrl;
 272        local->rate_ctrl = ref;
 273        if (old) {
 274                rate_control_put(old);
 275                sta_info_flush(local, NULL);
 276        }
 277
 278        printk(KERN_DEBUG "%s: Selected rate control "
 279               "algorithm '%s'\n", wiphy_name(local->hw.wiphy),
 280               ref->ops->name);
 281
 282
 283        return 0;
 284}
 285
 286void rate_control_deinitialize(struct ieee80211_local *local)
 287{
 288        struct rate_control_ref *ref;
 289
 290        ref = local->rate_ctrl;
 291        local->rate_ctrl = NULL;
 292        rate_control_put(ref);
 293}
 294
 295