diff options
author | Mattias Nissler <mattias.nissler@gmx.de> | 2007-10-27 07:41:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:03:00 -0500 |
commit | acaa410d06e057ed4d8d3926ec4f3cdcdf1ab37f (patch) | |
tree | 172b0f7f43d7f4f51d4446c8caff20f88713595b /drivers/net/wireless/rt2x00 | |
parent | 0e14f6d3e088473b411d35ff63737e46efb9e6df (diff) |
rt2x00: Rework rt61 antenna selection.
This patch changes rt61 antenna selection again. It helps at least with the
rt61 pci card in my box, I hope I haven't broken behaviour on other RF chips.
RF 2529 antenna setup is incomplete, we need to at code for diversity when we
figure out how it is done properly.
Signed-off-by: Mattias Nissler <mattias.nissler@gmx.de>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 143 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.h | 10 |
2 files changed, 46 insertions, 107 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 19ae8f49d9c8..5fd109a99cf2 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -422,40 +422,24 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
422 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | 422 | rt61pci_bbp_read(rt2x00dev, 77, &r77); |
423 | 423 | ||
424 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, | 424 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, |
425 | !rt2x00_rf(&rt2x00dev->chip, RF5225)); | 425 | rt2x00_rf(&rt2x00dev->chip, RF5325)); |
426 | |||
427 | /* | ||
428 | * Configure the TX antenna. | ||
429 | */ | ||
430 | switch (ant->tx) { | ||
431 | case ANTENNA_A: | ||
432 | rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0); | ||
433 | break; | ||
434 | case ANTENNA_SW_DIVERSITY: | ||
435 | case ANTENNA_HW_DIVERSITY: | ||
436 | /* | ||
437 | * NOTE: We should never come here because rt2x00lib is | ||
438 | * supposed to catch this and send us the correct antenna | ||
439 | * explicitely. However we are nog going to bug about this. | ||
440 | * Instead, just default to antenna B. | ||
441 | */ | ||
442 | case ANTENNA_B: | ||
443 | rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3); | ||
444 | break; | ||
445 | } | ||
446 | 426 | ||
447 | /* | 427 | /* |
448 | * Configure the RX antenna. | 428 | * Configure the RX antenna. |
449 | */ | 429 | */ |
450 | switch (ant->rx) { | 430 | switch (ant->rx) { |
451 | case ANTENNA_HW_DIVERSITY: | 431 | case ANTENNA_HW_DIVERSITY: |
452 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | 432 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
453 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | 433 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, |
454 | (rt2x00dev->curr_hwmode != HWMODE_A)); | 434 | (rt2x00dev->curr_hwmode != HWMODE_A)); |
455 | break; | 435 | break; |
456 | case ANTENNA_A: | 436 | case ANTENNA_A: |
457 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | 437 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
458 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 438 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
439 | if (rt2x00dev->curr_hwmode == HWMODE_A) | ||
440 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | ||
441 | else | ||
442 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | ||
459 | break; | 443 | break; |
460 | case ANTENNA_SW_DIVERSITY: | 444 | case ANTENNA_SW_DIVERSITY: |
461 | /* | 445 | /* |
@@ -465,8 +449,12 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
465 | * Instead, just default to antenna B. | 449 | * Instead, just default to antenna B. |
466 | */ | 450 | */ |
467 | case ANTENNA_B: | 451 | case ANTENNA_B: |
468 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | 452 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
469 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 453 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
454 | if (rt2x00dev->curr_hwmode == HWMODE_A) | ||
455 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | ||
456 | else | ||
457 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | ||
470 | break; | 458 | break; |
471 | } | 459 | } |
472 | 460 | ||
@@ -487,39 +475,20 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | |||
487 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | 475 | rt61pci_bbp_read(rt2x00dev, 77, &r77); |
488 | 476 | ||
489 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, | 477 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, |
490 | !rt2x00_rf(&rt2x00dev->chip, RF2527)); | 478 | rt2x00_rf(&rt2x00dev->chip, RF2529)); |
491 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | 479 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, |
492 | !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); | 480 | !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); |
493 | 481 | ||
494 | /* | 482 | /* |
495 | * Configure the TX antenna. | ||
496 | */ | ||
497 | switch (ant->tx) { | ||
498 | case ANTENNA_A: | ||
499 | rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0); | ||
500 | break; | ||
501 | case ANTENNA_SW_DIVERSITY: | ||
502 | case ANTENNA_HW_DIVERSITY: | ||
503 | /* | ||
504 | * NOTE: We should never come here because rt2x00lib is | ||
505 | * supposed to catch this and send us the correct antenna | ||
506 | * explicitely. However we are nog going to bug about this. | ||
507 | * Instead, just default to antenna B. | ||
508 | */ | ||
509 | case ANTENNA_B: | ||
510 | rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3); | ||
511 | break; | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * Configure the RX antenna. | 483 | * Configure the RX antenna. |
516 | */ | 484 | */ |
517 | switch (ant->rx) { | 485 | switch (ant->rx) { |
518 | case ANTENNA_HW_DIVERSITY: | 486 | case ANTENNA_HW_DIVERSITY: |
519 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | 487 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
520 | break; | 488 | break; |
521 | case ANTENNA_A: | 489 | case ANTENNA_A: |
522 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | 490 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
491 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | ||
523 | break; | 492 | break; |
524 | case ANTENNA_SW_DIVERSITY: | 493 | case ANTENNA_SW_DIVERSITY: |
525 | /* | 494 | /* |
@@ -529,7 +498,8 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | |||
529 | * Instead, just default to antenna B. | 498 | * Instead, just default to antenna B. |
530 | */ | 499 | */ |
531 | case ANTENNA_B: | 500 | case ANTENNA_B: |
532 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | 501 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
502 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | ||
533 | break; | 503 | break; |
534 | } | 504 | } |
535 | 505 | ||
@@ -545,16 +515,13 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev, | |||
545 | 515 | ||
546 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | 516 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); |
547 | 517 | ||
548 | if (p1 != 0xff) { | 518 | rt2x00_set_field32(®, MAC_CSR13_BIT4, p1); |
549 | rt2x00_set_field32(®, MAC_CSR13_BIT4, !!p1); | 519 | rt2x00_set_field32(®, MAC_CSR13_BIT12, 0); |
550 | rt2x00_set_field32(®, MAC_CSR13_BIT12, 0); | 520 | |
551 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | 521 | rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2); |
552 | } | 522 | rt2x00_set_field32(®, MAC_CSR13_BIT11, 0); |
553 | if (p2 != 0xff) { | 523 | |
554 | rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2); | 524 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); |
555 | rt2x00_set_field32(®, MAC_CSR13_BIT11, 0); | ||
556 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | ||
557 | } | ||
558 | } | 525 | } |
559 | 526 | ||
560 | static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | 527 | static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, |
@@ -570,37 +537,18 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | |||
570 | rt61pci_bbp_read(rt2x00dev, 4, &r4); | 537 | rt61pci_bbp_read(rt2x00dev, 4, &r4); |
571 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | 538 | rt61pci_bbp_read(rt2x00dev, 77, &r77); |
572 | 539 | ||
573 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | 540 | /* FIXME: Antenna selection for the rf 2529 is very confusing in the |
574 | rx_ant = !!(rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) & 2); | 541 | * legacy driver. The code below should be ok for non-diversity setups. |
575 | |||
576 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); | ||
577 | |||
578 | /* | ||
579 | * Configure the TX antenna. | ||
580 | */ | 542 | */ |
581 | switch (ant->tx) { | ||
582 | case ANTENNA_A: | ||
583 | rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0); | ||
584 | break; | ||
585 | case ANTENNA_SW_DIVERSITY: | ||
586 | case ANTENNA_HW_DIVERSITY: | ||
587 | /* | ||
588 | * NOTE: We should never come here because rt2x00lib is | ||
589 | * supposed to catch this and send us the correct antenna | ||
590 | * explicitely. However we are nog going to bug about this. | ||
591 | * Instead, just default to antenna B. | ||
592 | */ | ||
593 | case ANTENNA_B: | ||
594 | rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3); | ||
595 | break; | ||
596 | } | ||
597 | 543 | ||
598 | /* | 544 | /* |
599 | * Configure the RX antenna. | 545 | * Configure the RX antenna. |
600 | */ | 546 | */ |
601 | switch (ant->rx) { | 547 | switch (ant->rx) { |
602 | case ANTENNA_A: | 548 | case ANTENNA_A: |
603 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, rx_ant); | 549 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
550 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | ||
551 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); | ||
604 | break; | 552 | break; |
605 | case ANTENNA_SW_DIVERSITY: | 553 | case ANTENNA_SW_DIVERSITY: |
606 | case ANTENNA_HW_DIVERSITY: | 554 | case ANTENNA_HW_DIVERSITY: |
@@ -611,27 +559,12 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | |||
611 | * Instead, just default to antenna B. | 559 | * Instead, just default to antenna B. |
612 | */ | 560 | */ |
613 | case ANTENNA_B: | 561 | case ANTENNA_B: |
614 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, rx_ant); | 562 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
563 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | ||
564 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); | ||
615 | break; | 565 | break; |
616 | } | 566 | } |
617 | 567 | ||
618 | /* | ||
619 | * FIXME: We are using the default antenna setup to | ||
620 | * determine the remaining settings. This because we | ||
621 | * need to know what the EEPROM indicated. | ||
622 | * It is however unclear if this is required, and overall | ||
623 | * using the default antenna settings here is incorrect | ||
624 | * since mac80211 might have told us to use fixed settings. | ||
625 | */ | ||
626 | if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) | ||
627 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
628 | else | ||
629 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
630 | |||
631 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | ||
632 | (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) && | ||
633 | (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)); | ||
634 | |||
635 | rt61pci_bbp_write(rt2x00dev, 77, r77); | 568 | rt61pci_bbp_write(rt2x00dev, 77, r77); |
636 | rt61pci_bbp_write(rt2x00dev, 3, r3); | 569 | rt61pci_bbp_write(rt2x00dev, 3, r3); |
637 | rt61pci_bbp_write(rt2x00dev, 4, r4); | 570 | rt61pci_bbp_write(rt2x00dev, 4, r4); |
@@ -676,8 +609,6 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
676 | unsigned int i; | 609 | unsigned int i; |
677 | u32 reg; | 610 | u32 reg; |
678 | 611 | ||
679 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); | ||
680 | |||
681 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 612 | if (rt2x00dev->curr_hwmode == HWMODE_A) { |
682 | sel = antenna_sel_a; | 613 | sel = antenna_sel_a; |
683 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 614 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
@@ -686,15 +617,17 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
686 | lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | 617 | lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); |
687 | } | 618 | } |
688 | 619 | ||
620 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) | ||
621 | rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); | ||
622 | |||
623 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); | ||
624 | |||
689 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 625 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
690 | (rt2x00dev->curr_hwmode == HWMODE_B || | 626 | (rt2x00dev->curr_hwmode == HWMODE_B || |
691 | rt2x00dev->curr_hwmode == HWMODE_G)); | 627 | rt2x00dev->curr_hwmode == HWMODE_G)); |
692 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 628 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
693 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 629 | (rt2x00dev->curr_hwmode == HWMODE_A)); |
694 | 630 | ||
695 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) | ||
696 | rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); | ||
697 | |||
698 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); | 631 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); |
699 | 632 | ||
700 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 633 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index ba5101649403..50d9f6aa62ed 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -1077,13 +1077,19 @@ struct hw_pairwise_ta_entry { | |||
1077 | * R4: RX antenna control | 1077 | * R4: RX antenna control |
1078 | * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529) | 1078 | * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529) |
1079 | */ | 1079 | */ |
1080 | #define BBP_R4_RX_ANTENNA FIELD8(0x03) | 1080 | |
1081 | /* | ||
1082 | * ANTENNA_CONTROL semantics (guessed): | ||
1083 | * 0x1: Software controlled antenna switching (fixed or SW diversity) | ||
1084 | * 0x2: Hardware diversity. | ||
1085 | */ | ||
1086 | #define BBP_R4_RX_ANTENNA_CONTROL FIELD8(0x03) | ||
1081 | #define BBP_R4_RX_FRAME_END FIELD8(0x20) | 1087 | #define BBP_R4_RX_FRAME_END FIELD8(0x20) |
1082 | 1088 | ||
1083 | /* | 1089 | /* |
1084 | * R77 | 1090 | * R77 |
1085 | */ | 1091 | */ |
1086 | #define BBP_R77_TX_ANTENNA FIELD8(0x03) | 1092 | #define BBP_R77_RX_ANTENNA FIELD8(0x03) |
1087 | 1093 | ||
1088 | /* | 1094 | /* |
1089 | * RF registers | 1095 | * RF registers |