arn_rc.c revision dd1de3740722a4b99a74005255effebbd20a6d70
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2004 Video54 Technologies, Inc.
* Copyright (c) 2004-2008 Atheros Communications, Inc.
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "arn_core.h"
static struct ath_rate_table ar5416_11na_ratetable = {
42,
{0},
{
5400, 0x0b, 0x00, 12,
0, 2, 1, 0, 0, 0, 0, 0 },
7800, 0x0f, 0x00, 18,
0, 3, 1, 1, 1, 1, 1, 0 },
10000, 0x0a, 0x00, 24,
2, 4, 2, 2, 2, 2, 2, 0 },
13900, 0x0e, 0x00, 36,
2, 6, 2, 3, 3, 3, 3, 0 },
17300, 0x09, 0x00, 48,
4, 10, 3, 4, 4, 4, 4, 0 },
23000, 0x0d, 0x00, 72,
4, 14, 3, 5, 5, 5, 5, 0 },
27400, 0x08, 0x00, 96,
4, 20, 3, 6, 6, 6, 6, 0 },
29300, 0x0c, 0x00, 108,
4, 23, 3, 7, 7, 7, 7, 0 },
6400, 0x80, 0x00, 0,
0, 2, 3, 8, 24, 8, 24, 3216 },
12700, 0x81, 0x00, 1,
2, 4, 3, 9, 25, 9, 25, 6434 },
18800, 0x82, 0x00, 2,
2, 6, 3, 10, 26, 10, 26, 9650 },
25000, 0x83, 0x00, 3,
4, 10, 3, 11, 27, 11, 27, 12868 },
36700, 0x84, 0x00, 4,
4, 14, 3, 12, 28, 12, 28, 19304 },
48100, 0x85, 0x00, 5,
4, 20, 3, 13, 29, 13, 29, 25740 },
53500, 0x86, 0x00, 6,
4, 23, 3, 14, 30, 14, 30, 28956 },
59000, 0x87, 0x00, 7,
4, 25, 3, 15, 31, 15, 32, 32180 },
12700, 0x88, 0x00,
8, 0, 2, 3, 16, 33, 16, 33, 6430 },
24800, 0x89, 0x00, 9,
2, 4, 3, 17, 34, 17, 34, 12860 },
36600, 0x8a, 0x00, 10,
2, 6, 3, 18, 35, 18, 35, 19300 },
48100, 0x8b, 0x00, 11,
4, 10, 3, 19, 36, 19, 36, 25736 },
69500, 0x8c, 0x00, 12,
4, 14, 3, 20, 37, 20, 37, 38600 },
89500, 0x8d, 0x00, 13,
4, 20, 3, 21, 38, 21, 38, 51472 },
98900, 0x8e, 0x00, 14,
4, 23, 3, 22, 39, 22, 39, 57890 },
108300, 0x8f, 0x00, 15,
4, 25, 3, 23, 40, 23, 41, 64320 },
13200, 0x80, 0x00, 0,
0, 2, 3, 8, 24, 24, 24, 6684 },
25900, 0x81, 0x00, 1,
2, 4, 3, 9, 25, 25, 25, 13368 },
38600, 0x82, 0x00, 2,
2, 6, 3, 10, 26, 26, 26, 20052 },
49800, 0x83, 0x00, 3,
4, 10, 3, 11, 27, 27, 27, 26738 },
72200, 0x84, 0x00, 4,
4, 14, 3, 12, 28, 28, 28, 40104 },
92900, 0x85, 0x00, 5,
4, 20, 3, 13, 29, 29, 29, 53476 },
102700, 0x86, 0x00, 6,
4, 23, 3, 14, 30, 30, 30, 60156 },
112000, 0x87, 0x00, 7,
4, 25, 3, 15, 31, 32, 32, 66840 },
150000, /* 150Mb */
122000, 0x87, 0x00, 7,
4, 25, 3, 15, 31, 32, 32, 74200 },
25800, 0x88, 0x00, 8,
0, 2, 3, 16, 33, 33, 33, 13360 },
49800, 0x89, 0x00, 9,
2, 4, 3, 17, 34, 34, 34, 26720 },
71900, 0x8a, 0x00, 10,
2, 6, 3, 18, 35, 35, 35, 40080 },
92500, 0x8b, 0x00, 11,
4, 10, 3, 19, 36, 36, 36, 53440 },
130300, 0x8c, 0x00, 12,
4, 14, 3, 20, 37, 37, 37, 80160 },
162800, 0x8d, 0x00, 13,
4, 20, 3, 21, 38, 38, 38, 106880 },
178200, 0x8e, 0x00, 14,
4, 23, 3, 22, 39, 39, 39, 120240 },
192100, 0x8f, 0x00, 15,
4, 25, 3, 23, 40, 41, 41, 133600 },
300000, /* 300 Mb */
207000, 0x8f, 0x00, 15,
4, 25, 3, 23, 40, 41, 41, 148400 },
},
50, /* probe interval */
50, /* rssi reduce interval */
WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
};
/*
* 4ms frame limit not used for NG mode. The values filled
* for HT are the 64K max aggregate limit
*/
static struct ath_rate_table ar5416_11ng_ratetable = {
46,
{0},
{
900, 0x1b, 0x00, 2,
0, 0, 1, 0, 0, 0, 0, 0 },
1900, 0x1a, 0x04, 4,
1, 1, 1, 1, 1, 1, 1, 0 },
4900, 0x19, 0x04, 11,
2, 2, 2, 2, 2, 2, 2, 0 },
8100, 0x18, 0x04, 22,
3, 3, 2, 3, 3, 3, 3, 0 },
5400, 0x0b, 0x00, 12,
4, 2, 1, 4, 4, 4, 4, 0 },
7800, 0x0f, 0x00, 18,
4, 3, 1, 5, 5, 5, 5, 0 },
10100, 0x0a, 0x00, 24,
6, 4, 1, 6, 6, 6, 6, 0 },
14100, 0x0e, 0x00, 36,
6, 6, 2, 7, 7, 7, 7, 0 },
17700, 0x09, 0x00, 48,
8, 10, 3, 8, 8, 8, 8, 0 },
23700, 0x0d, 0x00, 72,
8, 14, 3, 9, 9, 9, 9, 0 },
27400, 0x08, 0x00, 96,
8, 20, 3, 10, 10, 10, 10, 0 },
30900, 0x0c, 0x00, 108,
8, 23, 3, 11, 11, 11, 11, 0 },
6400, 0x80, 0x00, 0,
4, 2, 3, 12, 28, 12, 28, 3216 },
12700, 0x81, 0x00, 1,
6, 4, 3, 13, 29, 13, 29, 6434 },
18800, 0x82, 0x00, 2,
6, 6, 3, 14, 30, 14, 30, 9650 },
25000, 0x83, 0x00, 3,
8, 10, 3, 15, 31, 15, 31, 12868 },
36700, 0x84, 0x00, 4,
8, 14, 3, 16, 32, 16, 32, 19304 },
48100, 0x85, 0x00, 5,
8, 20, 3, 17, 33, 17, 33, 25740 },
53500, 0x86, 0x00, 6,
8, 23, 3, 18, 34, 18, 34, 28956 },
59000, 0x87, 0x00, 7,
8, 25, 3, 19, 35, 19, 36, 32180 },
12700, 0x88, 0x00, 8,
4, 2, 3, 20, 37, 20, 37, 6430 },
24800, 0x89, 0x00, 9,
6, 4, 3, 21, 38, 21, 38, 12860 },
36600, 0x8a, 0x00, 10,
6, 6, 3, 22, 39, 22, 39, 19300 },
48100, 0x8b, 0x00, 11,
8, 10, 3, 23, 40, 23, 40, 25736 },
69500, 0x8c, 0x00, 12,
8, 14, 3, 24, 41, 24, 41, 38600 },
89500, 0x8d, 0x00, 13,
8, 20, 3, 25, 42, 25, 42, 51472 },
98900, 0x8e, 0x00, 14,
8, 23, 3, 26, 43, 26, 44, 57890 },
108300, 0x8f, 0x00, 15,
8, 25, 3, 27, 44, 27, 45, 64320 },
13200, 0x80, 0x00, 0,
8, 2, 3, 12, 28, 28, 28, 6684 },
25900, 0x81, 0x00, 1,
8, 4, 3, 13, 29, 29, 29, 13368 },
38600, 0x82, 0x00, 2,
8, 6, 3, 14, 30, 30, 30, 20052 },
49800, 0x83, 0x00, 3,
8, 10, 3, 15, 31, 31, 31, 26738 },
72200, 0x84, 0x00, 4,
8, 14, 3, 16, 32, 32, 32, 40104 },
92900, 0x85, 0x00, 5,
8, 20, 3, 17, 33, 33, 33, 53476 },
121500, /* 121.5 Mb */
102700, 0x86, 0x00, 6,
8, 23, 3, 18, 34, 34, 34, 60156 },
112000, 0x87, 0x00, 7,
8, 23, 3, 19, 35, 36, 36, 66840 },
150000, /* 150 Mb */
122000, 0x87, 0x00, 7,
8, 25, 3, 19, 35, 36, 36, 74200 },
25800, 0x88, 0x00, 8,
8, 2, 3, 20, 37, 37, 37, 13360 },
49800, 0x89, 0x00, 9,
8, 4, 3, 21, 38, 38, 38, 26720 },
71900, 0x8a, 0x00, 10,
8, 6, 3, 22, 39, 39, 39, 40080 },
92500, 0x8b, 0x00, 11,
8, 10, 3, 23, 40, 40, 40, 53440 },
130300, 0x8c, 0x00, 12,
8, 14, 3, 24, 41, 41, 41, 80160 },
162800, 0x8d, 0x00, 13,
8, 20, 3, 25, 42, 42, 42, 106880 },
178200, 0x8e, 0x00, 14,
8, 23, 3, 26, 43, 43, 43, 120240 },
192100, 0x8f, 0x00, 15,
8, 23, 3, 27, 44, 45, 45, 133600 },
300000, /* 300 Mb */
207000, 0x8f, 0x00, 15,
8, 25, 3, 27, 44, 45, 45, 148400 },
},
50, /* probe interval */
50, /* rssi reduce interval */
WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
};
static struct ath_rate_table ar5416_11a_ratetable = {
8,
{0},
{
5400, 0x0b, 0x00, (0x80|12),
0, 2, 1, 0, 0 },
7800, 0x0f, 0x00, 18,
0, 3, 1, 1, 0 },
10000, 0x0a, 0x00, (0x80|24),
2, 4, 2, 2, 0 },
13900, 0x0e, 0x00, 36,
2, 6, 2, 3, 0 },
17300, 0x09, 0x00, (0x80|48),
4, 10, 3, 4, 0 },
23000, 0x0d, 0x00, 72,
4, 14, 3, 5, 0 },
27400, 0x08, 0x00, 96,
4, 19, 3, 6, 0 },
29300, 0x0c, 0x00, 108,
4, 23, 3, 7, 0 },
},
50, /* probe interval */
50, /* rssi reduce interval */
0, /* Phy rates allowed initially */
};
static struct ath_rate_table ar5416_11g_ratetable = {
12,
{0},
{
900, 0x1b, 0x00, 2,
0, 0, 1, 0, 0 },
1900, 0x1a, 0x04, 4,
1, 1, 1, 1, 0 },
4900, 0x19, 0x04, 11,
2, 2, 2, 2, 0 },
8100, 0x18, 0x04, 22,
3, 3, 2, 3, 0 },
5400, 0x0b, 0x00, 12,
4, 2, 1, 4, 0 },
7800, 0x0f, 0x00, 18,
4, 3, 1, 5, 0 },
10000, 0x0a, 0x00, 24,
6, 4, 1, 6, 0 },
13900, 0x0e, 0x00, 36,
6, 6, 2, 7, 0 },
17300, 0x09, 0x00, 48,
8, 10, 3, 8, 0 },
23000, 0x0d, 0x00, 72,
8, 14, 3, 9, 0 },
27400, 0x08, 0x00, 96,
8, 19, 3, 10, 0 },
29300, 0x0c, 0x00, 108,
8, 23, 3, 11, 0 },
},
50, /* probe interval */
50, /* rssi reduce interval */
0, /* Phy rates allowed initially */
};
static struct ath_rate_table ar5416_11b_ratetable = {
4,
{0},
{
900, 0x1b, 0x00, (0x80|2),
0, 0, 1, 0, 0 },
1800, 0x1a, 0x04, (0x80|4),
1, 1, 1, 1, 0 },
4300, 0x19, 0x04, (0x80|11),
1, 2, 2, 2, 0 },
7100, 0x18, 0x04, (0x80|22),
1, 4, 100, 3, 0 },
},
100, /* probe interval */
100, /* rssi reduce interval */
0, /* Phy rates allowed initially */
};
static void
struct ath_rate_table *rate_table)
{
int i;
for (i = 0; i < 256; i++)
for (i = 0; i < rate_table->rate_cnt; i++) {
cix,
B_FALSE);
cix,
B_TRUE);
}
}
void
{
}
void
{
/* management/control frames always go at the lowest speed */
"mgtrate=%d mgtratesp=%d\n",
/*
* Before associating a node has no rate set setup
* so we can't calculate any transmit codes to use.
* This is ok since we should never be sending anything
* but management frames and those always go at the
* lowest hardware rate.
*/
goto done;
if (sc->sc_mrretry) {
/*
* Hardware supports multi-rate retry; setup two
* step-down retry rates and make the lowest rate
* be the ``last chance''. We use 4, 2, 2, 2 tries
* respectively (4 is set here, the rest are fixed
* in the xmit routine).
*/
if (--rate >= 0) {
} else {
}
if (--rate >= 0) {
} else {
}
if (rate > 0) {
an->an_tx_rate3sp =
} else {
}
} else {
}
done:
}
/*
* Set the starting transmit rate for a node.
*/
void
{
/*
* No fixed rate is requested. For 11b start with
* the highest negotiated rate; otherwise, for 11g
* and 11a, we start "in the middle" at 24Mb or 36Mb.
*/
/*
* Scan the negotiated rate set to find the
* closest rate.
*/
/* NB: the rate set is assumed sorted */
srate--) {}
}
} else {
/*
* A fixed rate is to be used; We know the rate is
* there because the rate set is checked when the
* station associates.
*/
/* NB: the rate set is assumed sorted */
srate--) {}
}
}
void
{
}
/*
* Reset the rate control state for each 802.11 state transition.
*/
void
{
struct ieee80211_node *in;
/*
* Reset local xmit state; this is really only
* meaningful when operating in station mode.
*/
if (state == IEEE80211_S_RUN) {
} else {
}
} else {
/*
* When operating as a station the node table holds
* the AP's that were discovered during scanning.
* For any other operating mode we want to reset the
* tx rate state of each node.
*/
}
}
/*
* Examine and potentially adjust the transmit rate.
*/
void
{
/*
* Rate control(very primitive version).
*/
/* no packet reached -> down */
mod = -1;
/* all packets needs retry in average -> down */
mod = -1;
/* no error and less than 10% of packets needs retry -> up */
mod = 1;
switch (mod) {
case 0:
an->an_tx_upper--;
break;
case -1:
if (nrate > 0) {
nrate--;
}
an->an_tx_upper = 0;
break;
case 1:
break;
an->an_tx_upper = 0;
nrate++;
}
break;
}
"(%d ok, %d err, %d retr)\n",
} else if (enough)
}