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 16 struct rate_control_alg { 17 struct list_head list; 18 struct rate_control_ops *ops; 19 }; 20 21 static LIST_HEAD(rate_ctrl_algs); 22 static DEFINE_MUTEX(rate_ctrl_mutex); 23 24 static char *ieee80211_default_rc_algo = CONFIG_MAC80211_RC_DEFAULT; 25 module_param(ieee80211_default_rc_algo, charp, 0644); 26 MODULE_PARM_DESC(ieee80211_default_rc_algo, 27 "Default rate control algorithm for mac80211 to use"); 28 29 int ieee80211_rate_control_register(struct rate_control_ops *ops) 30 { 31 struct rate_control_alg *alg; 32 33 if (!ops->name) 34 return -EINVAL; 35 36 mutex_lock(&rate_ctrl_mutex); 37 list_for_each_entry(alg, &rate_ctrl_algs, list) { 38 if (!strcmp(alg->ops->name, ops->name)) { 39 /* don't register an algorithm twice */ 40 WARN_ON(1); 41 mutex_unlock(&rate_ctrl_mutex); 42 return -EALREADY; 43 } 44 } 45 46 alg = kzalloc(sizeof(*alg), GFP_KERNEL); 47 if (alg == NULL) { 48 mutex_unlock(&rate_ctrl_mutex); 49 return -ENOMEM; 50 } 51 alg->ops = ops; 52 53 list_add_tail(&alg->list, &rate_ctrl_algs); 54 mutex_unlock(&rate_ctrl_mutex); 55 56 return 0; 57 } 58 EXPORT_SYMBOL(ieee80211_rate_control_register); 59 60 void ieee80211_rate_control_unregister(struct rate_control_ops *ops) 61 { 62 struct rate_control_alg *alg; 63 64 mutex_lock(&rate_ctrl_mutex); 65 list_for_each_entry(alg, &rate_ctrl_algs, list) { 66 if (alg->ops == ops) { 67 list_del(&alg->list); 68 kfree(alg); 69 break; 70 } 71 } 72 mutex_unlock(&rate_ctrl_mutex); 73 } 74 EXPORT_SYMBOL(ieee80211_rate_control_unregister); 75 76 static struct rate_control_ops * 77 ieee80211_try_rate_control_ops_get(const char *name) 78 { 79 struct rate_control_alg *alg; 80 struct rate_control_ops *ops = NULL; 81 82 if (!name) 83 return NULL; 84 85 mutex_lock(&rate_ctrl_mutex); 86 list_for_each_entry(alg, &rate_ctrl_algs, list) { 87 if (!strcmp(alg->ops->name, name)) 88 if (try_module_get(alg->ops->module)) { 89 ops = alg->ops; 90 break; 91 } 92 } 93 mutex_unlock(&rate_ctrl_mutex); 94 return ops; 95 } 96 97 /* Get the rate control algorithm. */ 98 static struct rate_control_ops * 99 ieee80211_rate_control_ops_get(const char *name) 100 { 101 struct rate_control_ops *ops; 102 const char *alg_name; 103 104 if (!name) 105 alg_name = ieee80211_default_rc_algo; 106 else 107 alg_name = name; 108 109 ops = ieee80211_try_rate_control_ops_get(alg_name); 110 if (!ops) { 111 request_module("rc80211_%s", alg_name); 112 ops = ieee80211_try_rate_control_ops_get(alg_name); 113 } 114 if (!ops && name) 115 /* try default if specific alg requested but not found */ 116 ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo); 117 118 /* try built-in one if specific alg requested but not found */ 119 if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT)) 120 ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT); 121 122 return ops; 123 } 124 125 static void ieee80211_rate_control_ops_put(struct rate_control_ops *ops) 126 { 127 module_put(ops->module); 128 } 129 130 struct rate_control_ref *rate_control_alloc(const char *name, 131 struct ieee80211_local *local) 132 { 133 struct rate_control_ref *ref; 134 135 ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL); 136 if (!ref) 137 goto fail_ref; 138 kref_init(&ref->kref); 139 ref->ops = ieee80211_rate_control_ops_get(name); 140 if (!ref->ops) 141 goto fail_ops; 142 ref->priv = ref->ops->alloc(local); 143 if (!ref->priv) 144 goto fail_priv; 145 return ref; 146 147 fail_priv: 148 ieee80211_rate_control_ops_put(ref->ops); 149 fail_ops: 150 kfree(ref); 151 fail_ref: 152 return NULL; 153 } 154 155 static void rate_control_release(struct kref *kref) 156 { 157 struct rate_control_ref *ctrl_ref; 158 159 ctrl_ref = container_of(kref, struct rate_control_ref, kref); 160 ctrl_ref->ops->free(ctrl_ref->priv); 161 ieee80211_rate_control_ops_put(ctrl_ref->ops); 162 kfree(ctrl_ref); 163 } 164 165 void rate_control_get_rate(struct net_device *dev, 166 struct ieee80211_supported_band *sband, 167 struct sk_buff *skb, 168 struct rate_selection *sel) 169 { 170 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 171 struct rate_control_ref *ref = local->rate_ctrl; 172 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 173 struct sta_info *sta; 174 int i; 175 176 rcu_read_lock(); 177 sta = sta_info_get(local, hdr->addr1); 178 179 sel->rate_idx = -1; 180 sel->nonerp_idx = -1; 181 sel->probe_idx = -1; 182 183 ref->ops->get_rate(ref->priv, dev, sband, skb, sel); 184 185 BUG_ON(sel->rate_idx < 0); 186 187 /* Select a non-ERP backup rate. */ 188 if (sel->nonerp_idx < 0) { 189 for (i = 0; i < sband->n_bitrates; i++) { 190 struct ieee80211_rate *rate = &sband->bitrates[i]; 191 if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) 192 break; 193 194 if (rate_supported(sta, sband->band, i) && 195 !(rate->flags & IEEE80211_RATE_ERP_G)) 196 sel->nonerp_idx = i; 197 } 198 } 199 200 rcu_read_unlock(); 201 } 202 203 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) 204 { 205 kref_get(&ref->kref); 206 return ref; 207 } 208 209 void rate_control_put(struct rate_control_ref *ref) 210 { 211 kref_put(&ref->kref, rate_control_release); 212 } 213 214 int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 215 const char *name) 216 { 217 struct rate_control_ref *ref, *old; 218 219 ASSERT_RTNL(); 220 if (local->open_count || netif_running(local->mdev)) 221 return -EBUSY; 222 223 ref = rate_control_alloc(name, local); 224 if (!ref) { 225 printk(KERN_WARNING "%s: Failed to select rate control " 226 "algorithm\n", wiphy_name(local->hw.wiphy)); 227 return -ENOENT; 228 } 229 230 old = local->rate_ctrl; 231 local->rate_ctrl = ref; 232 if (old) { 233 rate_control_put(old); 234 sta_info_flush(local, NULL); 235 } 236 237 printk(KERN_DEBUG "%s: Selected rate control " 238 "algorithm '%s'\n", wiphy_name(local->hw.wiphy), 239 ref->ops->name); 240 241 242 return 0; 243 } 244 245 void rate_control_deinitialize(struct ieee80211_local *local) 246 { 247 struct rate_control_ref *ref; 248 249 ref = local->rate_ctrl; 250 local->rate_ctrl = NULL; 251 rate_control_put(ref); 252 } 253 254