2 * Copyright (c) 2006 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Sepherosa Ziehau <sepherosa@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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
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>
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"
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
);
69 ieee80211_ratectl_detach(struct ieee80211com
*ic
)
71 ieee80211_ratectl_change(ic
, IEEE80211_RATECTL_NONE
);
75 ieee80211_ratectl_register(const struct ieee80211_ratectl
*rc
)
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
);
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
);
93 ratectls
[rc
->rc_ratectl
] = rc
;
97 ieee80211_ratectl_unregister(const struct ieee80211_ratectl
*rc
)
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
);
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
);
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 */
132 if ((IEEE80211_RATECTL_CAP(rc_idx
) & rc_st
->rc_st_ratectl_cap
) == 0) {
133 /* We are not capable to do requested rate control */
137 rc
= ratectls
[rc_idx
];
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
];
149 kprintf("%s: can't load requested rate control module",
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
);
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
);
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
);
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
);
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
);
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
,
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
);
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
);