diff options
Diffstat (limited to 'drivers/net/wireless/ath5k/caps.c')
-rw-r--r-- | drivers/net/wireless/ath5k/caps.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath5k/caps.c new file mode 100644 index 000000000000..150f5ed204a0 --- /dev/null +++ b/drivers/net/wireless/ath5k/caps.c | |||
@@ -0,0 +1,193 @@ | |||
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 | */ | ||
33 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | ||
34 | { | ||
35 | u16 ee_header; | ||
36 | |||
37 | ATH5K_TRACE(ah->ah_sc); | ||
38 | /* Capabilities stored in the EEPROM */ | ||
39 | ee_header = ah->ah_capabilities.cap_eeprom.ee_header; | ||
40 | |||
41 | if (ah->ah_version == AR5K_AR5210) { | ||
42 | /* | ||
43 | * Set radio capabilities | ||
44 | * (The AR5110 only supports the middle 5GHz band) | ||
45 | */ | ||
46 | ah->ah_capabilities.cap_range.range_5ghz_min = 5120; | ||
47 | ah->ah_capabilities.cap_range.range_5ghz_max = 5430; | ||
48 | ah->ah_capabilities.cap_range.range_2ghz_min = 0; | ||
49 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; | ||
50 | |||
51 | /* Set supported modes */ | ||
52 | __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); | ||
53 | __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode); | ||
54 | } else { | ||
55 | /* | ||
56 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz | ||
57 | * XXX and from 2312 to 2732GHz. There are problems with the | ||
58 | * XXX current ieee80211 implementation because the IEEE | ||
59 | * XXX channel mapping does not support negative channel | ||
60 | * XXX numbers (2312MHz is channel -19). Of course, this | ||
61 | * XXX doesn't matter because these channels are out of range | ||
62 | * XXX but some regulation domains like MKK (Japan) will | ||
63 | * XXX support frequencies somewhere around 4.8GHz. | ||
64 | */ | ||
65 | |||
66 | /* | ||
67 | * Set radio capabilities | ||
68 | */ | ||
69 | |||
70 | if (AR5K_EEPROM_HDR_11A(ee_header)) { | ||
71 | /* 4920 */ | ||
72 | ah->ah_capabilities.cap_range.range_5ghz_min = 5005; | ||
73 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; | ||
74 | |||
75 | /* Set supported modes */ | ||
76 | __set_bit(AR5K_MODE_11A, | ||
77 | ah->ah_capabilities.cap_mode); | ||
78 | __set_bit(AR5K_MODE_11A_TURBO, | ||
79 | ah->ah_capabilities.cap_mode); | ||
80 | if (ah->ah_version == AR5K_AR5212) | ||
81 | __set_bit(AR5K_MODE_11G_TURBO, | ||
82 | ah->ah_capabilities.cap_mode); | ||
83 | } | ||
84 | |||
85 | /* Enable 802.11b if a 2GHz capable radio (2111/5112) is | ||
86 | * connected */ | ||
87 | if (AR5K_EEPROM_HDR_11B(ee_header) || | ||
88 | AR5K_EEPROM_HDR_11G(ee_header)) { | ||
89 | /* 2312 */ | ||
90 | ah->ah_capabilities.cap_range.range_2ghz_min = 2412; | ||
91 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; | ||
92 | |||
93 | if (AR5K_EEPROM_HDR_11B(ee_header)) | ||
94 | __set_bit(AR5K_MODE_11B, | ||
95 | ah->ah_capabilities.cap_mode); | ||
96 | |||
97 | if (AR5K_EEPROM_HDR_11G(ee_header)) | ||
98 | __set_bit(AR5K_MODE_11G, | ||
99 | ah->ah_capabilities.cap_mode); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* GPIO */ | ||
104 | ah->ah_gpio_npins = AR5K_NUM_GPIO; | ||
105 | |||
106 | /* Set number of supported TX queues */ | ||
107 | if (ah->ah_version == AR5K_AR5210) | ||
108 | ah->ah_capabilities.cap_queues.q_tx_num = | ||
109 | AR5K_NUM_TX_QUEUES_NOQCU; | ||
110 | else | ||
111 | ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | /* Main function used by the driver part to check caps */ | ||
117 | int ath5k_hw_get_capability(struct ath5k_hw *ah, | ||
118 | enum ath5k_capability_type cap_type, | ||
119 | u32 capability, u32 *result) | ||
120 | { | ||
121 | ATH5K_TRACE(ah->ah_sc); | ||
122 | |||
123 | switch (cap_type) { | ||
124 | case AR5K_CAP_NUM_TXQUEUES: | ||
125 | if (result) { | ||
126 | if (ah->ah_version == AR5K_AR5210) | ||
127 | *result = AR5K_NUM_TX_QUEUES_NOQCU; | ||
128 | else | ||
129 | *result = AR5K_NUM_TX_QUEUES; | ||
130 | goto yes; | ||
131 | } | ||
132 | case AR5K_CAP_VEOL: | ||
133 | goto yes; | ||
134 | case AR5K_CAP_COMPRESSION: | ||
135 | if (ah->ah_version == AR5K_AR5212) | ||
136 | goto yes; | ||
137 | else | ||
138 | goto no; | ||
139 | case AR5K_CAP_BURST: | ||
140 | goto yes; | ||
141 | case AR5K_CAP_TPC: | ||
142 | goto yes; | ||
143 | case AR5K_CAP_BSSIDMASK: | ||
144 | if (ah->ah_version == AR5K_AR5212) | ||
145 | goto yes; | ||
146 | else | ||
147 | goto no; | ||
148 | case AR5K_CAP_XR: | ||
149 | if (ah->ah_version == AR5K_AR5212) | ||
150 | goto yes; | ||
151 | else | ||
152 | goto no; | ||
153 | default: | ||
154 | goto no; | ||
155 | } | ||
156 | |||
157 | no: | ||
158 | return -EINVAL; | ||
159 | yes: | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * TODO: Following functions should be part of a new function | ||
165 | * set_capability | ||
166 | */ | ||
167 | |||
168 | int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, | ||
169 | u16 assoc_id) | ||
170 | { | ||
171 | ATH5K_TRACE(ah->ah_sc); | ||
172 | |||
173 | if (ah->ah_version == AR5K_AR5210) { | ||
174 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
175 | AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | return -EIO; | ||
180 | } | ||
181 | |||
182 | int ath5k_hw_disable_pspoll(struct ath5k_hw *ah) | ||
183 | { | ||
184 | ATH5K_TRACE(ah->ah_sc); | ||
185 | |||
186 | if (ah->ah_version == AR5K_AR5210) { | ||
187 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, | ||
188 | AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | return -EIO; | ||
193 | } | ||