amd64 port: mainly on the pmap headers, identify_cpu and initcpu
[dragonfly/port-amd64.git] / sys / netproto / 802_11 / wlan / ieee80211_ratectl.c
blob20cc1dbc20bd8dc51d153e4359228983e9da7c4a
1 /*
2 * Copyright (c) 2006 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
34 * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_ratectl.c,v 1.4 2007/04/01 13:59:41 sephe Exp $
37 #include <sys/param.h>
38 #include <sys/kernel.h>
40 #include <net/if.h>
41 #include <net/if_media.h>
42 #include <net/if_arp.h>
44 #include <netproto/802_11/ieee80211_var.h>
46 static const struct ieee80211_ratectl *ratectls[IEEE80211_RATECTL_MAX] = {
47 [IEEE80211_RATECTL_NONE] = &ieee80211_ratectl_none
50 static const char *ratectl_modname[IEEE80211_RATECTL_MAX] = {
51 [IEEE80211_RATECTL_ONOE] = "wlan_ratectl_onoe",
52 [IEEE80211_RATECTL_AMRR] = "wlan_ratectl_amrr",
53 [IEEE80211_RATECTL_SAMPLE] = "wlan_ratectl_sample"
56 void
57 ieee80211_ratectl_attach(struct ieee80211com *ic)
59 struct ieee80211_ratectl_state *rc_st = &ic->ic_ratectl;
60 u_int cur_ratectl = rc_st->rc_st_ratectl;
62 rc_st->rc_st_ratectl_cap |= IEEE80211_RATECTL_CAP_NONE;
63 rc_st->rc_st_ratectl = IEEE80211_RATECTL_NONE;
65 ieee80211_ratectl_change(ic, cur_ratectl);
68 void
69 ieee80211_ratectl_detach(struct ieee80211com *ic)
71 ieee80211_ratectl_change(ic, IEEE80211_RATECTL_NONE);
74 void
75 ieee80211_ratectl_register(const struct ieee80211_ratectl *rc)
78 * Sanity checks
80 if (rc->rc_ratectl >= IEEE80211_RATECTL_MAX) {
81 kprintf("%s: rate control %s has an invalid index %d\n",
82 __func__, rc->rc_name, rc->rc_ratectl);
83 return;
85 if (ratectls[rc->rc_ratectl] != NULL &&
86 ratectls[rc->rc_ratectl] != rc) {
87 kprintf("%s: rate control index %d is registered by %s\n",
88 __func__, rc->rc_ratectl,
89 ratectls[rc->rc_ratectl]->rc_name);
90 return;
93 ratectls[rc->rc_ratectl] = rc;
96 void
97 ieee80211_ratectl_unregister(const struct ieee80211_ratectl *rc)
100 * Sanity checks
102 if (rc->rc_ratectl >= IEEE80211_RATECTL_MAX) {
103 kprintf("%s: rate control %s has an invalid index %d\n",
104 __func__, rc->rc_name, rc->rc_ratectl);
105 return;
107 if (ratectls[rc->rc_ratectl] != NULL &&
108 ratectls[rc->rc_ratectl] != rc) {
109 kprintf("%s: rate control index %d is registered by %s\n",
110 __func__, rc->rc_ratectl,
111 ratectls[rc->rc_ratectl]->rc_name);
112 return;
116 * Indiviual rate control module MUST maintain reference count itself.
118 ratectls[rc->rc_ratectl] = NULL;
122 ieee80211_ratectl_change(struct ieee80211com *ic, u_int rc_idx)
124 struct ieee80211_ratectl_state *rc_st = &ic->ic_ratectl;
125 const struct ieee80211_ratectl *rc, *rc_old;
127 if (rc_idx == rc_st->rc_st_ratectl) {
128 /* Nothing need to be changed */
129 return 0;
132 if ((IEEE80211_RATECTL_CAP(rc_idx) & rc_st->rc_st_ratectl_cap) == 0) {
133 /* We are not capable to do requested rate control */
134 return EOPNOTSUPP;
137 rc = ratectls[rc_idx];
138 if (rc == NULL) {
139 /* Try load the rate control module */
140 ieee80211_load_module(ratectl_modname[rc_idx]);
143 * If rate control module loaded it should immediately
144 * call ieee80211_ratectl_register() which will fill in
145 * the entry in the 'ratectls' array.
147 rc = ratectls[rc_idx];
148 if (rc == NULL) {
149 kprintf("%s: can't load requested rate control module",
150 __func__);
151 return EOPNOTSUPP;
155 /* Detach old rate control */
156 rc_old = ratectls[rc_st->rc_st_ratectl];
157 rc_old->rc_detach(rc_st->rc_st_ctx);
159 if (rc_st->rc_st_change != NULL)
160 rc_st->rc_st_change(ic, rc_st->rc_st_ratectl, rc_idx);
162 /* Attach new rate control */
163 rc_st->rc_st_ratectl = rc_idx;
164 rc_st->rc_st_ctx = rc->rc_attach(ic);
166 return 0;
169 void
170 ieee80211_ratectl_data_alloc(struct ieee80211_node *ni)
172 struct ieee80211com *ic = ni->ni_ic;
173 struct ieee80211_ratectl_state *rc_st = &ic->ic_ratectl;
174 const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl];
176 rc->rc_data_alloc(ni);
179 void
180 ieee80211_ratectl_data_dup(const struct ieee80211_node *oni,
181 struct ieee80211_node *nni)
183 struct ieee80211com *ic = oni->ni_ic;
184 struct ieee80211_ratectl_state *rc_st = &ic->ic_ratectl;
185 const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl];
187 rc->rc_data_dup(oni, nni);
190 void
191 ieee80211_ratectl_data_free(struct ieee80211_node *ni)
193 struct ieee80211com *ic = ni->ni_ic;
194 struct ieee80211_ratectl_state *rc_st = &ic->ic_ratectl;
195 const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl];
197 rc->rc_data_free(ni);
200 void
201 ieee80211_ratectl_newstate(struct ieee80211com *ic, enum ieee80211_state state)
203 struct ieee80211_ratectl_state *rc_st = &ic->ic_ratectl;
204 const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl];
206 rc->rc_newstate(rc_st->rc_st_ctx, state);
209 void
210 ieee80211_ratectl_tx_complete(struct ieee80211_node *ni, int frame_len,
211 const struct ieee80211_ratectl_res res[],
212 int res_len, int data_retries, int rts_retries,
213 int is_fail)
215 struct ieee80211com *ic = ni->ni_ic;
216 struct ieee80211_ratectl_state *rc_st = &ic->ic_ratectl;
217 const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl];
219 rc->rc_tx_complete(rc_st->rc_st_ctx, ni, frame_len, res, res_len,
220 data_retries, rts_retries, is_fail);
223 void
224 ieee80211_ratectl_newassoc(struct ieee80211_node *ni, int is_new)
226 struct ieee80211com *ic = ni->ni_ic;
227 struct ieee80211_ratectl_state *rc_st = &ic->ic_ratectl;
228 const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl];
230 rc->rc_newassoc(rc_st->rc_st_ctx, ni, is_new);
234 ieee80211_ratectl_findrate(struct ieee80211_node *ni, int frame_len,
235 int rateidx[], int rateidx_len)
237 struct ieee80211com *ic = ni->ni_ic;
238 struct ieee80211_ratectl_state *rc_st = &ic->ic_ratectl;
239 const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl];
241 KKASSERT(rateidx_len > 0);
243 return rc->rc_findrate(rc_st->rc_st_ctx, ni, frame_len,
244 rateidx, rateidx_len);