diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-11-04 12:36:40 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-06 16:48:58 -0500 |
commit | f445061630c7a4a85193fdef006234f94f71c366 (patch) | |
tree | 518141ce242b2722e532318034525da282dc945b /drivers/net/wireless/rt2x00/rt2800usb.c | |
parent | 89297425c2104b187c25d6260a41345c491c8f18 (diff) |
rt2800: add rt2800lib (part two)
Code unification.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 856 |
1 files changed, 15 insertions, 841 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6bd646a979af..365f66fe7c68 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -45,832 +45,6 @@ static int modparam_nohwcrypt = 1; | |||
45 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 45 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); |
46 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 46 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
47 | 47 | ||
48 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
49 | static const struct rt2x00debug rt2800usb_rt2x00debug = { | ||
50 | .owner = THIS_MODULE, | ||
51 | .csr = { | ||
52 | .read = rt2800_register_read, | ||
53 | .write = rt2800_register_write, | ||
54 | .flags = RT2X00DEBUGFS_OFFSET, | ||
55 | .word_base = CSR_REG_BASE, | ||
56 | .word_size = sizeof(u32), | ||
57 | .word_count = CSR_REG_SIZE / sizeof(u32), | ||
58 | }, | ||
59 | .eeprom = { | ||
60 | .read = rt2x00_eeprom_read, | ||
61 | .write = rt2x00_eeprom_write, | ||
62 | .word_base = EEPROM_BASE, | ||
63 | .word_size = sizeof(u16), | ||
64 | .word_count = EEPROM_SIZE / sizeof(u16), | ||
65 | }, | ||
66 | .bbp = { | ||
67 | .read = rt2800_bbp_read, | ||
68 | .write = rt2800_bbp_write, | ||
69 | .word_base = BBP_BASE, | ||
70 | .word_size = sizeof(u8), | ||
71 | .word_count = BBP_SIZE / sizeof(u8), | ||
72 | }, | ||
73 | .rf = { | ||
74 | .read = rt2x00_rf_read, | ||
75 | .write = rt2800_rf_write, | ||
76 | .word_base = RF_BASE, | ||
77 | .word_size = sizeof(u32), | ||
78 | .word_count = RF_SIZE / sizeof(u32), | ||
79 | }, | ||
80 | }; | ||
81 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
82 | |||
83 | static int rt2800usb_rfkill_poll(struct rt2x00_dev *rt2x00dev) | ||
84 | { | ||
85 | u32 reg; | ||
86 | |||
87 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
88 | return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2); | ||
89 | } | ||
90 | |||
91 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
92 | static void rt2800usb_brightness_set(struct led_classdev *led_cdev, | ||
93 | enum led_brightness brightness) | ||
94 | { | ||
95 | struct rt2x00_led *led = | ||
96 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
97 | unsigned int enabled = brightness != LED_OFF; | ||
98 | unsigned int bg_mode = | ||
99 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); | ||
100 | unsigned int polarity = | ||
101 | rt2x00_get_field16(led->rt2x00dev->led_mcu_reg, | ||
102 | EEPROM_FREQ_LED_POLARITY); | ||
103 | unsigned int ledmode = | ||
104 | rt2x00_get_field16(led->rt2x00dev->led_mcu_reg, | ||
105 | EEPROM_FREQ_LED_MODE); | ||
106 | |||
107 | if (led->type == LED_TYPE_RADIO) { | ||
108 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | ||
109 | enabled ? 0x20 : 0); | ||
110 | } else if (led->type == LED_TYPE_ASSOC) { | ||
111 | rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode, | ||
112 | enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20); | ||
113 | } else if (led->type == LED_TYPE_QUALITY) { | ||
114 | /* | ||
115 | * The brightness is divided into 6 levels (0 - 5), | ||
116 | * The specs tell us the following levels: | ||
117 | * 0, 1 ,3, 7, 15, 31 | ||
118 | * to determine the level in a simple way we can simply | ||
119 | * work with bitshifting: | ||
120 | * (1 << level) - 1 | ||
121 | */ | ||
122 | rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, | ||
123 | (1 << brightness / (LED_FULL / 6)) - 1, | ||
124 | polarity); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | static int rt2800usb_blink_set(struct led_classdev *led_cdev, | ||
129 | unsigned long *delay_on, | ||
130 | unsigned long *delay_off) | ||
131 | { | ||
132 | struct rt2x00_led *led = | ||
133 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
134 | u32 reg; | ||
135 | |||
136 | rt2800_register_read(led->rt2x00dev, LED_CFG, ®); | ||
137 | rt2x00_set_field32(®, LED_CFG_ON_PERIOD, *delay_on); | ||
138 | rt2x00_set_field32(®, LED_CFG_OFF_PERIOD, *delay_off); | ||
139 | rt2x00_set_field32(®, LED_CFG_SLOW_BLINK_PERIOD, 3); | ||
140 | rt2x00_set_field32(®, LED_CFG_R_LED_MODE, 3); | ||
141 | rt2x00_set_field32(®, LED_CFG_G_LED_MODE, 12); | ||
142 | rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, 3); | ||
143 | rt2x00_set_field32(®, LED_CFG_LED_POLAR, 1); | ||
144 | rt2800_register_write(led->rt2x00dev, LED_CFG, reg); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static void rt2800usb_init_led(struct rt2x00_dev *rt2x00dev, | ||
150 | struct rt2x00_led *led, | ||
151 | enum led_type type) | ||
152 | { | ||
153 | led->rt2x00dev = rt2x00dev; | ||
154 | led->type = type; | ||
155 | led->led_dev.brightness_set = rt2800usb_brightness_set; | ||
156 | led->led_dev.blink_set = rt2800usb_blink_set; | ||
157 | led->flags = LED_INITIALIZED; | ||
158 | } | ||
159 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
160 | |||
161 | /* | ||
162 | * Configuration handlers. | ||
163 | */ | ||
164 | static void rt2800usb_config_wcid_attr(struct rt2x00_dev *rt2x00dev, | ||
165 | struct rt2x00lib_crypto *crypto, | ||
166 | struct ieee80211_key_conf *key) | ||
167 | { | ||
168 | struct mac_wcid_entry wcid_entry; | ||
169 | struct mac_iveiv_entry iveiv_entry; | ||
170 | u32 offset; | ||
171 | u32 reg; | ||
172 | |||
173 | offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx); | ||
174 | |||
175 | rt2800_register_read(rt2x00dev, offset, ®); | ||
176 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, | ||
177 | !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); | ||
178 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER, | ||
179 | (crypto->cmd == SET_KEY) * crypto->cipher); | ||
180 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, | ||
181 | (crypto->cmd == SET_KEY) * crypto->bssidx); | ||
182 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher); | ||
183 | rt2800_register_write(rt2x00dev, offset, reg); | ||
184 | |||
185 | offset = MAC_IVEIV_ENTRY(key->hw_key_idx); | ||
186 | |||
187 | memset(&iveiv_entry, 0, sizeof(iveiv_entry)); | ||
188 | if ((crypto->cipher == CIPHER_TKIP) || | ||
189 | (crypto->cipher == CIPHER_TKIP_NO_MIC) || | ||
190 | (crypto->cipher == CIPHER_AES)) | ||
191 | iveiv_entry.iv[3] |= 0x20; | ||
192 | iveiv_entry.iv[3] |= key->keyidx << 6; | ||
193 | rt2800_register_multiwrite(rt2x00dev, offset, | ||
194 | &iveiv_entry, sizeof(iveiv_entry)); | ||
195 | |||
196 | offset = MAC_WCID_ENTRY(key->hw_key_idx); | ||
197 | |||
198 | memset(&wcid_entry, 0, sizeof(wcid_entry)); | ||
199 | if (crypto->cmd == SET_KEY) | ||
200 | memcpy(&wcid_entry, crypto->address, ETH_ALEN); | ||
201 | rt2800_register_multiwrite(rt2x00dev, offset, | ||
202 | &wcid_entry, sizeof(wcid_entry)); | ||
203 | } | ||
204 | |||
205 | static int rt2800usb_config_shared_key(struct rt2x00_dev *rt2x00dev, | ||
206 | struct rt2x00lib_crypto *crypto, | ||
207 | struct ieee80211_key_conf *key) | ||
208 | { | ||
209 | struct hw_key_entry key_entry; | ||
210 | struct rt2x00_field32 field; | ||
211 | u32 offset; | ||
212 | u32 reg; | ||
213 | |||
214 | if (crypto->cmd == SET_KEY) { | ||
215 | key->hw_key_idx = (4 * crypto->bssidx) + key->keyidx; | ||
216 | |||
217 | memcpy(key_entry.key, crypto->key, | ||
218 | sizeof(key_entry.key)); | ||
219 | memcpy(key_entry.tx_mic, crypto->tx_mic, | ||
220 | sizeof(key_entry.tx_mic)); | ||
221 | memcpy(key_entry.rx_mic, crypto->rx_mic, | ||
222 | sizeof(key_entry.rx_mic)); | ||
223 | |||
224 | offset = SHARED_KEY_ENTRY(key->hw_key_idx); | ||
225 | rt2800_register_multiwrite(rt2x00dev, offset, | ||
226 | &key_entry, sizeof(key_entry)); | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * The cipher types are stored over multiple registers | ||
231 | * starting with SHARED_KEY_MODE_BASE each word will have | ||
232 | * 32 bits and contains the cipher types for 2 bssidx each. | ||
233 | * Using the correct defines correctly will cause overhead, | ||
234 | * so just calculate the correct offset. | ||
235 | */ | ||
236 | field.bit_offset = 4 * (key->hw_key_idx % 8); | ||
237 | field.bit_mask = 0x7 << field.bit_offset; | ||
238 | |||
239 | offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8); | ||
240 | |||
241 | rt2800_register_read(rt2x00dev, offset, ®); | ||
242 | rt2x00_set_field32(®, field, | ||
243 | (crypto->cmd == SET_KEY) * crypto->cipher); | ||
244 | rt2800_register_write(rt2x00dev, offset, reg); | ||
245 | |||
246 | /* | ||
247 | * Update WCID information | ||
248 | */ | ||
249 | rt2800usb_config_wcid_attr(rt2x00dev, crypto, key); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static int rt2800usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | ||
255 | struct rt2x00lib_crypto *crypto, | ||
256 | struct ieee80211_key_conf *key) | ||
257 | { | ||
258 | struct hw_key_entry key_entry; | ||
259 | u32 offset; | ||
260 | |||
261 | if (crypto->cmd == SET_KEY) { | ||
262 | /* | ||
263 | * 1 pairwise key is possible per AID, this means that the AID | ||
264 | * equals our hw_key_idx. Make sure the WCID starts _after_ the | ||
265 | * last possible shared key entry. | ||
266 | */ | ||
267 | if (crypto->aid > (256 - 32)) | ||
268 | return -ENOSPC; | ||
269 | |||
270 | key->hw_key_idx = 32 + crypto->aid; | ||
271 | |||
272 | memcpy(key_entry.key, crypto->key, | ||
273 | sizeof(key_entry.key)); | ||
274 | memcpy(key_entry.tx_mic, crypto->tx_mic, | ||
275 | sizeof(key_entry.tx_mic)); | ||
276 | memcpy(key_entry.rx_mic, crypto->rx_mic, | ||
277 | sizeof(key_entry.rx_mic)); | ||
278 | |||
279 | offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx); | ||
280 | rt2800_register_multiwrite(rt2x00dev, offset, | ||
281 | &key_entry, sizeof(key_entry)); | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | * Update WCID information | ||
286 | */ | ||
287 | rt2800usb_config_wcid_attr(rt2x00dev, crypto, key); | ||
288 | |||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static void rt2800usb_config_filter(struct rt2x00_dev *rt2x00dev, | ||
293 | const unsigned int filter_flags) | ||
294 | { | ||
295 | u32 reg; | ||
296 | |||
297 | /* | ||
298 | * Start configuration steps. | ||
299 | * Note that the version error will always be dropped | ||
300 | * and broadcast frames will always be accepted since | ||
301 | * there is no filter for it at this time. | ||
302 | */ | ||
303 | rt2800_register_read(rt2x00dev, RX_FILTER_CFG, ®); | ||
304 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CRC_ERROR, | ||
305 | !(filter_flags & FIF_FCSFAIL)); | ||
306 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PHY_ERROR, | ||
307 | !(filter_flags & FIF_PLCPFAIL)); | ||
308 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_TO_ME, | ||
309 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
310 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0); | ||
311 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_VER_ERROR, 1); | ||
312 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_MULTICAST, | ||
313 | !(filter_flags & FIF_ALLMULTI)); | ||
314 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BROADCAST, 0); | ||
315 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_DUPLICATE, 1); | ||
316 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CF_END_ACK, | ||
317 | !(filter_flags & FIF_CONTROL)); | ||
318 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CF_END, | ||
319 | !(filter_flags & FIF_CONTROL)); | ||
320 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_ACK, | ||
321 | !(filter_flags & FIF_CONTROL)); | ||
322 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CTS, | ||
323 | !(filter_flags & FIF_CONTROL)); | ||
324 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_RTS, | ||
325 | !(filter_flags & FIF_CONTROL)); | ||
326 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PSPOLL, | ||
327 | !(filter_flags & FIF_PSPOLL)); | ||
328 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BA, 1); | ||
329 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_BAR, 0); | ||
330 | rt2x00_set_field32(®, RX_FILTER_CFG_DROP_CNTL, | ||
331 | !(filter_flags & FIF_CONTROL)); | ||
332 | rt2800_register_write(rt2x00dev, RX_FILTER_CFG, reg); | ||
333 | } | ||
334 | |||
335 | static void rt2800usb_config_intf(struct rt2x00_dev *rt2x00dev, | ||
336 | struct rt2x00_intf *intf, | ||
337 | struct rt2x00intf_conf *conf, | ||
338 | const unsigned int flags) | ||
339 | { | ||
340 | unsigned int beacon_base; | ||
341 | u32 reg; | ||
342 | |||
343 | if (flags & CONFIG_UPDATE_TYPE) { | ||
344 | /* | ||
345 | * Clear current synchronisation setup. | ||
346 | * For the Beacon base registers we only need to clear | ||
347 | * the first byte since that byte contains the VALID and OWNER | ||
348 | * bits which (when set to 0) will invalidate the entire beacon. | ||
349 | */ | ||
350 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
351 | rt2800_register_write(rt2x00dev, beacon_base, 0); | ||
352 | |||
353 | /* | ||
354 | * Enable synchronisation. | ||
355 | */ | ||
356 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
357 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
358 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); | ||
359 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
360 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
361 | } | ||
362 | |||
363 | if (flags & CONFIG_UPDATE_MAC) { | ||
364 | reg = le32_to_cpu(conf->mac[1]); | ||
365 | rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); | ||
366 | conf->mac[1] = cpu_to_le32(reg); | ||
367 | |||
368 | rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, | ||
369 | conf->mac, sizeof(conf->mac)); | ||
370 | } | ||
371 | |||
372 | if (flags & CONFIG_UPDATE_BSSID) { | ||
373 | reg = le32_to_cpu(conf->bssid[1]); | ||
374 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 0); | ||
375 | rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 0); | ||
376 | conf->bssid[1] = cpu_to_le32(reg); | ||
377 | |||
378 | rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, | ||
379 | conf->bssid, sizeof(conf->bssid)); | ||
380 | } | ||
381 | } | ||
382 | |||
383 | static void rt2800usb_config_erp(struct rt2x00_dev *rt2x00dev, | ||
384 | struct rt2x00lib_erp *erp) | ||
385 | { | ||
386 | u32 reg; | ||
387 | |||
388 | rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, ®); | ||
389 | rt2x00_set_field32(®, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 0x20); | ||
390 | rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg); | ||
391 | |||
392 | rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®); | ||
393 | rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, | ||
394 | !!erp->short_preamble); | ||
395 | rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, | ||
396 | !!erp->short_preamble); | ||
397 | rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); | ||
398 | |||
399 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); | ||
400 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, | ||
401 | erp->cts_protection ? 2 : 0); | ||
402 | rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); | ||
403 | |||
404 | rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, | ||
405 | erp->basic_rates); | ||
406 | rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); | ||
407 | |||
408 | rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®); | ||
409 | rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time); | ||
410 | rt2x00_set_field32(®, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2); | ||
411 | rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); | ||
412 | |||
413 | rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); | ||
414 | rt2x00_set_field32(®, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs); | ||
415 | rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs); | ||
416 | rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4); | ||
417 | rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); | ||
418 | rt2x00_set_field32(®, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1); | ||
419 | rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); | ||
420 | |||
421 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
422 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, | ||
423 | erp->beacon_int * 16); | ||
424 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
425 | } | ||
426 | |||
427 | static void rt2800usb_config_ant(struct rt2x00_dev *rt2x00dev, | ||
428 | struct antenna_setup *ant) | ||
429 | { | ||
430 | u8 r1; | ||
431 | u8 r3; | ||
432 | |||
433 | rt2800_bbp_read(rt2x00dev, 1, &r1); | ||
434 | rt2800_bbp_read(rt2x00dev, 3, &r3); | ||
435 | |||
436 | /* | ||
437 | * Configure the TX antenna. | ||
438 | */ | ||
439 | switch ((int)ant->tx) { | ||
440 | case 1: | ||
441 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); | ||
442 | break; | ||
443 | case 2: | ||
444 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2); | ||
445 | break; | ||
446 | case 3: | ||
447 | /* Do nothing */ | ||
448 | break; | ||
449 | } | ||
450 | |||
451 | /* | ||
452 | * Configure the RX antenna. | ||
453 | */ | ||
454 | switch ((int)ant->rx) { | ||
455 | case 1: | ||
456 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); | ||
457 | break; | ||
458 | case 2: | ||
459 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1); | ||
460 | break; | ||
461 | case 3: | ||
462 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2); | ||
463 | break; | ||
464 | } | ||
465 | |||
466 | rt2800_bbp_write(rt2x00dev, 3, r3); | ||
467 | rt2800_bbp_write(rt2x00dev, 1, r1); | ||
468 | } | ||
469 | |||
470 | static void rt2800usb_config_lna_gain(struct rt2x00_dev *rt2x00dev, | ||
471 | struct rt2x00lib_conf *libconf) | ||
472 | { | ||
473 | u16 eeprom; | ||
474 | short lna_gain; | ||
475 | |||
476 | if (libconf->rf.channel <= 14) { | ||
477 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom); | ||
478 | lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG); | ||
479 | } else if (libconf->rf.channel <= 64) { | ||
480 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom); | ||
481 | lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0); | ||
482 | } else if (libconf->rf.channel <= 128) { | ||
483 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom); | ||
484 | lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1); | ||
485 | } else { | ||
486 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom); | ||
487 | lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2); | ||
488 | } | ||
489 | |||
490 | rt2x00dev->lna_gain = lna_gain; | ||
491 | } | ||
492 | |||
493 | static void rt2800usb_config_channel_rt2x(struct rt2x00_dev *rt2x00dev, | ||
494 | struct ieee80211_conf *conf, | ||
495 | struct rf_channel *rf, | ||
496 | struct channel_info *info) | ||
497 | { | ||
498 | rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); | ||
499 | |||
500 | if (rt2x00dev->default_ant.tx == 1) | ||
501 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1); | ||
502 | |||
503 | if (rt2x00dev->default_ant.rx == 1) { | ||
504 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1); | ||
505 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); | ||
506 | } else if (rt2x00dev->default_ant.rx == 2) | ||
507 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); | ||
508 | |||
509 | if (rf->channel > 14) { | ||
510 | /* | ||
511 | * When TX power is below 0, we should increase it by 7 to | ||
512 | * make it a positive value (Minumum value is -7). | ||
513 | * However this means that values between 0 and 7 have | ||
514 | * double meaning, and we should set a 7DBm boost flag. | ||
515 | */ | ||
516 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, | ||
517 | (info->tx_power1 >= 0)); | ||
518 | |||
519 | if (info->tx_power1 < 0) | ||
520 | info->tx_power1 += 7; | ||
521 | |||
522 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, | ||
523 | TXPOWER_A_TO_DEV(info->tx_power1)); | ||
524 | |||
525 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, | ||
526 | (info->tx_power2 >= 0)); | ||
527 | |||
528 | if (info->tx_power2 < 0) | ||
529 | info->tx_power2 += 7; | ||
530 | |||
531 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, | ||
532 | TXPOWER_A_TO_DEV(info->tx_power2)); | ||
533 | } else { | ||
534 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, | ||
535 | TXPOWER_G_TO_DEV(info->tx_power1)); | ||
536 | rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, | ||
537 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
538 | } | ||
539 | |||
540 | rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); | ||
541 | |||
542 | rt2800_rf_write(rt2x00dev, 1, rf->rf1); | ||
543 | rt2800_rf_write(rt2x00dev, 2, rf->rf2); | ||
544 | rt2800_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004); | ||
545 | rt2800_rf_write(rt2x00dev, 4, rf->rf4); | ||
546 | |||
547 | udelay(200); | ||
548 | |||
549 | rt2800_rf_write(rt2x00dev, 1, rf->rf1); | ||
550 | rt2800_rf_write(rt2x00dev, 2, rf->rf2); | ||
551 | rt2800_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004); | ||
552 | rt2800_rf_write(rt2x00dev, 4, rf->rf4); | ||
553 | |||
554 | udelay(200); | ||
555 | |||
556 | rt2800_rf_write(rt2x00dev, 1, rf->rf1); | ||
557 | rt2800_rf_write(rt2x00dev, 2, rf->rf2); | ||
558 | rt2800_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004); | ||
559 | rt2800_rf_write(rt2x00dev, 4, rf->rf4); | ||
560 | } | ||
561 | |||
562 | static void rt2800usb_config_channel_rt3x(struct rt2x00_dev *rt2x00dev, | ||
563 | struct ieee80211_conf *conf, | ||
564 | struct rf_channel *rf, | ||
565 | struct channel_info *info) | ||
566 | { | ||
567 | u8 rfcsr; | ||
568 | |||
569 | rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1); | ||
570 | rt2800_rfcsr_write(rt2x00dev, 2, rf->rf3); | ||
571 | |||
572 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); | ||
573 | rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2); | ||
574 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | ||
575 | |||
576 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); | ||
577 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, | ||
578 | TXPOWER_G_TO_DEV(info->tx_power1)); | ||
579 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); | ||
580 | |||
581 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); | ||
582 | rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); | ||
583 | rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); | ||
584 | |||
585 | rt2800_rfcsr_write(rt2x00dev, 24, | ||
586 | rt2x00dev->calibration[conf_is_ht40(conf)]); | ||
587 | |||
588 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); | ||
589 | rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); | ||
590 | rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); | ||
591 | } | ||
592 | |||
593 | static void rt2800usb_config_channel(struct rt2x00_dev *rt2x00dev, | ||
594 | struct ieee80211_conf *conf, | ||
595 | struct rf_channel *rf, | ||
596 | struct channel_info *info) | ||
597 | { | ||
598 | u32 reg; | ||
599 | unsigned int tx_pin; | ||
600 | u8 bbp; | ||
601 | |||
602 | if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION) | ||
603 | rt2800usb_config_channel_rt2x(rt2x00dev, conf, rf, info); | ||
604 | else | ||
605 | rt2800usb_config_channel_rt3x(rt2x00dev, conf, rf, info); | ||
606 | |||
607 | /* | ||
608 | * Change BBP settings | ||
609 | */ | ||
610 | rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); | ||
611 | rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); | ||
612 | rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); | ||
613 | rt2800_bbp_write(rt2x00dev, 86, 0); | ||
614 | |||
615 | if (rf->channel <= 14) { | ||
616 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { | ||
617 | rt2800_bbp_write(rt2x00dev, 82, 0x62); | ||
618 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | ||
619 | } else { | ||
620 | rt2800_bbp_write(rt2x00dev, 82, 0x84); | ||
621 | rt2800_bbp_write(rt2x00dev, 75, 0x50); | ||
622 | } | ||
623 | } else { | ||
624 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); | ||
625 | |||
626 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | ||
627 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | ||
628 | else | ||
629 | rt2800_bbp_write(rt2x00dev, 75, 0x50); | ||
630 | } | ||
631 | |||
632 | rt2800_register_read(rt2x00dev, TX_BAND_CFG, ®); | ||
633 | rt2x00_set_field32(®, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf)); | ||
634 | rt2x00_set_field32(®, TX_BAND_CFG_A, rf->channel > 14); | ||
635 | rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14); | ||
636 | rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg); | ||
637 | |||
638 | tx_pin = 0; | ||
639 | |||
640 | /* Turn on unused PA or LNA when not using 1T or 1R */ | ||
641 | if (rt2x00dev->default_ant.tx != 1) { | ||
642 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); | ||
643 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); | ||
644 | } | ||
645 | |||
646 | /* Turn on unused PA or LNA when not using 1T or 1R */ | ||
647 | if (rt2x00dev->default_ant.rx != 1) { | ||
648 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); | ||
649 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); | ||
650 | } | ||
651 | |||
652 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1); | ||
653 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1); | ||
654 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); | ||
655 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); | ||
656 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14); | ||
657 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14); | ||
658 | |||
659 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); | ||
660 | |||
661 | rt2800_bbp_read(rt2x00dev, 4, &bbp); | ||
662 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); | ||
663 | rt2800_bbp_write(rt2x00dev, 4, bbp); | ||
664 | |||
665 | rt2800_bbp_read(rt2x00dev, 3, &bbp); | ||
666 | rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf)); | ||
667 | rt2800_bbp_write(rt2x00dev, 3, bbp); | ||
668 | |||
669 | if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) { | ||
670 | if (conf_is_ht40(conf)) { | ||
671 | rt2800_bbp_write(rt2x00dev, 69, 0x1a); | ||
672 | rt2800_bbp_write(rt2x00dev, 70, 0x0a); | ||
673 | rt2800_bbp_write(rt2x00dev, 73, 0x16); | ||
674 | } else { | ||
675 | rt2800_bbp_write(rt2x00dev, 69, 0x16); | ||
676 | rt2800_bbp_write(rt2x00dev, 70, 0x08); | ||
677 | rt2800_bbp_write(rt2x00dev, 73, 0x11); | ||
678 | } | ||
679 | } | ||
680 | |||
681 | msleep(1); | ||
682 | } | ||
683 | |||
684 | static void rt2800usb_config_txpower(struct rt2x00_dev *rt2x00dev, | ||
685 | const int txpower) | ||
686 | { | ||
687 | u32 reg; | ||
688 | u32 value = TXPOWER_G_TO_DEV(txpower); | ||
689 | u8 r1; | ||
690 | |||
691 | rt2800_bbp_read(rt2x00dev, 1, &r1); | ||
692 | rt2x00_set_field8(®, BBP1_TX_POWER, 0); | ||
693 | rt2800_bbp_write(rt2x00dev, 1, r1); | ||
694 | |||
695 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®); | ||
696 | rt2x00_set_field32(®, TX_PWR_CFG_0_1MBS, value); | ||
697 | rt2x00_set_field32(®, TX_PWR_CFG_0_2MBS, value); | ||
698 | rt2x00_set_field32(®, TX_PWR_CFG_0_55MBS, value); | ||
699 | rt2x00_set_field32(®, TX_PWR_CFG_0_11MBS, value); | ||
700 | rt2x00_set_field32(®, TX_PWR_CFG_0_6MBS, value); | ||
701 | rt2x00_set_field32(®, TX_PWR_CFG_0_9MBS, value); | ||
702 | rt2x00_set_field32(®, TX_PWR_CFG_0_12MBS, value); | ||
703 | rt2x00_set_field32(®, TX_PWR_CFG_0_18MBS, value); | ||
704 | rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, reg); | ||
705 | |||
706 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, ®); | ||
707 | rt2x00_set_field32(®, TX_PWR_CFG_1_24MBS, value); | ||
708 | rt2x00_set_field32(®, TX_PWR_CFG_1_36MBS, value); | ||
709 | rt2x00_set_field32(®, TX_PWR_CFG_1_48MBS, value); | ||
710 | rt2x00_set_field32(®, TX_PWR_CFG_1_54MBS, value); | ||
711 | rt2x00_set_field32(®, TX_PWR_CFG_1_MCS0, value); | ||
712 | rt2x00_set_field32(®, TX_PWR_CFG_1_MCS1, value); | ||
713 | rt2x00_set_field32(®, TX_PWR_CFG_1_MCS2, value); | ||
714 | rt2x00_set_field32(®, TX_PWR_CFG_1_MCS3, value); | ||
715 | rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, reg); | ||
716 | |||
717 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, ®); | ||
718 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS4, value); | ||
719 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS5, value); | ||
720 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS6, value); | ||
721 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS7, value); | ||
722 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS8, value); | ||
723 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS9, value); | ||
724 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS10, value); | ||
725 | rt2x00_set_field32(®, TX_PWR_CFG_2_MCS11, value); | ||
726 | rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, reg); | ||
727 | |||
728 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, ®); | ||
729 | rt2x00_set_field32(®, TX_PWR_CFG_3_MCS12, value); | ||
730 | rt2x00_set_field32(®, TX_PWR_CFG_3_MCS13, value); | ||
731 | rt2x00_set_field32(®, TX_PWR_CFG_3_MCS14, value); | ||
732 | rt2x00_set_field32(®, TX_PWR_CFG_3_MCS15, value); | ||
733 | rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN1, value); | ||
734 | rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN2, value); | ||
735 | rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN3, value); | ||
736 | rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN4, value); | ||
737 | rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, reg); | ||
738 | |||
739 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, ®); | ||
740 | rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN5, value); | ||
741 | rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN6, value); | ||
742 | rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN7, value); | ||
743 | rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN8, value); | ||
744 | rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, reg); | ||
745 | } | ||
746 | |||
747 | static void rt2800usb_config_retry_limit(struct rt2x00_dev *rt2x00dev, | ||
748 | struct rt2x00lib_conf *libconf) | ||
749 | { | ||
750 | u32 reg; | ||
751 | |||
752 | rt2800_register_read(rt2x00dev, TX_RTY_CFG, ®); | ||
753 | rt2x00_set_field32(®, TX_RTY_CFG_SHORT_RTY_LIMIT, | ||
754 | libconf->conf->short_frame_max_tx_count); | ||
755 | rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_LIMIT, | ||
756 | libconf->conf->long_frame_max_tx_count); | ||
757 | rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_THRE, 2000); | ||
758 | rt2x00_set_field32(®, TX_RTY_CFG_NON_AGG_RTY_MODE, 0); | ||
759 | rt2x00_set_field32(®, TX_RTY_CFG_AGG_RTY_MODE, 0); | ||
760 | rt2x00_set_field32(®, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1); | ||
761 | rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg); | ||
762 | } | ||
763 | |||
764 | static void rt2800usb_config_ps(struct rt2x00_dev *rt2x00dev, | ||
765 | struct rt2x00lib_conf *libconf) | ||
766 | { | ||
767 | enum dev_state state = | ||
768 | (libconf->conf->flags & IEEE80211_CONF_PS) ? | ||
769 | STATE_SLEEP : STATE_AWAKE; | ||
770 | u32 reg; | ||
771 | |||
772 | if (state == STATE_SLEEP) { | ||
773 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0); | ||
774 | |||
775 | rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, ®); | ||
776 | rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 5); | ||
777 | rt2x00_set_field32(®, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, | ||
778 | libconf->conf->listen_interval - 1); | ||
779 | rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTOWAKE, 1); | ||
780 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg); | ||
781 | |||
782 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | ||
783 | } else { | ||
784 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | ||
785 | |||
786 | rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, ®); | ||
787 | rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0); | ||
788 | rt2x00_set_field32(®, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0); | ||
789 | rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTOWAKE, 0); | ||
790 | rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg); | ||
791 | } | ||
792 | } | ||
793 | |||
794 | static void rt2800usb_config(struct rt2x00_dev *rt2x00dev, | ||
795 | struct rt2x00lib_conf *libconf, | ||
796 | const unsigned int flags) | ||
797 | { | ||
798 | /* Always recalculate LNA gain before changing configuration */ | ||
799 | rt2800usb_config_lna_gain(rt2x00dev, libconf); | ||
800 | |||
801 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) | ||
802 | rt2800usb_config_channel(rt2x00dev, libconf->conf, | ||
803 | &libconf->rf, &libconf->channel); | ||
804 | if (flags & IEEE80211_CONF_CHANGE_POWER) | ||
805 | rt2800usb_config_txpower(rt2x00dev, libconf->conf->power_level); | ||
806 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) | ||
807 | rt2800usb_config_retry_limit(rt2x00dev, libconf); | ||
808 | if (flags & IEEE80211_CONF_CHANGE_PS) | ||
809 | rt2800usb_config_ps(rt2x00dev, libconf); | ||
810 | } | ||
811 | |||
812 | /* | ||
813 | * Link tuning | ||
814 | */ | ||
815 | static void rt2800usb_link_stats(struct rt2x00_dev *rt2x00dev, | ||
816 | struct link_qual *qual) | ||
817 | { | ||
818 | u32 reg; | ||
819 | |||
820 | /* | ||
821 | * Update FCS error count from register. | ||
822 | */ | ||
823 | rt2800_register_read(rt2x00dev, RX_STA_CNT0, ®); | ||
824 | qual->rx_failed = rt2x00_get_field32(reg, RX_STA_CNT0_CRC_ERR); | ||
825 | } | ||
826 | |||
827 | static u8 rt2800usb_get_default_vgc(struct rt2x00_dev *rt2x00dev) | ||
828 | { | ||
829 | if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { | ||
830 | if (rt2x00_intf_is_usb(rt2x00dev) && | ||
831 | rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) | ||
832 | return 0x1c + (2 * rt2x00dev->lna_gain); | ||
833 | else | ||
834 | return 0x2e + rt2x00dev->lna_gain; | ||
835 | } | ||
836 | |||
837 | if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) | ||
838 | return 0x32 + (rt2x00dev->lna_gain * 5) / 3; | ||
839 | else | ||
840 | return 0x3a + (rt2x00dev->lna_gain * 5) / 3; | ||
841 | } | ||
842 | |||
843 | static inline void rt2800usb_set_vgc(struct rt2x00_dev *rt2x00dev, | ||
844 | struct link_qual *qual, u8 vgc_level) | ||
845 | { | ||
846 | if (qual->vgc_level != vgc_level) { | ||
847 | rt2800_bbp_write(rt2x00dev, 66, vgc_level); | ||
848 | qual->vgc_level = vgc_level; | ||
849 | qual->vgc_level_reg = vgc_level; | ||
850 | } | ||
851 | } | ||
852 | |||
853 | static void rt2800usb_reset_tuner(struct rt2x00_dev *rt2x00dev, | ||
854 | struct link_qual *qual) | ||
855 | { | ||
856 | rt2800usb_set_vgc(rt2x00dev, qual, | ||
857 | rt2800usb_get_default_vgc(rt2x00dev)); | ||
858 | } | ||
859 | |||
860 | static void rt2800usb_link_tuner(struct rt2x00_dev *rt2x00dev, | ||
861 | struct link_qual *qual, const u32 count) | ||
862 | { | ||
863 | if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) | ||
864 | return; | ||
865 | |||
866 | /* | ||
867 | * When RSSI is better then -80 increase VGC level with 0x10 | ||
868 | */ | ||
869 | rt2800usb_set_vgc(rt2x00dev, qual, | ||
870 | rt2800usb_get_default_vgc(rt2x00dev) + | ||
871 | ((qual->rssi > -80) * 0x10)); | ||
872 | } | ||
873 | |||
874 | /* | 48 | /* |
875 | * Firmware functions | 49 | * Firmware functions |
876 | */ | 50 | */ |
@@ -2205,9 +1379,9 @@ static int rt2800usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2205 | * Store led settings, for correct led behaviour. | 1379 | * Store led settings, for correct led behaviour. |
2206 | */ | 1380 | */ |
2207 | #ifdef CONFIG_RT2X00_LIB_LEDS | 1381 | #ifdef CONFIG_RT2X00_LIB_LEDS |
2208 | rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); | 1382 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
2209 | rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); | 1383 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); |
2210 | rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); | 1384 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); |
2211 | 1385 | ||
2212 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, | 1386 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, |
2213 | &rt2x00dev->led_mcu_reg); | 1387 | &rt2x00dev->led_mcu_reg); |
@@ -2645,10 +1819,10 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
2645 | .uninitialize = rt2x00usb_uninitialize, | 1819 | .uninitialize = rt2x00usb_uninitialize, |
2646 | .clear_entry = rt2x00usb_clear_entry, | 1820 | .clear_entry = rt2x00usb_clear_entry, |
2647 | .set_device_state = rt2800usb_set_device_state, | 1821 | .set_device_state = rt2800usb_set_device_state, |
2648 | .rfkill_poll = rt2800usb_rfkill_poll, | 1822 | .rfkill_poll = rt2800_rfkill_poll, |
2649 | .link_stats = rt2800usb_link_stats, | 1823 | .link_stats = rt2800_link_stats, |
2650 | .reset_tuner = rt2800usb_reset_tuner, | 1824 | .reset_tuner = rt2800_reset_tuner, |
2651 | .link_tuner = rt2800usb_link_tuner, | 1825 | .link_tuner = rt2800_link_tuner, |
2652 | .write_tx_desc = rt2800usb_write_tx_desc, | 1826 | .write_tx_desc = rt2800usb_write_tx_desc, |
2653 | .write_tx_data = rt2x00usb_write_tx_data, | 1827 | .write_tx_data = rt2x00usb_write_tx_data, |
2654 | .write_beacon = rt2800usb_write_beacon, | 1828 | .write_beacon = rt2800usb_write_beacon, |
@@ -2656,13 +1830,13 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
2656 | .kick_tx_queue = rt2800usb_kick_tx_queue, | 1830 | .kick_tx_queue = rt2800usb_kick_tx_queue, |
2657 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 1831 | .kill_tx_queue = rt2x00usb_kill_tx_queue, |
2658 | .fill_rxdone = rt2800usb_fill_rxdone, | 1832 | .fill_rxdone = rt2800usb_fill_rxdone, |
2659 | .config_shared_key = rt2800usb_config_shared_key, | 1833 | .config_shared_key = rt2800_config_shared_key, |
2660 | .config_pairwise_key = rt2800usb_config_pairwise_key, | 1834 | .config_pairwise_key = rt2800_config_pairwise_key, |
2661 | .config_filter = rt2800usb_config_filter, | 1835 | .config_filter = rt2800_config_filter, |
2662 | .config_intf = rt2800usb_config_intf, | 1836 | .config_intf = rt2800_config_intf, |
2663 | .config_erp = rt2800usb_config_erp, | 1837 | .config_erp = rt2800_config_erp, |
2664 | .config_ant = rt2800usb_config_ant, | 1838 | .config_ant = rt2800_config_ant, |
2665 | .config = rt2800usb_config, | 1839 | .config = rt2800_config, |
2666 | }; | 1840 | }; |
2667 | 1841 | ||
2668 | static const struct data_queue_desc rt2800usb_queue_rx = { | 1842 | static const struct data_queue_desc rt2800usb_queue_rx = { |
@@ -2699,7 +1873,7 @@ static const struct rt2x00_ops rt2800usb_ops = { | |||
2699 | .lib = &rt2800usb_rt2x00_ops, | 1873 | .lib = &rt2800usb_rt2x00_ops, |
2700 | .hw = &rt2800usb_mac80211_ops, | 1874 | .hw = &rt2800usb_mac80211_ops, |
2701 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1875 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
2702 | .debugfs = &rt2800usb_rt2x00debug, | 1876 | .debugfs = &rt2800_rt2x00debug, |
2703 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 1877 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
2704 | }; | 1878 | }; |
2705 | 1879 | ||