ieee80211_rate.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. #include <linux/kernel.h>
  11. #include <linux/rtnetlink.h>
  12. #include "ieee80211_rate.h"
  13. #include "ieee80211_i.h"
  14. struct rate_control_alg {
  15. struct list_head list;
  16. struct rate_control_ops *ops;
  17. };
  18. static LIST_HEAD(rate_ctrl_algs);
  19. static DEFINE_MUTEX(rate_ctrl_mutex);
  20. int ieee80211_rate_control_register(struct rate_control_ops *ops)
  21. {
  22. struct rate_control_alg *alg;
  23. if (!ops->name)
  24. return -EINVAL;
  25. mutex_lock(&rate_ctrl_mutex);
  26. list_for_each_entry(alg, &rate_ctrl_algs, list) {
  27. if (!strcmp(alg->ops->name, ops->name)) {
  28. /* don't register an algorithm twice */
  29. WARN_ON(1);
  30. mutex_unlock(&rate_ctrl_mutex);
  31. return -EALREADY;
  32. }
  33. }
  34. alg = kzalloc(sizeof(*alg), GFP_KERNEL);
  35. if (alg == NULL) {
  36. mutex_unlock(&rate_ctrl_mutex);
  37. return -ENOMEM;
  38. }
  39. alg->ops = ops;
  40. list_add_tail(&alg->list, &rate_ctrl_algs);
  41. mutex_unlock(&rate_ctrl_mutex);
  42. return 0;
  43. }
  44. EXPORT_SYMBOL(ieee80211_rate_control_register);
  45. void ieee80211_rate_control_unregister(struct rate_control_ops *ops)
  46. {
  47. struct rate_control_alg *alg;
  48. mutex_lock(&rate_ctrl_mutex);
  49. list_for_each_entry(alg, &rate_ctrl_algs, list) {
  50. if (alg->ops == ops) {
  51. list_del(&alg->list);
  52. kfree(alg);
  53. break;
  54. }
  55. }
  56. mutex_unlock(&rate_ctrl_mutex);
  57. }
  58. EXPORT_SYMBOL(ieee80211_rate_control_unregister);
  59. static struct rate_control_ops *
  60. ieee80211_try_rate_control_ops_get(const char *name)
  61. {
  62. struct rate_control_alg *alg;
  63. struct rate_control_ops *ops = NULL;
  64. if (!name)
  65. return NULL;
  66. mutex_lock(&rate_ctrl_mutex);
  67. list_for_each_entry(alg, &rate_ctrl_algs, list) {
  68. if (!strcmp(alg->ops->name, name))
  69. if (try_module_get(alg->ops->module)) {
  70. ops = alg->ops;
  71. break;
  72. }
  73. }
  74. mutex_unlock(&rate_ctrl_mutex);
  75. return ops;
  76. }
  77. /* Get the rate control algorithm. If `name' is NULL, get the first
  78. * available algorithm. */
  79. static struct rate_control_ops *
  80. ieee80211_rate_control_ops_get(const char *name)
  81. {
  82. struct rate_control_ops *ops;
  83. if (!name)
  84. name = "simple";
  85. ops = ieee80211_try_rate_control_ops_get(name);
  86. if (!ops) {
  87. request_module("rc80211_%s", name);
  88. ops = ieee80211_try_rate_control_ops_get(name);
  89. }
  90. return ops;
  91. }
  92. static void ieee80211_rate_control_ops_put(struct rate_control_ops *ops)
  93. {
  94. module_put(ops->module);
  95. }
  96. struct rate_control_ref *rate_control_alloc(const char *name,
  97. struct ieee80211_local *local)
  98. {
  99. struct rate_control_ref *ref;
  100. ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
  101. if (!ref)
  102. goto fail_ref;
  103. kref_init(&ref->kref);
  104. ref->ops = ieee80211_rate_control_ops_get(name);
  105. if (!ref->ops)
  106. goto fail_ops;
  107. ref->priv = ref->ops->alloc(local);
  108. if (!ref->priv)
  109. goto fail_priv;
  110. return ref;
  111. fail_priv:
  112. ieee80211_rate_control_ops_put(ref->ops);
  113. fail_ops:
  114. kfree(ref);
  115. fail_ref:
  116. return NULL;
  117. }
  118. static void rate_control_release(struct kref *kref)
  119. {
  120. struct rate_control_ref *ctrl_ref;
  121. ctrl_ref = container_of(kref, struct rate_control_ref, kref);
  122. ctrl_ref->ops->free(ctrl_ref->priv);
  123. ieee80211_rate_control_ops_put(ctrl_ref->ops);
  124. kfree(ctrl_ref);
  125. }
  126. struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
  127. {
  128. kref_get(&ref->kref);
  129. return ref;
  130. }
  131. void rate_control_put(struct rate_control_ref *ref)
  132. {
  133. kref_put(&ref->kref, rate_control_release);
  134. }
  135. int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
  136. const char *name)
  137. {
  138. struct rate_control_ref *ref, *old;
  139. ASSERT_RTNL();
  140. if (local->open_count || netif_running(local->mdev))
  141. return -EBUSY;
  142. ref = rate_control_alloc(name, local);
  143. if (!ref) {
  144. printk(KERN_WARNING "%s: Failed to select rate control "
  145. "algorithm\n", wiphy_name(local->hw.wiphy));
  146. return -ENOENT;
  147. }
  148. old = local->rate_ctrl;
  149. local->rate_ctrl = ref;
  150. if (old) {
  151. rate_control_put(old);
  152. sta_info_flush(local, NULL);
  153. }
  154. printk(KERN_DEBUG "%s: Selected rate control "
  155. "algorithm '%s'\n", wiphy_name(local->hw.wiphy),
  156. ref->ops->name);
  157. return 0;
  158. }
  159. void rate_control_deinitialize(struct ieee80211_local *local)
  160. {
  161. struct rate_control_ref *ref;
  162. ref = local->rate_ctrl;
  163. local->rate_ctrl = NULL;
  164. rate_control_put(ref);
  165. }