• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/net/wireless/ath/ath5k/
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20/**************\
21* Capabilities *
22\**************/
23
24#include "ath5k.h"
25#include "reg.h"
26#include "debug.h"
27#include "base.h"
28
29/*
30 * Fill the capabilities struct
31 * TODO: Merge this with EEPROM code when we are done with it
32 */
33int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
34{
35	u16 ee_header;
36
37	/* Capabilities stored in the EEPROM */
38	ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
39
40	if (ah->ah_version == AR5K_AR5210) {
41		/*
42		 * Set radio capabilities
43		 * (The AR5110 only supports the middle 5GHz band)
44		 */
45		ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
46		ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
47		ah->ah_capabilities.cap_range.range_2ghz_min = 0;
48		ah->ah_capabilities.cap_range.range_2ghz_max = 0;
49
50		/* Set supported modes */
51		__set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
52		__set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
53	} else {
54
55		/*
56		 * Set radio capabilities
57		 */
58
59		if (AR5K_EEPROM_HDR_11A(ee_header)) {
60			/* 4920 */
61			ah->ah_capabilities.cap_range.range_5ghz_min = 5005;
62			ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
63
64			/* Set supported modes */
65			__set_bit(AR5K_MODE_11A,
66					ah->ah_capabilities.cap_mode);
67			__set_bit(AR5K_MODE_11A_TURBO,
68					ah->ah_capabilities.cap_mode);
69			if (ah->ah_version == AR5K_AR5212)
70				__set_bit(AR5K_MODE_11G_TURBO,
71						ah->ah_capabilities.cap_mode);
72		}
73
74		/* Enable  802.11b if a 2GHz capable radio (2111/5112) is
75		 * connected */
76		if (AR5K_EEPROM_HDR_11B(ee_header) ||
77		    (AR5K_EEPROM_HDR_11G(ee_header) &&
78		     ah->ah_version != AR5K_AR5211)) {
79			/* 2312 */
80			ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
81			ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
82
83			if (AR5K_EEPROM_HDR_11B(ee_header))
84				__set_bit(AR5K_MODE_11B,
85						ah->ah_capabilities.cap_mode);
86
87			if (AR5K_EEPROM_HDR_11G(ee_header) &&
88			    ah->ah_version != AR5K_AR5211)
89				__set_bit(AR5K_MODE_11G,
90						ah->ah_capabilities.cap_mode);
91		}
92	}
93
94	/* Set number of supported TX queues */
95	if (ah->ah_version == AR5K_AR5210)
96		ah->ah_capabilities.cap_queues.q_tx_num =
97			AR5K_NUM_TX_QUEUES_NOQCU;
98	else
99		ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
100
101	/* newer hardware has PHY error counters */
102	if (ah->ah_mac_srev >= AR5K_SREV_AR5213A)
103		ah->ah_capabilities.cap_has_phyerr_counters = true;
104	else
105		ah->ah_capabilities.cap_has_phyerr_counters = false;
106
107	return 0;
108}
109
110/* Main function used by the driver part to check caps */
111int ath5k_hw_get_capability(struct ath5k_hw *ah,
112		enum ath5k_capability_type cap_type,
113		u32 capability, u32 *result)
114{
115	switch (cap_type) {
116	case AR5K_CAP_NUM_TXQUEUES:
117		if (result) {
118			if (ah->ah_version == AR5K_AR5210)
119				*result = AR5K_NUM_TX_QUEUES_NOQCU;
120			else
121				*result = AR5K_NUM_TX_QUEUES;
122			goto yes;
123		}
124	case AR5K_CAP_VEOL:
125		goto yes;
126	case AR5K_CAP_COMPRESSION:
127		if (ah->ah_version == AR5K_AR5212)
128			goto yes;
129		else
130			goto no;
131	case AR5K_CAP_BURST:
132		goto yes;
133	case AR5K_CAP_TPC:
134		goto yes;
135	case AR5K_CAP_BSSIDMASK:
136		if (ah->ah_version == AR5K_AR5212)
137			goto yes;
138		else
139			goto no;
140	case AR5K_CAP_XR:
141		if (ah->ah_version == AR5K_AR5212)
142			goto yes;
143		else
144			goto no;
145	default:
146		goto no;
147	}
148
149no:
150	return -EINVAL;
151yes:
152	return 0;
153}
154
155/*
156 * TODO: Following functions should be part of a new function
157 * set_capability
158 */
159
160int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
161		u16 assoc_id)
162{
163	if (ah->ah_version == AR5K_AR5210) {
164		AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
165			AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
166		return 0;
167	}
168
169	return -EIO;
170}
171
172int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
173{
174	if (ah->ah_version == AR5K_AR5210) {
175		AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
176			AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
177		return 0;
178	}
179
180	return -EIO;
181}
182