1206358Srpaulo/*-
2206358Srpaulo * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
3206358Srpaulo * All rights reserved.
4206358Srpaulo *
5206358Srpaulo * Redistribution and use in source and binary forms, with or without
6206358Srpaulo * modification, are permitted provided that the following conditions
7206358Srpaulo * are met:
8206358Srpaulo * 1. Redistributions of source code must retain the above copyright
9206358Srpaulo *    notice, this list of conditions and the following disclaimer.
10206358Srpaulo * 2. Redistributions in binary form must reproduce the above copyright
11206358Srpaulo *    notice, this list of conditions and the following disclaimer in the
12206358Srpaulo *    documentation and/or other materials provided with the distribution.
13206358Srpaulo *
14206358Srpaulo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15206358Srpaulo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16206358Srpaulo * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17206358Srpaulo * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18206358Srpaulo * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19206358Srpaulo * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20206358Srpaulo * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21206358Srpaulo * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22206358Srpaulo * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23206358Srpaulo * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24206358Srpaulo */
25206358Srpaulo
26206358Srpaulo#include <sys/cdefs.h>
27206358Srpaulo__FBSDID("$FreeBSD$");
28206358Srpaulo
29206358Srpaulo#include <sys/param.h>
30206358Srpaulo#include <sys/kernel.h>
31206358Srpaulo#include <sys/systm.h>
32206358Srpaulo#include <sys/socket.h>
33206358Srpaulo
34206358Srpaulo#include <net/if.h>
35206358Srpaulo#include <net/if_media.h>
36206358Srpaulo
37206358Srpaulo#include <net80211/ieee80211_var.h>
38206358Srpaulo#include <net80211/ieee80211_ratectl.h>
39206358Srpaulo
40206358Srpaulostatic const struct ieee80211_ratectl *ratectls[IEEE80211_RATECTL_MAX];
41206358Srpaulo
42214069Sbschmidtstatic const char *ratectl_modnames[IEEE80211_RATECTL_MAX] = {
43214069Sbschmidt	[IEEE80211_RATECTL_AMRR]	= "wlan_amrr",
44214069Sbschmidt	[IEEE80211_RATECTL_RSSADAPT]	= "wlan_rssadapt",
45214069Sbschmidt	[IEEE80211_RATECTL_ONOE]	= "wlan_onoe",
46214069Sbschmidt	[IEEE80211_RATECTL_SAMPLE]	= "wlan_sample",
47214069Sbschmidt	[IEEE80211_RATECTL_NONE]	= "wlan_none",
48214069Sbschmidt};
49214069Sbschmidt
50206358SrpauloMALLOC_DEFINE(M_80211_RATECTL, "80211ratectl", "802.11 rate control");
51206358Srpaulo
52206358Srpaulovoid
53206358Srpauloieee80211_ratectl_register(int type, const struct ieee80211_ratectl *ratectl)
54206358Srpaulo{
55206358Srpaulo	if (type >= IEEE80211_RATECTL_MAX)
56206358Srpaulo		return;
57206358Srpaulo	ratectls[type] = ratectl;
58206358Srpaulo}
59206358Srpaulo
60206358Srpaulovoid
61206358Srpauloieee80211_ratectl_unregister(int type)
62206358Srpaulo{
63206358Srpaulo	if (type >= IEEE80211_RATECTL_MAX)
64206358Srpaulo		return;
65206358Srpaulo	ratectls[type] = NULL;
66206358Srpaulo}
67206358Srpaulo
68206358Srpaulovoid
69214894Sbschmidtieee80211_ratectl_init(struct ieee80211vap *vap)
70214894Sbschmidt{
71214894Sbschmidt	if (vap->iv_rate == ratectls[IEEE80211_RATECTL_NONE])
72214894Sbschmidt		ieee80211_ratectl_set(vap, IEEE80211_RATECTL_AMRR);
73214894Sbschmidt	vap->iv_rate->ir_init(vap);
74214894Sbschmidt}
75214894Sbschmidt
76214894Sbschmidtvoid
77206358Srpauloieee80211_ratectl_set(struct ieee80211vap *vap, int type)
78206358Srpaulo{
79206358Srpaulo	if (type >= IEEE80211_RATECTL_MAX)
80206358Srpaulo		return;
81214069Sbschmidt	if (ratectls[type] == NULL) {
82214069Sbschmidt		ieee80211_load_module(ratectl_modnames[type]);
83214069Sbschmidt		if (ratectls[type] == NULL) {
84214069Sbschmidt			IEEE80211_DPRINTF(vap, IEEE80211_MSG_RATECTL,
85214069Sbschmidt			    "%s: unable to load algo %u, module %s\n",
86214069Sbschmidt			    __func__, type, ratectl_modnames[type]);
87214069Sbschmidt			vap->iv_rate = ratectls[IEEE80211_RATECTL_NONE];
88214069Sbschmidt			return;
89214069Sbschmidt		}
90214069Sbschmidt	}
91206358Srpaulo	vap->iv_rate = ratectls[type];
92206358Srpaulo}
93