diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 699 |
1 files changed, 365 insertions, 334 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 3909cf42f472..a9efe25f1ea7 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -24,6 +24,7 @@ | |||
24 | Supported chipsets: rt2571W & rt2671. | 24 | Supported chipsets: rt2571W & rt2671. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/crc-itu-t.h> | ||
27 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
28 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
29 | #include <linux/init.h> | 30 | #include <linux/init.h> |
@@ -278,85 +279,158 @@ static const struct rt2x00debug rt73usb_rt2x00debug = { | |||
278 | }; | 279 | }; |
279 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 280 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
280 | 281 | ||
281 | /* | 282 | #ifdef CONFIG_RT73USB_LEDS |
282 | * Configuration handlers. | 283 | static void rt73usb_brightness_set(struct led_classdev *led_cdev, |
283 | */ | 284 | enum led_brightness brightness) |
284 | static void rt73usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | ||
285 | { | 285 | { |
286 | u32 tmp; | 286 | struct rt2x00_led *led = |
287 | 287 | container_of(led_cdev, struct rt2x00_led, led_dev); | |
288 | tmp = le32_to_cpu(mac[1]); | 288 | unsigned int enabled = brightness != LED_OFF; |
289 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | 289 | unsigned int a_mode = |
290 | mac[1] = cpu_to_le32(tmp); | 290 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); |
291 | 291 | unsigned int bg_mode = | |
292 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 292 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); |
293 | (2 * sizeof(__le32))); | 293 | |
294 | if (led->type == LED_TYPE_RADIO) { | ||
295 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
296 | MCU_LEDCS_RADIO_STATUS, enabled); | ||
297 | |||
298 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
299 | 0, led->rt2x00dev->led_mcu_reg, | ||
300 | REGISTER_TIMEOUT); | ||
301 | } else if (led->type == LED_TYPE_ASSOC) { | ||
302 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
303 | MCU_LEDCS_LINK_BG_STATUS, bg_mode); | ||
304 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
305 | MCU_LEDCS_LINK_A_STATUS, a_mode); | ||
306 | |||
307 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
308 | 0, led->rt2x00dev->led_mcu_reg, | ||
309 | REGISTER_TIMEOUT); | ||
310 | } else if (led->type == LED_TYPE_QUALITY) { | ||
311 | /* | ||
312 | * The brightness is divided into 6 levels (0 - 5), | ||
313 | * this means we need to convert the brightness | ||
314 | * argument into the matching level within that range. | ||
315 | */ | ||
316 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
317 | brightness / (LED_FULL / 6), | ||
318 | led->rt2x00dev->led_mcu_reg, | ||
319 | REGISTER_TIMEOUT); | ||
320 | } | ||
294 | } | 321 | } |
295 | 322 | ||
296 | static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 323 | static int rt73usb_blink_set(struct led_classdev *led_cdev, |
324 | unsigned long *delay_on, | ||
325 | unsigned long *delay_off) | ||
297 | { | 326 | { |
298 | u32 tmp; | 327 | struct rt2x00_led *led = |
328 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
329 | u32 reg; | ||
299 | 330 | ||
300 | tmp = le32_to_cpu(bssid[1]); | 331 | rt73usb_register_read(led->rt2x00dev, MAC_CSR14, ®); |
301 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 332 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, *delay_on); |
302 | bssid[1] = cpu_to_le32(tmp); | 333 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, *delay_off); |
334 | rt73usb_register_write(led->rt2x00dev, MAC_CSR14, reg); | ||
303 | 335 | ||
304 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 336 | return 0; |
305 | (2 * sizeof(__le32))); | ||
306 | } | 337 | } |
338 | #endif /* CONFIG_RT73USB_LEDS */ | ||
307 | 339 | ||
308 | static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 340 | /* |
309 | const int tsf_sync) | 341 | * Configuration handlers. |
342 | */ | ||
343 | static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev, | ||
344 | const unsigned int filter_flags) | ||
310 | { | 345 | { |
311 | u32 reg; | 346 | u32 reg; |
312 | 347 | ||
313 | /* | 348 | /* |
314 | * Clear current synchronisation setup. | 349 | * Start configuration steps. |
315 | * For the Beacon base registers we only need to clear | 350 | * Note that the version error will always be dropped |
316 | * the first byte since that byte contains the VALID and OWNER | 351 | * and broadcast frames will always be accepted since |
317 | * bits which (when set to 0) will invalidate the entire beacon. | 352 | * there is no filter for it at this time. |
318 | */ | ||
319 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
320 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
321 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
322 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
323 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
324 | |||
325 | /* | ||
326 | * Enable synchronisation. | ||
327 | */ | 353 | */ |
328 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 354 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
329 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | 355 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, |
330 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | 356 | !(filter_flags & FIF_FCSFAIL)); |
331 | (tsf_sync == TSF_SYNC_BEACON)); | 357 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, |
332 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 358 | !(filter_flags & FIF_PLCPFAIL)); |
333 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | 359 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, |
334 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 360 | !(filter_flags & FIF_CONTROL)); |
361 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | ||
362 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
363 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | ||
364 | !(filter_flags & FIF_PROMISC_IN_BSS) && | ||
365 | !rt2x00dev->intf_ap_count); | ||
366 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
367 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | ||
368 | !(filter_flags & FIF_ALLMULTI)); | ||
369 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | ||
370 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, | ||
371 | !(filter_flags & FIF_CONTROL)); | ||
372 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
335 | } | 373 | } |
336 | 374 | ||
337 | static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 375 | static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 376 | struct rt2x00_intf *intf, |
339 | const int ack_timeout, | 377 | struct rt2x00intf_conf *conf, |
340 | const int ack_consume_time) | 378 | const unsigned int flags) |
341 | { | 379 | { |
380 | unsigned int beacon_base; | ||
342 | u32 reg; | 381 | u32 reg; |
343 | 382 | ||
344 | /* | 383 | if (flags & CONFIG_UPDATE_TYPE) { |
345 | * When in atomic context, reschedule and let rt2x00lib | 384 | /* |
346 | * call this function again. | 385 | * Clear current synchronisation setup. |
347 | */ | 386 | * For the Beacon base registers we only need to clear |
348 | if (in_atomic()) { | 387 | * the first byte since that byte contains the VALID and OWNER |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 388 | * bits which (when set to 0) will invalidate the entire beacon. |
350 | return; | 389 | */ |
390 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
391 | rt73usb_register_write(rt2x00dev, beacon_base, 0); | ||
392 | |||
393 | /* | ||
394 | * Enable synchronisation. | ||
395 | */ | ||
396 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
397 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
398 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
399 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
400 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
351 | } | 401 | } |
352 | 402 | ||
403 | if (flags & CONFIG_UPDATE_MAC) { | ||
404 | reg = le32_to_cpu(conf->mac[1]); | ||
405 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
406 | conf->mac[1] = cpu_to_le32(reg); | ||
407 | |||
408 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, | ||
409 | conf->mac, sizeof(conf->mac)); | ||
410 | } | ||
411 | |||
412 | if (flags & CONFIG_UPDATE_BSSID) { | ||
413 | reg = le32_to_cpu(conf->bssid[1]); | ||
414 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); | ||
415 | conf->bssid[1] = cpu_to_le32(reg); | ||
416 | |||
417 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, | ||
418 | conf->bssid, sizeof(conf->bssid)); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, | ||
423 | struct rt2x00lib_erp *erp) | ||
424 | { | ||
425 | u32 reg; | ||
426 | |||
353 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 427 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
354 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); | 428 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); |
355 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 429 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
356 | 430 | ||
357 | rt73usb_register_read(rt2x00dev, TXRX_CSR4, ®); | 431 | rt73usb_register_read(rt2x00dev, TXRX_CSR4, ®); |
358 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 432 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 433 | !!erp->short_preamble); |
360 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | 434 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); |
361 | } | 435 | } |
362 | 436 | ||
@@ -442,28 +516,22 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
442 | case ANTENNA_HW_DIVERSITY: | 516 | case ANTENNA_HW_DIVERSITY: |
443 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 517 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
444 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) | 518 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) |
445 | && (rt2x00dev->curr_hwmode != HWMODE_A); | 519 | && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); |
446 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); | 520 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); |
447 | break; | 521 | break; |
448 | case ANTENNA_A: | 522 | case ANTENNA_A: |
449 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 523 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
450 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 524 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
451 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 525 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
452 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 526 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
453 | else | 527 | else |
454 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 528 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
455 | break; | 529 | break; |
456 | case ANTENNA_SW_DIVERSITY: | ||
457 | /* | ||
458 | * NOTE: We should never come here because rt2x00lib is | ||
459 | * supposed to catch this and send us the correct antenna | ||
460 | * explicitely. However we are nog going to bug about this. | ||
461 | * Instead, just default to antenna B. | ||
462 | */ | ||
463 | case ANTENNA_B: | 530 | case ANTENNA_B: |
531 | default: | ||
464 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 532 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
465 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 533 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
466 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 534 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
467 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 535 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
468 | else | 536 | else |
469 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 537 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
@@ -501,14 +569,8 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | |||
501 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 569 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
502 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 570 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
503 | break; | 571 | break; |
504 | case ANTENNA_SW_DIVERSITY: | ||
505 | /* | ||
506 | * NOTE: We should never come here because rt2x00lib is | ||
507 | * supposed to catch this and send us the correct antenna | ||
508 | * explicitely. However we are nog going to bug about this. | ||
509 | * Instead, just default to antenna B. | ||
510 | */ | ||
511 | case ANTENNA_B: | 572 | case ANTENNA_B: |
573 | default: | ||
512 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 574 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
513 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 575 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
514 | break; | 576 | break; |
@@ -558,7 +620,14 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
558 | unsigned int i; | 620 | unsigned int i; |
559 | u32 reg; | 621 | u32 reg; |
560 | 622 | ||
561 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 623 | /* |
624 | * We should never come here because rt2x00lib is supposed | ||
625 | * to catch this and send us the correct antenna explicitely. | ||
626 | */ | ||
627 | BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY || | ||
628 | ant->tx == ANTENNA_SW_DIVERSITY); | ||
629 | |||
630 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | ||
562 | sel = antenna_sel_a; | 631 | sel = antenna_sel_a; |
563 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 632 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
564 | } else { | 633 | } else { |
@@ -572,10 +641,9 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
572 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); | 641 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); |
573 | 642 | ||
574 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 643 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
575 | (rt2x00dev->curr_hwmode == HWMODE_B || | 644 | (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ)); |
576 | rt2x00dev->curr_hwmode == HWMODE_G)); | ||
577 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 645 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
578 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 646 | (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)); |
579 | 647 | ||
580 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); | 648 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); |
581 | 649 | ||
@@ -617,8 +685,8 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
617 | } | 685 | } |
618 | 686 | ||
619 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | 687 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, |
620 | const unsigned int flags, | 688 | struct rt2x00lib_conf *libconf, |
621 | struct rt2x00lib_conf *libconf) | 689 | const unsigned int flags) |
622 | { | 690 | { |
623 | if (flags & CONFIG_UPDATE_PHYMODE) | 691 | if (flags & CONFIG_UPDATE_PHYMODE) |
624 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); | 692 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -634,68 +702,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | |||
634 | } | 702 | } |
635 | 703 | ||
636 | /* | 704 | /* |
637 | * LED functions. | ||
638 | */ | ||
639 | static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev) | ||
640 | { | ||
641 | u32 reg; | ||
642 | |||
643 | rt73usb_register_read(rt2x00dev, MAC_CSR14, ®); | ||
644 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
645 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
646 | rt73usb_register_write(rt2x00dev, MAC_CSR14, reg); | ||
647 | |||
648 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
649 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, | ||
650 | (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); | ||
651 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, | ||
652 | (rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); | ||
653 | |||
654 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
655 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
656 | } | ||
657 | |||
658 | static void rt73usb_disable_led(struct rt2x00_dev *rt2x00dev) | ||
659 | { | ||
660 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
661 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
662 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
663 | |||
664 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
665 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
666 | } | ||
667 | |||
668 | static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
669 | { | ||
670 | u32 led; | ||
671 | |||
672 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
673 | return; | ||
674 | |||
675 | /* | ||
676 | * Led handling requires a positive value for the rssi, | ||
677 | * to do that correctly we need to add the correction. | ||
678 | */ | ||
679 | rssi += rt2x00dev->rssi_offset; | ||
680 | |||
681 | if (rssi <= 30) | ||
682 | led = 0; | ||
683 | else if (rssi <= 39) | ||
684 | led = 1; | ||
685 | else if (rssi <= 49) | ||
686 | led = 2; | ||
687 | else if (rssi <= 53) | ||
688 | led = 3; | ||
689 | else if (rssi <= 63) | ||
690 | led = 4; | ||
691 | else | ||
692 | led = 5; | ||
693 | |||
694 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, led, | ||
695 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * Link tuning | 705 | * Link tuning |
700 | */ | 706 | */ |
701 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, | 707 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -729,17 +735,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
729 | u8 up_bound; | 735 | u8 up_bound; |
730 | u8 low_bound; | 736 | u8 low_bound; |
731 | 737 | ||
732 | /* | ||
733 | * Update Led strength | ||
734 | */ | ||
735 | rt73usb_activity_led(rt2x00dev, rssi); | ||
736 | |||
737 | rt73usb_bbp_read(rt2x00dev, 17, &r17); | 738 | rt73usb_bbp_read(rt2x00dev, 17, &r17); |
738 | 739 | ||
739 | /* | 740 | /* |
740 | * Determine r17 bounds. | 741 | * Determine r17 bounds. |
741 | */ | 742 | */ |
742 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 743 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
743 | low_bound = 0x28; | 744 | low_bound = 0x28; |
744 | up_bound = 0x48; | 745 | up_bound = 0x48; |
745 | 746 | ||
@@ -766,6 +767,13 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
766 | } | 767 | } |
767 | 768 | ||
768 | /* | 769 | /* |
770 | * If we are not associated, we should go straight to the | ||
771 | * dynamic CCA tuning. | ||
772 | */ | ||
773 | if (!rt2x00dev->intf_associated) | ||
774 | goto dynamic_cca_tune; | ||
775 | |||
776 | /* | ||
769 | * Special big-R17 for very short distance | 777 | * Special big-R17 for very short distance |
770 | */ | 778 | */ |
771 | if (rssi > -35) { | 779 | if (rssi > -35) { |
@@ -815,6 +823,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
815 | return; | 823 | return; |
816 | } | 824 | } |
817 | 825 | ||
826 | dynamic_cca_tune: | ||
827 | |||
818 | /* | 828 | /* |
819 | * r17 does not yet exceed upper limit, continue and base | 829 | * r17 does not yet exceed upper limit, continue and base |
820 | * the r17 tuning on the false CCA count. | 830 | * the r17 tuning on the false CCA count. |
@@ -833,16 +843,30 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
833 | } | 843 | } |
834 | 844 | ||
835 | /* | 845 | /* |
836 | * Firmware name function. | 846 | * Firmware functions |
837 | */ | 847 | */ |
838 | static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 848 | static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) |
839 | { | 849 | { |
840 | return FIRMWARE_RT2571; | 850 | return FIRMWARE_RT2571; |
841 | } | 851 | } |
842 | 852 | ||
843 | /* | 853 | static u16 rt73usb_get_firmware_crc(void *data, const size_t len) |
844 | * Initialization functions. | 854 | { |
845 | */ | 855 | u16 crc; |
856 | |||
857 | /* | ||
858 | * Use the crc itu-t algorithm. | ||
859 | * The last 2 bytes in the firmware array are the crc checksum itself, | ||
860 | * this means that we should never pass those 2 bytes to the crc | ||
861 | * algorithm. | ||
862 | */ | ||
863 | crc = crc_itu_t(0, data, len - 2); | ||
864 | crc = crc_itu_t_byte(crc, 0); | ||
865 | crc = crc_itu_t_byte(crc, 0); | ||
866 | |||
867 | return crc; | ||
868 | } | ||
869 | |||
846 | static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | 870 | static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, |
847 | const size_t len) | 871 | const size_t len) |
848 | { | 872 | { |
@@ -889,7 +913,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
889 | 913 | ||
890 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 914 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
891 | USB_VENDOR_REQUEST_OUT, | 915 | USB_VENDOR_REQUEST_OUT, |
892 | FIRMWARE_IMAGE_BASE + i, 0x0000, | 916 | FIRMWARE_IMAGE_BASE + i, 0, |
893 | cache, buflen, timeout); | 917 | cache, buflen, timeout); |
894 | 918 | ||
895 | ptr += buflen; | 919 | ptr += buflen; |
@@ -902,18 +926,19 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
902 | * we need to specify a long timeout time. | 926 | * we need to specify a long timeout time. |
903 | */ | 927 | */ |
904 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, | 928 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, |
905 | 0x0000, USB_MODE_FIRMWARE, | 929 | 0, USB_MODE_FIRMWARE, |
906 | REGISTER_TIMEOUT_FIRMWARE); | 930 | REGISTER_TIMEOUT_FIRMWARE); |
907 | if (status < 0) { | 931 | if (status < 0) { |
908 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); | 932 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); |
909 | return status; | 933 | return status; |
910 | } | 934 | } |
911 | 935 | ||
912 | rt73usb_disable_led(rt2x00dev); | ||
913 | |||
914 | return 0; | 936 | return 0; |
915 | } | 937 | } |
916 | 938 | ||
939 | /* | ||
940 | * Initialization functions. | ||
941 | */ | ||
917 | static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | 942 | static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) |
918 | { | 943 | { |
919 | u32 reg; | 944 | u32 reg; |
@@ -1021,6 +1046,17 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1021 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); | 1046 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); |
1022 | 1047 | ||
1023 | /* | 1048 | /* |
1049 | * Clear all beacons | ||
1050 | * For the Beacon base registers we only need to clear | ||
1051 | * the first byte since that byte contains the VALID and OWNER | ||
1052 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1053 | */ | ||
1054 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1055 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1056 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1057 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1058 | |||
1059 | /* | ||
1024 | * We must clear the error counters. | 1060 | * We must clear the error counters. |
1025 | * These registers are cleared on read, | 1061 | * These registers are cleared on read, |
1026 | * so we may pass a useless variable to store the value. | 1062 | * so we may pass a useless variable to store the value. |
@@ -1094,19 +1130,15 @@ continue_csr_init: | |||
1094 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); | 1130 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); |
1095 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); | 1131 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); |
1096 | 1132 | ||
1097 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1098 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1133 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1099 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1134 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
1100 | 1135 | ||
1101 | if (eeprom != 0xffff && eeprom != 0x0000) { | 1136 | if (eeprom != 0xffff && eeprom != 0x0000) { |
1102 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 1137 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
1103 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 1138 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
1104 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
1105 | reg_id, value); | ||
1106 | rt73usb_bbp_write(rt2x00dev, reg_id, value); | 1139 | rt73usb_bbp_write(rt2x00dev, reg_id, value); |
1107 | } | 1140 | } |
1108 | } | 1141 | } |
1109 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1110 | 1142 | ||
1111 | return 0; | 1143 | return 0; |
1112 | } | 1144 | } |
@@ -1136,21 +1168,11 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1136 | return -EIO; | 1168 | return -EIO; |
1137 | } | 1169 | } |
1138 | 1170 | ||
1139 | /* | ||
1140 | * Enable LED | ||
1141 | */ | ||
1142 | rt73usb_enable_led(rt2x00dev); | ||
1143 | |||
1144 | return 0; | 1171 | return 0; |
1145 | } | 1172 | } |
1146 | 1173 | ||
1147 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 1174 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
1148 | { | 1175 | { |
1149 | /* | ||
1150 | * Disable LED | ||
1151 | */ | ||
1152 | rt73usb_disable_led(rt2x00dev); | ||
1153 | |||
1154 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1176 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1155 | 1177 | ||
1156 | /* | 1178 | /* |
@@ -1234,10 +1256,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1234 | */ | 1256 | */ |
1235 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1257 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1236 | struct sk_buff *skb, | 1258 | struct sk_buff *skb, |
1237 | struct txdata_entry_desc *desc, | 1259 | struct txentry_desc *txdesc, |
1238 | struct ieee80211_tx_control *control) | 1260 | struct ieee80211_tx_control *control) |
1239 | { | 1261 | { |
1240 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1262 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1241 | __le32 *txd = skbdesc->desc; | 1263 | __le32 *txd = skbdesc->desc; |
1242 | u32 word; | 1264 | u32 word; |
1243 | 1265 | ||
@@ -1245,47 +1267,47 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1245 | * Start writing the descriptor words. | 1267 | * Start writing the descriptor words. |
1246 | */ | 1268 | */ |
1247 | rt2x00_desc_read(txd, 1, &word); | 1269 | rt2x00_desc_read(txd, 1, &word); |
1248 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | 1270 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); |
1249 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | 1271 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1250 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1272 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1251 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1273 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1252 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1274 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1253 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1275 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1254 | rt2x00_desc_write(txd, 1, word); | 1276 | rt2x00_desc_write(txd, 1, word); |
1255 | 1277 | ||
1256 | rt2x00_desc_read(txd, 2, &word); | 1278 | rt2x00_desc_read(txd, 2, &word); |
1257 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1279 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1258 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1280 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1259 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1281 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1260 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1282 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1261 | rt2x00_desc_write(txd, 2, word); | 1283 | rt2x00_desc_write(txd, 2, word); |
1262 | 1284 | ||
1263 | rt2x00_desc_read(txd, 5, &word); | 1285 | rt2x00_desc_read(txd, 5, &word); |
1264 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1286 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1265 | TXPOWER_TO_DEV(control->power_level)); | 1287 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1266 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1288 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1267 | rt2x00_desc_write(txd, 5, word); | 1289 | rt2x00_desc_write(txd, 5, word); |
1268 | 1290 | ||
1269 | rt2x00_desc_read(txd, 0, &word); | 1291 | rt2x00_desc_read(txd, 0, &word); |
1270 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1292 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1271 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1293 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1272 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1294 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1273 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1295 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1274 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1296 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1275 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1297 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1276 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1298 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1277 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1299 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1278 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1300 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1279 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1301 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1280 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1302 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1281 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1303 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1282 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1304 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1283 | !!(control->flags & | 1305 | !!(control->flags & |
1284 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1306 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
1285 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1307 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1286 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1308 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1287 | rt2x00_set_field32(&word, TXD_W0_BURST2, | 1309 | rt2x00_set_field32(&word, TXD_W0_BURST2, |
1288 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1310 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1289 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1311 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1290 | rt2x00_desc_write(txd, 0, word); | 1312 | rt2x00_desc_write(txd, 0, word); |
1291 | } | 1313 | } |
@@ -1309,11 +1331,11 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1309 | * TX data initialization | 1331 | * TX data initialization |
1310 | */ | 1332 | */ |
1311 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1333 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1312 | unsigned int queue) | 1334 | const unsigned int queue) |
1313 | { | 1335 | { |
1314 | u32 reg; | 1336 | u32 reg; |
1315 | 1337 | ||
1316 | if (queue != IEEE80211_TX_QUEUE_BEACON) | 1338 | if (queue != RT2X00_BCN_QUEUE_BEACON) |
1317 | return; | 1339 | return; |
1318 | 1340 | ||
1319 | /* | 1341 | /* |
@@ -1324,6 +1346,8 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1324 | 1346 | ||
1325 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 1347 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
1326 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | 1348 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { |
1349 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1350 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1327 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1351 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); |
1328 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 1352 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
1329 | } | 1353 | } |
@@ -1353,7 +1377,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1353 | return 0; | 1377 | return 0; |
1354 | } | 1378 | } |
1355 | 1379 | ||
1356 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 1380 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1357 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 1381 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
1358 | if (lna == 3 || lna == 2) | 1382 | if (lna == 3 || lna == 2) |
1359 | offset += 10; | 1383 | offset += 10; |
@@ -1377,37 +1401,62 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1377 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | 1401 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
1378 | } | 1402 | } |
1379 | 1403 | ||
1380 | static void rt73usb_fill_rxdone(struct data_entry *entry, | 1404 | static void rt73usb_fill_rxdone(struct queue_entry *entry, |
1381 | struct rxdata_entry_desc *desc) | 1405 | struct rxdone_entry_desc *rxdesc) |
1382 | { | 1406 | { |
1383 | struct skb_desc *skbdesc = get_skb_desc(entry->skb); | 1407 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1384 | __le32 *rxd = (__le32 *)entry->skb->data; | 1408 | __le32 *rxd = (__le32 *)entry->skb->data; |
1409 | unsigned int offset = entry->queue->desc_size + 2; | ||
1385 | u32 word0; | 1410 | u32 word0; |
1386 | u32 word1; | 1411 | u32 word1; |
1387 | 1412 | ||
1413 | /* | ||
1414 | * Copy descriptor to the available headroom inside the skbuffer. | ||
1415 | */ | ||
1416 | skb_push(entry->skb, offset); | ||
1417 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | ||
1418 | rxd = (__le32 *)entry->skb->data; | ||
1419 | |||
1420 | /* | ||
1421 | * The descriptor is now aligned to 4 bytes and thus it is | ||
1422 | * now safe to read it on all architectures. | ||
1423 | */ | ||
1388 | rt2x00_desc_read(rxd, 0, &word0); | 1424 | rt2x00_desc_read(rxd, 0, &word0); |
1389 | rt2x00_desc_read(rxd, 1, &word1); | 1425 | rt2x00_desc_read(rxd, 1, &word1); |
1390 | 1426 | ||
1391 | desc->flags = 0; | 1427 | rxdesc->flags = 0; |
1392 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1428 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1393 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1429 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1394 | 1430 | ||
1395 | /* | 1431 | /* |
1396 | * Obtain the status about this packet. | 1432 | * Obtain the status about this packet. |
1433 | * When frame was received with an OFDM bitrate, | ||
1434 | * the signal is the PLCP value. If it was received with | ||
1435 | * a CCK bitrate the signal is the rate in 100kbit/s. | ||
1397 | */ | 1436 | */ |
1398 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1437 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1399 | desc->rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1); | 1438 | rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1400 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1439 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1401 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1440 | |
1402 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1441 | rxdesc->dev_flags = 0; |
1442 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | ||
1443 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | ||
1444 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | ||
1445 | rxdesc->dev_flags |= RXDONE_MY_BSS; | ||
1446 | |||
1447 | /* | ||
1448 | * Adjust the skb memory window to the frame boundaries. | ||
1449 | */ | ||
1450 | skb_pull(entry->skb, offset + entry->queue->desc_size); | ||
1451 | skb_trim(entry->skb, rxdesc->size); | ||
1403 | 1452 | ||
1404 | /* | 1453 | /* |
1405 | * Set descriptor and data pointer. | 1454 | * Set descriptor and data pointer. |
1406 | */ | 1455 | */ |
1407 | skbdesc->desc = entry->skb->data; | 1456 | skbdesc->data = entry->skb->data; |
1408 | skbdesc->desc_len = entry->ring->desc_size; | 1457 | skbdesc->data_len = rxdesc->size; |
1409 | skbdesc->data = entry->skb->data + entry->ring->desc_size; | 1458 | skbdesc->desc = rxd; |
1410 | skbdesc->data_len = desc->size; | 1459 | skbdesc->desc_len = entry->queue->desc_size; |
1411 | } | 1460 | } |
1412 | 1461 | ||
1413 | /* | 1462 | /* |
@@ -1499,7 +1548,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1499 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1548 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
1500 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1549 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
1501 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1550 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
1502 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1551 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
1503 | } else { | 1552 | } else { |
1504 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1553 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
1505 | if (value < -10 || value > 10) | 1554 | if (value < -10 || value > 10) |
@@ -1577,33 +1626,60 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1577 | /* | 1626 | /* |
1578 | * Store led settings, for correct led behaviour. | 1627 | * Store led settings, for correct led behaviour. |
1579 | */ | 1628 | */ |
1629 | #ifdef CONFIG_RT73USB_LEDS | ||
1580 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 1630 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
1581 | 1631 | ||
1582 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | 1632 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; |
1583 | rt2x00dev->led_mode); | 1633 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; |
1584 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | 1634 | rt2x00dev->led_radio.led_dev.brightness_set = |
1635 | rt73usb_brightness_set; | ||
1636 | rt2x00dev->led_radio.led_dev.blink_set = | ||
1637 | rt73usb_blink_set; | ||
1638 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1639 | |||
1640 | rt2x00dev->led_assoc.rt2x00dev = rt2x00dev; | ||
1641 | rt2x00dev->led_assoc.type = LED_TYPE_ASSOC; | ||
1642 | rt2x00dev->led_assoc.led_dev.brightness_set = | ||
1643 | rt73usb_brightness_set; | ||
1644 | rt2x00dev->led_assoc.led_dev.blink_set = | ||
1645 | rt73usb_blink_set; | ||
1646 | rt2x00dev->led_assoc.flags = LED_INITIALIZED; | ||
1647 | |||
1648 | if (value == LED_MODE_SIGNAL_STRENGTH) { | ||
1649 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1650 | rt2x00dev->led_radio.type = LED_TYPE_QUALITY; | ||
1651 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1652 | rt73usb_brightness_set; | ||
1653 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1654 | rt73usb_blink_set; | ||
1655 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1656 | } | ||
1657 | |||
1658 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); | ||
1659 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
1585 | rt2x00_get_field16(eeprom, | 1660 | rt2x00_get_field16(eeprom, |
1586 | EEPROM_LED_POLARITY_GPIO_0)); | 1661 | EEPROM_LED_POLARITY_GPIO_0)); |
1587 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | 1662 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, |
1588 | rt2x00_get_field16(eeprom, | 1663 | rt2x00_get_field16(eeprom, |
1589 | EEPROM_LED_POLARITY_GPIO_1)); | 1664 | EEPROM_LED_POLARITY_GPIO_1)); |
1590 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | 1665 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, |
1591 | rt2x00_get_field16(eeprom, | 1666 | rt2x00_get_field16(eeprom, |
1592 | EEPROM_LED_POLARITY_GPIO_2)); | 1667 | EEPROM_LED_POLARITY_GPIO_2)); |
1593 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | 1668 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, |
1594 | rt2x00_get_field16(eeprom, | 1669 | rt2x00_get_field16(eeprom, |
1595 | EEPROM_LED_POLARITY_GPIO_3)); | 1670 | EEPROM_LED_POLARITY_GPIO_3)); |
1596 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | 1671 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, |
1597 | rt2x00_get_field16(eeprom, | 1672 | rt2x00_get_field16(eeprom, |
1598 | EEPROM_LED_POLARITY_GPIO_4)); | 1673 | EEPROM_LED_POLARITY_GPIO_4)); |
1599 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | 1674 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, |
1600 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | 1675 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); |
1601 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | 1676 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, |
1602 | rt2x00_get_field16(eeprom, | 1677 | rt2x00_get_field16(eeprom, |
1603 | EEPROM_LED_POLARITY_RDY_G)); | 1678 | EEPROM_LED_POLARITY_RDY_G)); |
1604 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | 1679 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
1605 | rt2x00_get_field16(eeprom, | 1680 | rt2x00_get_field16(eeprom, |
1606 | EEPROM_LED_POLARITY_RDY_A)); | 1681 | EEPROM_LED_POLARITY_RDY_A)); |
1682 | #endif /* CONFIG_RT73USB_LEDS */ | ||
1607 | 1683 | ||
1608 | return 0; | 1684 | return 0; |
1609 | } | 1685 | } |
@@ -1759,7 +1835,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1759 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1835 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1760 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 1836 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
1761 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 1837 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
1762 | rt2x00dev->hw->queues = 5; | 1838 | rt2x00dev->hw->queues = 4; |
1763 | 1839 | ||
1764 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1840 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); |
1765 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1841 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -1776,8 +1852,8 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1776 | /* | 1852 | /* |
1777 | * Initialize hw_mode information. | 1853 | * Initialize hw_mode information. |
1778 | */ | 1854 | */ |
1779 | spec->num_modes = 2; | 1855 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1780 | spec->num_rates = 12; | 1856 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1781 | spec->tx_power_a = NULL; | 1857 | spec->tx_power_a = NULL; |
1782 | spec->tx_power_bg = txpower; | 1858 | spec->tx_power_bg = txpower; |
1783 | spec->tx_power_default = DEFAULT_TXPOWER; | 1859 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1786,20 +1862,20 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1786 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); | 1862 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); |
1787 | spec->channels = rf_vals_bg_2528; | 1863 | spec->channels = rf_vals_bg_2528; |
1788 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1864 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1865 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1789 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); | 1866 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); |
1790 | spec->channels = rf_vals_5226; | 1867 | spec->channels = rf_vals_5226; |
1791 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { | 1868 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { |
1792 | spec->num_channels = 14; | 1869 | spec->num_channels = 14; |
1793 | spec->channels = rf_vals_5225_2527; | 1870 | spec->channels = rf_vals_5225_2527; |
1794 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { | 1871 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { |
1872 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1795 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); | 1873 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); |
1796 | spec->channels = rf_vals_5225_2527; | 1874 | spec->channels = rf_vals_5225_2527; |
1797 | } | 1875 | } |
1798 | 1876 | ||
1799 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 1877 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
1800 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1878 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1801 | spec->num_modes = 3; | ||
1802 | |||
1803 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 1879 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
1804 | for (i = 0; i < 14; i++) | 1880 | for (i = 0; i < 14; i++) |
1805 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | 1881 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); |
@@ -1829,9 +1905,10 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1829 | rt73usb_probe_hw_mode(rt2x00dev); | 1905 | rt73usb_probe_hw_mode(rt2x00dev); |
1830 | 1906 | ||
1831 | /* | 1907 | /* |
1832 | * This device requires firmware | 1908 | * This device requires firmware. |
1833 | */ | 1909 | */ |
1834 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 1910 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
1911 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); | ||
1835 | 1912 | ||
1836 | /* | 1913 | /* |
1837 | * Set the rssi offset. | 1914 | * Set the rssi offset. |
@@ -1844,79 +1921,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1844 | /* | 1921 | /* |
1845 | * IEEE80211 stack callback functions. | 1922 | * IEEE80211 stack callback functions. |
1846 | */ | 1923 | */ |
1847 | static void rt73usb_configure_filter(struct ieee80211_hw *hw, | ||
1848 | unsigned int changed_flags, | ||
1849 | unsigned int *total_flags, | ||
1850 | int mc_count, | ||
1851 | struct dev_addr_list *mc_list) | ||
1852 | { | ||
1853 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1854 | u32 reg; | ||
1855 | |||
1856 | /* | ||
1857 | * Mask off any flags we are going to ignore from | ||
1858 | * the total_flags field. | ||
1859 | */ | ||
1860 | *total_flags &= | ||
1861 | FIF_ALLMULTI | | ||
1862 | FIF_FCSFAIL | | ||
1863 | FIF_PLCPFAIL | | ||
1864 | FIF_CONTROL | | ||
1865 | FIF_OTHER_BSS | | ||
1866 | FIF_PROMISC_IN_BSS; | ||
1867 | |||
1868 | /* | ||
1869 | * Apply some rules to the filters: | ||
1870 | * - Some filters imply different filters to be set. | ||
1871 | * - Some things we can't filter out at all. | ||
1872 | * - Multicast filter seems to kill broadcast traffic so never use it. | ||
1873 | */ | ||
1874 | *total_flags |= FIF_ALLMULTI; | ||
1875 | if (*total_flags & FIF_OTHER_BSS || | ||
1876 | *total_flags & FIF_PROMISC_IN_BSS) | ||
1877 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
1878 | |||
1879 | /* | ||
1880 | * Check if there is any work left for us. | ||
1881 | */ | ||
1882 | if (rt2x00dev->packet_filter == *total_flags) | ||
1883 | return; | ||
1884 | rt2x00dev->packet_filter = *total_flags; | ||
1885 | |||
1886 | /* | ||
1887 | * When in atomic context, reschedule and let rt2x00lib | ||
1888 | * call this function again. | ||
1889 | */ | ||
1890 | if (in_atomic()) { | ||
1891 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | ||
1892 | return; | ||
1893 | } | ||
1894 | |||
1895 | /* | ||
1896 | * Start configuration steps. | ||
1897 | * Note that the version error will always be dropped | ||
1898 | * and broadcast frames will always be accepted since | ||
1899 | * there is no filter for it at this time. | ||
1900 | */ | ||
1901 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
1902 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, | ||
1903 | !(*total_flags & FIF_FCSFAIL)); | ||
1904 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, | ||
1905 | !(*total_flags & FIF_PLCPFAIL)); | ||
1906 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, | ||
1907 | !(*total_flags & FIF_CONTROL)); | ||
1908 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | ||
1909 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1910 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | ||
1911 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1912 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
1913 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | ||
1914 | !(*total_flags & FIF_ALLMULTI)); | ||
1915 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | ||
1916 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | ||
1917 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
1918 | } | ||
1919 | |||
1920 | static int rt73usb_set_retry_limit(struct ieee80211_hw *hw, | 1924 | static int rt73usb_set_retry_limit(struct ieee80211_hw *hw, |
1921 | u32 short_retry, u32 long_retry) | 1925 | u32 short_retry, u32 long_retry) |
1922 | { | 1926 | { |
@@ -1955,61 +1959,65 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | |||
1955 | #define rt73usb_get_tsf NULL | 1959 | #define rt73usb_get_tsf NULL |
1956 | #endif | 1960 | #endif |
1957 | 1961 | ||
1958 | static void rt73usb_reset_tsf(struct ieee80211_hw *hw) | ||
1959 | { | ||
1960 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1961 | |||
1962 | rt73usb_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
1963 | rt73usb_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
1964 | } | ||
1965 | |||
1966 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 1962 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1967 | struct ieee80211_tx_control *control) | 1963 | struct ieee80211_tx_control *control) |
1968 | { | 1964 | { |
1969 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1965 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1970 | struct skb_desc *desc; | 1966 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1971 | struct data_ring *ring; | 1967 | struct skb_frame_desc *skbdesc; |
1972 | struct data_entry *entry; | 1968 | unsigned int beacon_base; |
1973 | int timeout; | 1969 | unsigned int timeout; |
1970 | u32 reg; | ||
1974 | 1971 | ||
1975 | /* | 1972 | if (unlikely(!intf->beacon)) |
1976 | * Just in case the ieee80211 doesn't set this, | 1973 | return -ENOBUFS; |
1977 | * but we need this queue set for the descriptor | ||
1978 | * initialization. | ||
1979 | */ | ||
1980 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
1981 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
1982 | entry = rt2x00_get_data_entry(ring); | ||
1983 | 1974 | ||
1984 | /* | 1975 | /* |
1985 | * Add the descriptor in front of the skb. | 1976 | * Add the descriptor in front of the skb. |
1986 | */ | 1977 | */ |
1987 | skb_push(skb, ring->desc_size); | 1978 | skb_push(skb, intf->beacon->queue->desc_size); |
1988 | memset(skb->data, 0, ring->desc_size); | 1979 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1989 | 1980 | ||
1990 | /* | 1981 | /* |
1991 | * Fill in skb descriptor | 1982 | * Fill in skb descriptor |
1992 | */ | 1983 | */ |
1993 | desc = get_skb_desc(skb); | 1984 | skbdesc = get_skb_frame_desc(skb); |
1994 | desc->desc_len = ring->desc_size; | 1985 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1995 | desc->data_len = skb->len - ring->desc_size; | 1986 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
1996 | desc->desc = skb->data; | 1987 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
1997 | desc->data = skb->data + ring->desc_size; | 1988 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
1998 | desc->ring = ring; | 1989 | skbdesc->desc = skb->data; |
1999 | desc->entry = entry; | 1990 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
1991 | skbdesc->entry = intf->beacon; | ||
2000 | 1992 | ||
1993 | /* | ||
1994 | * Disable beaconing while we are reloading the beacon data, | ||
1995 | * otherwise we might be sending out invalid data. | ||
1996 | */ | ||
1997 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1998 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1999 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2000 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2001 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2002 | |||
2003 | /* | ||
2004 | * mac80211 doesn't provide the control->queue variable | ||
2005 | * for beacons. Set our own queue identification so | ||
2006 | * it can be used during descriptor initialization. | ||
2007 | */ | ||
2008 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2001 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2009 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2002 | 2010 | ||
2003 | /* | 2011 | /* |
2004 | * Write entire beacon with descriptor to register, | 2012 | * Write entire beacon with descriptor to register, |
2005 | * and kick the beacon generator. | 2013 | * and kick the beacon generator. |
2006 | */ | 2014 | */ |
2015 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2007 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); | 2016 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); |
2008 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 2017 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
2009 | USB_VENDOR_REQUEST_OUT, | 2018 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, |
2010 | HW_BEACON_BASE0, 0x0000, | ||
2011 | skb->data, skb->len, timeout); | 2019 | skb->data, skb->len, timeout); |
2012 | rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2020 | rt73usb_kick_tx_queue(rt2x00dev, control->queue); |
2013 | 2021 | ||
2014 | return 0; | 2022 | return 0; |
2015 | } | 2023 | } |
@@ -2022,20 +2030,20 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2022 | .remove_interface = rt2x00mac_remove_interface, | 2030 | .remove_interface = rt2x00mac_remove_interface, |
2023 | .config = rt2x00mac_config, | 2031 | .config = rt2x00mac_config, |
2024 | .config_interface = rt2x00mac_config_interface, | 2032 | .config_interface = rt2x00mac_config_interface, |
2025 | .configure_filter = rt73usb_configure_filter, | 2033 | .configure_filter = rt2x00mac_configure_filter, |
2026 | .get_stats = rt2x00mac_get_stats, | 2034 | .get_stats = rt2x00mac_get_stats, |
2027 | .set_retry_limit = rt73usb_set_retry_limit, | 2035 | .set_retry_limit = rt73usb_set_retry_limit, |
2028 | .bss_info_changed = rt2x00mac_bss_info_changed, | 2036 | .bss_info_changed = rt2x00mac_bss_info_changed, |
2029 | .conf_tx = rt2x00mac_conf_tx, | 2037 | .conf_tx = rt2x00mac_conf_tx, |
2030 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2038 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2031 | .get_tsf = rt73usb_get_tsf, | 2039 | .get_tsf = rt73usb_get_tsf, |
2032 | .reset_tsf = rt73usb_reset_tsf, | ||
2033 | .beacon_update = rt73usb_beacon_update, | 2040 | .beacon_update = rt73usb_beacon_update, |
2034 | }; | 2041 | }; |
2035 | 2042 | ||
2036 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | 2043 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { |
2037 | .probe_hw = rt73usb_probe_hw, | 2044 | .probe_hw = rt73usb_probe_hw, |
2038 | .get_firmware_name = rt73usb_get_firmware_name, | 2045 | .get_firmware_name = rt73usb_get_firmware_name, |
2046 | .get_firmware_crc = rt73usb_get_firmware_crc, | ||
2039 | .load_firmware = rt73usb_load_firmware, | 2047 | .load_firmware = rt73usb_load_firmware, |
2040 | .initialize = rt2x00usb_initialize, | 2048 | .initialize = rt2x00usb_initialize, |
2041 | .uninitialize = rt2x00usb_uninitialize, | 2049 | .uninitialize = rt2x00usb_uninitialize, |
@@ -2050,19 +2058,42 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2050 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2058 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2051 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2059 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2052 | .fill_rxdone = rt73usb_fill_rxdone, | 2060 | .fill_rxdone = rt73usb_fill_rxdone, |
2053 | .config_mac_addr = rt73usb_config_mac_addr, | 2061 | .config_filter = rt73usb_config_filter, |
2054 | .config_bssid = rt73usb_config_bssid, | 2062 | .config_intf = rt73usb_config_intf, |
2055 | .config_type = rt73usb_config_type, | 2063 | .config_erp = rt73usb_config_erp, |
2056 | .config_preamble = rt73usb_config_preamble, | ||
2057 | .config = rt73usb_config, | 2064 | .config = rt73usb_config, |
2058 | }; | 2065 | }; |
2059 | 2066 | ||
2067 | static const struct data_queue_desc rt73usb_queue_rx = { | ||
2068 | .entry_num = RX_ENTRIES, | ||
2069 | .data_size = DATA_FRAME_SIZE, | ||
2070 | .desc_size = RXD_DESC_SIZE, | ||
2071 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | ||
2072 | }; | ||
2073 | |||
2074 | static const struct data_queue_desc rt73usb_queue_tx = { | ||
2075 | .entry_num = TX_ENTRIES, | ||
2076 | .data_size = DATA_FRAME_SIZE, | ||
2077 | .desc_size = TXD_DESC_SIZE, | ||
2078 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2079 | }; | ||
2080 | |||
2081 | static const struct data_queue_desc rt73usb_queue_bcn = { | ||
2082 | .entry_num = 4 * BEACON_ENTRIES, | ||
2083 | .data_size = MGMT_FRAME_SIZE, | ||
2084 | .desc_size = TXINFO_SIZE, | ||
2085 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2086 | }; | ||
2087 | |||
2060 | static const struct rt2x00_ops rt73usb_ops = { | 2088 | static const struct rt2x00_ops rt73usb_ops = { |
2061 | .name = KBUILD_MODNAME, | 2089 | .name = KBUILD_MODNAME, |
2062 | .rxd_size = RXD_DESC_SIZE, | 2090 | .max_sta_intf = 1, |
2063 | .txd_size = TXD_DESC_SIZE, | 2091 | .max_ap_intf = 4, |
2064 | .eeprom_size = EEPROM_SIZE, | 2092 | .eeprom_size = EEPROM_SIZE, |
2065 | .rf_size = RF_SIZE, | 2093 | .rf_size = RF_SIZE, |
2094 | .rx = &rt73usb_queue_rx, | ||
2095 | .tx = &rt73usb_queue_tx, | ||
2096 | .bcn = &rt73usb_queue_bcn, | ||
2066 | .lib = &rt73usb_rt2x00_ops, | 2097 | .lib = &rt73usb_rt2x00_ops, |
2067 | .hw = &rt73usb_mac80211_ops, | 2098 | .hw = &rt73usb_mac80211_ops, |
2068 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 2099 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |