1185377Ssam/*
2185377Ssam * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3185377Ssam * Copyright (c) 2002-2008 Atheros Communications, Inc.
4185377Ssam *
5185377Ssam * Permission to use, copy, modify, and/or distribute this software for any
6185377Ssam * purpose with or without fee is hereby granted, provided that the above
7185377Ssam * copyright notice and this permission notice appear in all copies.
8185377Ssam *
9185377Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10185377Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11185377Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12185377Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13185377Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14185377Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15185377Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16185377Ssam *
17188773Ssam * $FreeBSD$
18185377Ssam */
19185377Ssam#include "opt_ah.h"
20185377Ssam
21185377Ssam#include "ah.h"
22185377Ssam#include "ah_internal.h"
23185377Ssam
24185377Ssam#include "ar5212/ar5212.h"
25185377Ssam
26185377Ssam/* shorthands to compact tables for readability */
27185377Ssam#define	OFDM	IEEE80211_T_OFDM
28185377Ssam#define	CCK	IEEE80211_T_CCK
29185377Ssam#define	TURBO	IEEE80211_T_TURBO
30188773Ssam#define	HALF	IEEE80211_T_OFDM_HALF
31188773Ssam#define	QUART	IEEE80211_T_OFDM_QUARTER
32185377Ssam
33185377SsamHAL_RATE_TABLE ar5212_11a_table = {
34185377Ssam	8,  /* number of rates */
35185377Ssam	{ 0 },
36185377Ssam	{
37185377Ssam/*                                                  short            ctrl  */
38185377Ssam/*                valid                 rateCode Preamble  dot11Rate Rate */
39185377Ssam/*   6 Mb */ {  AH_TRUE, OFDM,    6000,     0x0b,    0x00, (0x80|12),   0 },
40185377Ssam/*   9 Mb */ {  AH_TRUE, OFDM,    9000,     0x0f,    0x00,        18,   0 },
41185377Ssam/*  12 Mb */ {  AH_TRUE, OFDM,   12000,     0x0a,    0x00, (0x80|24),   2 },
42185377Ssam/*  18 Mb */ {  AH_TRUE, OFDM,   18000,     0x0e,    0x00,        36,   2 },
43185377Ssam/*  24 Mb */ {  AH_TRUE, OFDM,   24000,     0x09,    0x00, (0x80|48),   4 },
44185377Ssam/*  36 Mb */ {  AH_TRUE, OFDM,   36000,     0x0d,    0x00,        72,   4 },
45185377Ssam/*  48 Mb */ {  AH_TRUE, OFDM,   48000,     0x08,    0x00,        96,   4 },
46185377Ssam/*  54 Mb */ {  AH_TRUE, OFDM,   54000,     0x0c,    0x00,       108,   4 }
47185377Ssam	},
48185377Ssam};
49185377Ssam
50185380SsamHAL_RATE_TABLE ar5212_half_table = {
51185377Ssam	8,  /* number of rates */
52185377Ssam	{ 0 },
53185377Ssam	{
54185377Ssam/*                                                  short            ctrl  */
55185377Ssam/*                valid                 rateCode Preamble  dot11Rate Rate */
56188773Ssam/*   3 Mb */ {  AH_TRUE, HALF,    3000,     0x0b,    0x00, (0x80|6),   0 },
57188773Ssam/* 4.5 Mb */ {  AH_TRUE, HALF,    4500,     0x0f,    0x00,        9,   0 },
58188773Ssam/*   6 Mb */ {  AH_TRUE, HALF,    6000,     0x0a,    0x00, (0x80|12),  2 },
59188773Ssam/*   9 Mb */ {  AH_TRUE, HALF,    9000,     0x0e,    0x00,       18,   2 },
60188773Ssam/*  12 Mb */ {  AH_TRUE, HALF,   12000,     0x09,    0x00, (0x80|24),  4 },
61188773Ssam/*  18 Mb */ {  AH_TRUE, HALF,   18000,     0x0d,    0x00,       36,   4 },
62188773Ssam/*  24 Mb */ {  AH_TRUE, HALF,   24000,     0x08,    0x00,       48,   4 },
63188773Ssam/*  27 Mb */ {  AH_TRUE, HALF,   27000,     0x0c,    0x00,       54,   4 }
64185377Ssam	},
65185377Ssam};
66185377Ssam
67185380SsamHAL_RATE_TABLE ar5212_quarter_table = {
68185377Ssam	8,  /* number of rates */
69185377Ssam	{ 0 },
70185377Ssam	{
71185377Ssam/*                                                  short            ctrl  */
72185377Ssam/*                valid                 rateCode Preamble  dot11Rate Rate */
73188773Ssam/* 1.5 Mb */ {  AH_TRUE, QUART,   1500,     0x0b,    0x00, (0x80|3),   0 },
74188773Ssam/*   2 Mb */ {  AH_TRUE, QUART,   2250,     0x0f,    0x00,        4,   0 },
75188773Ssam/*   3 Mb */ {  AH_TRUE, QUART,   3000,     0x0a,    0x00, (0x80|6),   2 },
76188773Ssam/* 4.5 Mb */ {  AH_TRUE, QUART,   4500,     0x0e,    0x00,        9,   2 },
77188773Ssam/*   6 Mb */ {  AH_TRUE, QUART,   6000,     0x09,    0x00, (0x80|12),  4 },
78188773Ssam/*   9 Mb */ {  AH_TRUE, QUART,   9000,     0x0d,    0x00,       18,   4 },
79188773Ssam/*  12 Mb */ {  AH_TRUE, QUART,  12000,     0x08,    0x00,       24,   4 },
80188773Ssam/*13.5 Mb */ {  AH_TRUE, QUART,  13500,     0x0c,    0x00,       27,   4 }
81185377Ssam	},
82185377Ssam};
83185377Ssam
84185377SsamHAL_RATE_TABLE ar5212_turbog_table = {
85185377Ssam	7,  /* number of rates */
86185377Ssam	{ 0 },
87185377Ssam	{
88185377Ssam/*                                                 short            ctrl  */
89185377Ssam/*                valid                rateCode Preamble  dot11Rate Rate */
90191022Ssam/*   6 Mb */ {  AH_TRUE, TURBO,  12000,    0x0b,    0x00, (0x80|12),   0 },
91191022Ssam/*  12 Mb */ {  AH_TRUE, TURBO,  24000,    0x0a,    0x00, (0x80|24),   1 },
92191022Ssam/*  18 Mb */ {  AH_TRUE, TURBO,  36000,    0x0e,    0x00,        36,   1 },
93191022Ssam/*  24 Mb */ {  AH_TRUE, TURBO,  48000,    0x09,    0x00, (0x80|48),   2 },
94191022Ssam/*  36 Mb */ {  AH_TRUE, TURBO,  72000,    0x0d,    0x00,        72,   2 },
95191022Ssam/*  48 Mb */ {  AH_TRUE, TURBO,  96000,    0x08,    0x00,        96,   2 },
96191022Ssam/*  54 Mb */ {  AH_TRUE, TURBO, 108000,    0x0c,    0x00,       108,   2 }
97185377Ssam	},
98185377Ssam};
99185377Ssam
100185377SsamHAL_RATE_TABLE ar5212_turboa_table = {
101185377Ssam	8,  /* number of rates */
102185377Ssam	{ 0 },
103185377Ssam	{
104185377Ssam/*                                                 short            ctrl  */
105185377Ssam/*                valid                rateCode Preamble  dot11Rate Rate */
106191022Ssam/*   6 Mb */ {  AH_TRUE, TURBO,  12000,    0x0b,    0x00, (0x80|12),   0 },
107191022Ssam/*   9 Mb */ {  AH_TRUE, TURBO,  18000,    0x0f,    0x00,        18,   0 },
108191022Ssam/*  12 Mb */ {  AH_TRUE, TURBO,  24000,    0x0a,    0x00, (0x80|24),   2 },
109191022Ssam/*  18 Mb */ {  AH_TRUE, TURBO,  36000,    0x0e,    0x00,        36,   2 },
110191022Ssam/*  24 Mb */ {  AH_TRUE, TURBO,  48000,    0x09,    0x00, (0x80|48),   4 },
111191022Ssam/*  36 Mb */ {  AH_TRUE, TURBO,  72000,    0x0d,    0x00,        72,   4 },
112191022Ssam/*  48 Mb */ {  AH_TRUE, TURBO,  96000,    0x08,    0x00,        96,   4 },
113191022Ssam/*  54 Mb */ {  AH_TRUE, TURBO, 108000,    0x0c,    0x00,       108,   4 }
114185377Ssam	},
115185377Ssam};
116185377Ssam
117185377SsamHAL_RATE_TABLE ar5212_11b_table = {
118185377Ssam	4,  /* number of rates */
119185377Ssam	{ 0 },
120185377Ssam	{
121185377Ssam/*                                                 short            ctrl  */
122185377Ssam/*                valid                rateCode Preamble  dot11Rate Rate */
123185377Ssam/*   1 Mb */ {  AH_TRUE,  CCK,    1000,    0x1b,    0x00, (0x80| 2),   0 },
124185377Ssam/*   2 Mb */ {  AH_TRUE,  CCK,    2000,    0x1a,    0x04, (0x80| 4),   1 },
125185377Ssam/* 5.5 Mb */ {  AH_TRUE,  CCK,    5500,    0x19,    0x04, (0x80|11),   1 },
126185377Ssam/*  11 Mb */ {  AH_TRUE,  CCK,   11000,    0x18,    0x04, (0x80|22),   1 }
127185377Ssam	},
128185377Ssam};
129185377Ssam
130185377Ssam
131185377Ssam/* Venice TODO: roundUpRate() is broken when the rate table does not represent rates
132185377Ssam * in increasing order  e.g.  5.5, 11, 6, 9.
133185377Ssam * An average rate of 6 Mbps will currently map to 11 Mbps.
134185377Ssam */
135185377SsamHAL_RATE_TABLE ar5212_11g_table = {
136185377Ssam	12,  /* number of rates */
137185377Ssam	{ 0 },
138185377Ssam	{
139185377Ssam/*                                                 short            ctrl  */
140185377Ssam/*                valid                rateCode Preamble  dot11Rate Rate */
141185377Ssam/*   1 Mb */ {  AH_TRUE, CCK,     1000,    0x1b,    0x00, (0x80| 2),   0 },
142185377Ssam/*   2 Mb */ {  AH_TRUE, CCK,     2000,    0x1a,    0x04, (0x80| 4),   1 },
143185377Ssam/* 5.5 Mb */ {  AH_TRUE, CCK,     5500,    0x19,    0x04, (0x80|11),   2 },
144185377Ssam/*  11 Mb */ {  AH_TRUE, CCK,    11000,    0x18,    0x04, (0x80|22),   3 },
145185377Ssam/* remove rates 6, 9 from rate ctrl */
146185377Ssam/*   6 Mb */ { AH_FALSE, OFDM,    6000,    0x0b,    0x00,        12,   4 },
147185377Ssam/*   9 Mb */ { AH_FALSE, OFDM,    9000,    0x0f,    0x00,        18,   4 },
148185377Ssam/*  12 Mb */ {  AH_TRUE, OFDM,   12000,    0x0a,    0x00,        24,   6 },
149185377Ssam/*  18 Mb */ {  AH_TRUE, OFDM,   18000,    0x0e,    0x00,        36,   6 },
150185377Ssam/*  24 Mb */ {  AH_TRUE, OFDM,   24000,    0x09,    0x00,        48,   8 },
151185377Ssam/*  36 Mb */ {  AH_TRUE, OFDM,   36000,    0x0d,    0x00,        72,   8 },
152185377Ssam/*  48 Mb */ {  AH_TRUE, OFDM,   48000,    0x08,    0x00,        96,   8 },
153185377Ssam/*  54 Mb */ {  AH_TRUE, OFDM,   54000,    0x0c,    0x00,       108,   8 }
154185377Ssam	},
155185377Ssam};
156185377Ssam
157185377Ssam#undef	OFDM
158185377Ssam#undef	CCK
159185377Ssam#undef	TURBO
160185377Ssam#undef	XR
161185377Ssam
162185377Ssamconst HAL_RATE_TABLE *
163185377Ssamar5212GetRateTable(struct ath_hal *ah, u_int mode)
164185377Ssam{
165185377Ssam	HAL_RATE_TABLE *rt;
166185377Ssam	switch (mode) {
167185377Ssam	case HAL_MODE_11A:
168185377Ssam		rt = &ar5212_11a_table;
169185377Ssam		break;
170185377Ssam	case HAL_MODE_11B:
171185377Ssam		rt = &ar5212_11b_table;
172185377Ssam		break;
173185377Ssam	case HAL_MODE_11G:
174185377Ssam#ifdef notdef
175185377Ssam	case HAL_MODE_PUREG:
176185377Ssam#endif
177185377Ssam		rt =  &ar5212_11g_table;
178185377Ssam		break;
179185377Ssam	case HAL_MODE_108A:
180185377Ssam	case HAL_MODE_TURBO:
181185377Ssam		rt =  &ar5212_turboa_table;
182185377Ssam		break;
183185377Ssam	case HAL_MODE_108G:
184185377Ssam		rt =  &ar5212_turbog_table;
185185377Ssam		break;
186185377Ssam	case HAL_MODE_11A_HALF_RATE:
187185380Ssam	case HAL_MODE_11G_HALF_RATE:
188185380Ssam		rt = &ar5212_half_table;
189185377Ssam		break;
190185377Ssam	case HAL_MODE_11A_QUARTER_RATE:
191185380Ssam	case HAL_MODE_11G_QUARTER_RATE:
192185380Ssam		rt = &ar5212_quarter_table;
193185377Ssam		break;
194185377Ssam	default:
195185377Ssam		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n",
196185377Ssam		    __func__, mode);
197185377Ssam		return AH_NULL;
198185377Ssam	}
199185377Ssam	ath_hal_setupratetable(ah, rt);
200185377Ssam	return rt;
201185377Ssam}
202