diff options
author | Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> | 2008-02-03 21:51:04 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:19:35 -0500 |
commit | d8ee398d183df36083e41e9162b0cf014f38f482 (patch) | |
tree | ee5c10f61aadd7ef8d78a06c3a48151b00ff0945 /drivers/net/wireless/ath5k/hw.c | |
parent | 406f2388cc1f6e6c176305bd325cef230ce1afdd (diff) |
ath5k: Port to new bitrate/channel API
Author: Nick Kossifidis <mickflemm@gmail.com>
Tested on 5211, 5213+5112, 5213A+2112A and it wors fine.
Also i figured out a way to process rate vallue found
on status descriptors, it's still buggy but we are getting
closer (i think it improved stability a little).
Changes to hw.c, initvals.c, phy.c
Changes-licensed-under: ISC
Changes to ath5k.h, base.c, base.h
Changes-licensed-under: 3-Clause-BSD
Acked-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Nick Kossifidis <mickflemm@gmail.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k/hw.c')
-rw-r--r-- | drivers/net/wireless/ath5k/hw.c | 170 |
1 files changed, 46 insertions, 124 deletions
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index c2de2d958e8e..998da6be2be3 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c | |||
@@ -140,9 +140,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
140 | * HW information | 140 | * HW information |
141 | */ | 141 | */ |
142 | 142 | ||
143 | /* Get reg domain from eeprom */ | ||
144 | ath5k_get_regdomain(ah); | ||
145 | |||
146 | ah->ah_op_mode = IEEE80211_IF_TYPE_STA; | 143 | ah->ah_op_mode = IEEE80211_IF_TYPE_STA; |
147 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; | 144 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; |
148 | ah->ah_turbo = false; | 145 | ah->ah_turbo = false; |
@@ -405,15 +402,15 @@ const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, | |||
405 | 402 | ||
406 | /* Get rate tables */ | 403 | /* Get rate tables */ |
407 | switch (mode) { | 404 | switch (mode) { |
408 | case MODE_IEEE80211A: | 405 | case AR5K_MODE_11A: |
409 | return &ath5k_rt_11a; | 406 | return &ath5k_rt_11a; |
410 | case MODE_ATHEROS_TURBO: | 407 | case AR5K_MODE_11A_TURBO: |
411 | return &ath5k_rt_turbo; | 408 | return &ath5k_rt_turbo; |
412 | case MODE_IEEE80211B: | 409 | case AR5K_MODE_11B: |
413 | return &ath5k_rt_11b; | 410 | return &ath5k_rt_11b; |
414 | case MODE_IEEE80211G: | 411 | case AR5K_MODE_11G: |
415 | return &ath5k_rt_11g; | 412 | return &ath5k_rt_11g; |
416 | case MODE_ATHEROS_TURBOG: | 413 | case AR5K_MODE_11G_TURBO: |
417 | return &ath5k_rt_xr; | 414 | return &ath5k_rt_xr; |
418 | } | 415 | } |
419 | 416 | ||
@@ -457,15 +454,15 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
457 | ds_coef_exp, ds_coef_man, clock; | 454 | ds_coef_exp, ds_coef_man, clock; |
458 | 455 | ||
459 | if (!(ah->ah_version == AR5K_AR5212) || | 456 | if (!(ah->ah_version == AR5K_AR5212) || |
460 | !(channel->val & CHANNEL_OFDM)) | 457 | !(channel->hw_value & CHANNEL_OFDM)) |
461 | BUG(); | 458 | BUG(); |
462 | 459 | ||
463 | /* Seems there are two PLLs, one for baseband sampling and one | 460 | /* Seems there are two PLLs, one for baseband sampling and one |
464 | * for tuning. Tuning basebands are 40 MHz or 80MHz when in | 461 | * for tuning. Tuning basebands are 40 MHz or 80MHz when in |
465 | * turbo. */ | 462 | * turbo. */ |
466 | clock = channel->val & CHANNEL_TURBO ? 80 : 40; | 463 | clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40; |
467 | coef_scaled = ((5 * (clock << 24)) / 2) / | 464 | coef_scaled = ((5 * (clock << 24)) / 2) / |
468 | channel->freq; | 465 | channel->center_freq; |
469 | 466 | ||
470 | for (coef_exp = 31; coef_exp > 0; coef_exp--) | 467 | for (coef_exp = 31; coef_exp > 0; coef_exp--) |
471 | if ((coef_scaled >> coef_exp) & 0x1) | 468 | if ((coef_scaled >> coef_exp) & 0x1) |
@@ -492,8 +489,7 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
492 | * ath5k_hw_write_rate_duration - set rate duration during hw resets | 489 | * ath5k_hw_write_rate_duration - set rate duration during hw resets |
493 | * | 490 | * |
494 | * @ah: the &struct ath5k_hw | 491 | * @ah: the &struct ath5k_hw |
495 | * @driver_mode: one of enum ieee80211_phymode or our one of our own | 492 | * @mode: one of enum ath5k_driver_mode |
496 | * vendor modes | ||
497 | * | 493 | * |
498 | * Write the rate duration table for the current mode upon hw reset. This | 494 | * Write the rate duration table for the current mode upon hw reset. This |
499 | * is a helper for ath5k_hw_reset(). It seems all this is doing is setting | 495 | * is a helper for ath5k_hw_reset(). It seems all this is doing is setting |
@@ -504,19 +500,20 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
504 | * | 500 | * |
505 | */ | 501 | */ |
506 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | 502 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, |
507 | unsigned int driver_mode) | 503 | unsigned int mode) |
508 | { | 504 | { |
509 | struct ath5k_softc *sc = ah->ah_sc; | 505 | struct ath5k_softc *sc = ah->ah_sc; |
510 | const struct ath5k_rate_table *rt; | 506 | const struct ath5k_rate_table *rt; |
507 | struct ieee80211_rate srate = {}; | ||
511 | unsigned int i; | 508 | unsigned int i; |
512 | 509 | ||
513 | /* Get rate table for the current operating mode */ | 510 | /* Get rate table for the current operating mode */ |
514 | rt = ath5k_hw_get_rate_table(ah, | 511 | rt = ath5k_hw_get_rate_table(ah, mode); |
515 | driver_mode); | ||
516 | 512 | ||
517 | /* Write rate duration table */ | 513 | /* Write rate duration table */ |
518 | for (i = 0; i < rt->rate_count; i++) { | 514 | for (i = 0; i < rt->rate_count; i++) { |
519 | const struct ath5k_rate *rate, *control_rate; | 515 | const struct ath5k_rate *rate, *control_rate; |
516 | |||
520 | u32 reg; | 517 | u32 reg; |
521 | u16 tx_time; | 518 | u16 tx_time; |
522 | 519 | ||
@@ -526,6 +523,8 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | |||
526 | /* Set ACK timeout */ | 523 | /* Set ACK timeout */ |
527 | reg = AR5K_RATE_DUR(rate->rate_code); | 524 | reg = AR5K_RATE_DUR(rate->rate_code); |
528 | 525 | ||
526 | srate.bitrate = control_rate->rate_kbps/100; | ||
527 | |||
529 | /* An ACK frame consists of 10 bytes. If you add the FCS, | 528 | /* An ACK frame consists of 10 bytes. If you add the FCS, |
530 | * which ieee80211_generic_frame_duration() adds, | 529 | * which ieee80211_generic_frame_duration() adds, |
531 | * its 14 bytes. Note we use the control rate and not the | 530 | * its 14 bytes. Note we use the control rate and not the |
@@ -533,7 +532,7 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | |||
533 | * ieee80211_duration() for a brief description of | 532 | * ieee80211_duration() for a brief description of |
534 | * what rate we should choose to TX ACKs. */ | 533 | * what rate we should choose to TX ACKs. */ |
535 | tx_time = ieee80211_generic_frame_duration(sc->hw, | 534 | tx_time = ieee80211_generic_frame_duration(sc->hw, |
536 | sc->vif, 10, control_rate->rate_kbps/100); | 535 | sc->vif, 10, &srate); |
537 | 536 | ||
538 | ath5k_hw_reg_write(ah, tx_time, reg); | 537 | ath5k_hw_reg_write(ah, tx_time, reg); |
539 | 538 | ||
@@ -567,7 +566,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
567 | { | 566 | { |
568 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 567 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
569 | u32 data, s_seq, s_ant, s_led[3]; | 568 | u32 data, s_seq, s_ant, s_led[3]; |
570 | unsigned int i, mode, freq, ee_mode, ant[2], driver_mode = -1; | 569 | unsigned int i, mode, freq, ee_mode, ant[2]; |
571 | int ret; | 570 | int ret; |
572 | 571 | ||
573 | ATH5K_TRACE(ah->ah_sc); | 572 | ATH5K_TRACE(ah->ah_sc); |
@@ -602,7 +601,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
602 | 601 | ||
603 | 602 | ||
604 | /*Wakeup the device*/ | 603 | /*Wakeup the device*/ |
605 | ret = ath5k_hw_nic_wakeup(ah, channel->val, false); | 604 | ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); |
606 | if (ret) | 605 | if (ret) |
607 | return ret; | 606 | return ret; |
608 | 607 | ||
@@ -624,37 +623,32 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
624 | return -EINVAL; | 623 | return -EINVAL; |
625 | } | 624 | } |
626 | 625 | ||
627 | switch (channel->val & CHANNEL_MODES) { | 626 | switch (channel->hw_value & CHANNEL_MODES) { |
628 | case CHANNEL_A: | 627 | case CHANNEL_A: |
629 | mode = AR5K_INI_VAL_11A; | 628 | mode = AR5K_MODE_11A; |
630 | freq = AR5K_INI_RFGAIN_5GHZ; | 629 | freq = AR5K_INI_RFGAIN_5GHZ; |
631 | ee_mode = AR5K_EEPROM_MODE_11A; | 630 | ee_mode = AR5K_EEPROM_MODE_11A; |
632 | driver_mode = MODE_IEEE80211A; | ||
633 | break; | 631 | break; |
634 | case CHANNEL_G: | 632 | case CHANNEL_G: |
635 | mode = AR5K_INI_VAL_11G; | 633 | mode = AR5K_MODE_11G; |
636 | freq = AR5K_INI_RFGAIN_2GHZ; | 634 | freq = AR5K_INI_RFGAIN_2GHZ; |
637 | ee_mode = AR5K_EEPROM_MODE_11G; | 635 | ee_mode = AR5K_EEPROM_MODE_11G; |
638 | driver_mode = MODE_IEEE80211G; | ||
639 | break; | 636 | break; |
640 | case CHANNEL_B: | 637 | case CHANNEL_B: |
641 | mode = AR5K_INI_VAL_11B; | 638 | mode = AR5K_MODE_11B; |
642 | freq = AR5K_INI_RFGAIN_2GHZ; | 639 | freq = AR5K_INI_RFGAIN_2GHZ; |
643 | ee_mode = AR5K_EEPROM_MODE_11B; | 640 | ee_mode = AR5K_EEPROM_MODE_11B; |
644 | driver_mode = MODE_IEEE80211B; | ||
645 | break; | 641 | break; |
646 | case CHANNEL_T: | 642 | case CHANNEL_T: |
647 | mode = AR5K_INI_VAL_11A_TURBO; | 643 | mode = AR5K_MODE_11A_TURBO; |
648 | freq = AR5K_INI_RFGAIN_5GHZ; | 644 | freq = AR5K_INI_RFGAIN_5GHZ; |
649 | ee_mode = AR5K_EEPROM_MODE_11A; | 645 | ee_mode = AR5K_EEPROM_MODE_11A; |
650 | driver_mode = MODE_ATHEROS_TURBO; | ||
651 | break; | 646 | break; |
652 | /*Is this ok on 5211 too ?*/ | 647 | /*Is this ok on 5211 too ?*/ |
653 | case CHANNEL_TG: | 648 | case CHANNEL_TG: |
654 | mode = AR5K_INI_VAL_11G_TURBO; | 649 | mode = AR5K_MODE_11G_TURBO; |
655 | freq = AR5K_INI_RFGAIN_2GHZ; | 650 | freq = AR5K_INI_RFGAIN_2GHZ; |
656 | ee_mode = AR5K_EEPROM_MODE_11G; | 651 | ee_mode = AR5K_EEPROM_MODE_11G; |
657 | driver_mode = MODE_ATHEROS_TURBOG; | ||
658 | break; | 652 | break; |
659 | case CHANNEL_XR: | 653 | case CHANNEL_XR: |
660 | if (ah->ah_version == AR5K_AR5211) { | 654 | if (ah->ah_version == AR5K_AR5211) { |
@@ -662,14 +656,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
662 | "XR mode not available on 5211"); | 656 | "XR mode not available on 5211"); |
663 | return -EINVAL; | 657 | return -EINVAL; |
664 | } | 658 | } |
665 | mode = AR5K_INI_VAL_XR; | 659 | mode = AR5K_MODE_XR; |
666 | freq = AR5K_INI_RFGAIN_5GHZ; | 660 | freq = AR5K_INI_RFGAIN_5GHZ; |
667 | ee_mode = AR5K_EEPROM_MODE_11A; | 661 | ee_mode = AR5K_EEPROM_MODE_11A; |
668 | driver_mode = MODE_IEEE80211A; | ||
669 | break; | 662 | break; |
670 | default: | 663 | default: |
671 | ATH5K_ERR(ah->ah_sc, | 664 | ATH5K_ERR(ah->ah_sc, |
672 | "invalid channel: %d\n", channel->freq); | 665 | "invalid channel: %d\n", channel->center_freq); |
673 | return -EINVAL; | 666 | return -EINVAL; |
674 | } | 667 | } |
675 | 668 | ||
@@ -702,7 +695,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
702 | if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */ | 695 | if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */ |
703 | ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11)); | 696 | ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11)); |
704 | 697 | ||
705 | if (channel->val == CHANNEL_G) | 698 | if (channel->hw_value == CHANNEL_G) |
706 | ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */ | 699 | ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */ |
707 | else | 700 | else |
708 | ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83)); | 701 | ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83)); |
@@ -720,7 +713,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
720 | AR5K_SREV_RAD_5112A) { | 713 | AR5K_SREV_RAD_5112A) { |
721 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, | 714 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, |
722 | AR5K_PHY_CCKTXCTL); | 715 | AR5K_PHY_CCKTXCTL); |
723 | if (channel->val & CHANNEL_5GHZ) | 716 | if (channel->hw_value & CHANNEL_5GHZ) |
724 | data = 0xffb81020; | 717 | data = 0xffb81020; |
725 | else | 718 | else |
726 | data = 0xffb80d20; | 719 | data = 0xffb80d20; |
@@ -740,7 +733,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
740 | * mac80211 are integrated */ | 733 | * mac80211 are integrated */ |
741 | if (ah->ah_version == AR5K_AR5212 && | 734 | if (ah->ah_version == AR5K_AR5212 && |
742 | ah->ah_sc->vif != NULL) | 735 | ah->ah_sc->vif != NULL) |
743 | ath5k_hw_write_rate_duration(ah, driver_mode); | 736 | ath5k_hw_write_rate_duration(ah, mode); |
744 | 737 | ||
745 | /* | 738 | /* |
746 | * Write RF registers | 739 | * Write RF registers |
@@ -756,7 +749,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
756 | 749 | ||
757 | /* Write OFDM timings on 5212*/ | 750 | /* Write OFDM timings on 5212*/ |
758 | if (ah->ah_version == AR5K_AR5212 && | 751 | if (ah->ah_version == AR5K_AR5212 && |
759 | channel->val & CHANNEL_OFDM) { | 752 | channel->hw_value & CHANNEL_OFDM) { |
760 | ret = ath5k_hw_write_ofdm_timings(ah, channel); | 753 | ret = ath5k_hw_write_ofdm_timings(ah, channel); |
761 | if (ret) | 754 | if (ret) |
762 | return ret; | 755 | return ret; |
@@ -765,7 +758,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
765 | /*Enable/disable 802.11b mode on 5111 | 758 | /*Enable/disable 802.11b mode on 5111 |
766 | (enable 2111 frequency converter + CCK)*/ | 759 | (enable 2111 frequency converter + CCK)*/ |
767 | if (ah->ah_radio == AR5K_RF5111) { | 760 | if (ah->ah_radio == AR5K_RF5111) { |
768 | if (driver_mode == MODE_IEEE80211B) | 761 | if (mode == AR5K_MODE_11B) |
769 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, | 762 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, |
770 | AR5K_TXCFG_B_MODE); | 763 | AR5K_TXCFG_B_MODE); |
771 | else | 764 | else |
@@ -903,7 +896,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
903 | if (ah->ah_version != AR5K_AR5210) { | 896 | if (ah->ah_version != AR5K_AR5210) { |
904 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | 897 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & |
905 | AR5K_PHY_RX_DELAY_M; | 898 | AR5K_PHY_RX_DELAY_M; |
906 | data = (channel->val & CHANNEL_CCK) ? | 899 | data = (channel->hw_value & CHANNEL_CCK) ? |
907 | ((data << 2) / 22) : (data / 10); | 900 | ((data << 2) / 22) : (data / 10); |
908 | 901 | ||
909 | udelay(100 + data); | 902 | udelay(100 + data); |
@@ -920,11 +913,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
920 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | 913 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, |
921 | AR5K_PHY_AGCCTL_CAL, 0, false)) { | 914 | AR5K_PHY_AGCCTL_CAL, 0, false)) { |
922 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", | 915 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", |
923 | channel->freq); | 916 | channel->center_freq); |
924 | return -EAGAIN; | 917 | return -EAGAIN; |
925 | } | 918 | } |
926 | 919 | ||
927 | ret = ath5k_hw_noise_floor_calibration(ah, channel->freq); | 920 | ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); |
928 | if (ret) | 921 | if (ret) |
929 | return ret; | 922 | return ret; |
930 | 923 | ||
@@ -932,7 +925,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
932 | 925 | ||
933 | /* A and G modes can use QAM modulation which requires enabling | 926 | /* A and G modes can use QAM modulation which requires enabling |
934 | * I and Q calibration. Don't bother in B mode. */ | 927 | * I and Q calibration. Don't bother in B mode. */ |
935 | if (!(driver_mode == MODE_IEEE80211B)) { | 928 | if (!(mode == AR5K_MODE_11B)) { |
936 | ah->ah_calibration = true; | 929 | ah->ah_calibration = true; |
937 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, | 930 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, |
938 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); | 931 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); |
@@ -1590,9 +1583,10 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) | |||
1590 | /* | 1583 | /* |
1591 | * Write to eeprom - currently disabled, use at your own risk | 1584 | * Write to eeprom - currently disabled, use at your own risk |
1592 | */ | 1585 | */ |
1586 | #if 0 | ||
1593 | static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) | 1587 | static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) |
1594 | { | 1588 | { |
1595 | #if 0 | 1589 | |
1596 | u32 status, timeout; | 1590 | u32 status, timeout; |
1597 | 1591 | ||
1598 | ATH5K_TRACE(ah->ah_sc); | 1592 | ATH5K_TRACE(ah->ah_sc); |
@@ -1634,10 +1628,11 @@ static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) | |||
1634 | } | 1628 | } |
1635 | udelay(15); | 1629 | udelay(15); |
1636 | } | 1630 | } |
1637 | #endif | 1631 | |
1638 | ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!"); | 1632 | ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!"); |
1639 | return -EIO; | 1633 | return -EIO; |
1640 | } | 1634 | } |
1635 | #endif | ||
1641 | 1636 | ||
1642 | /* | 1637 | /* |
1643 | * Translate binary channel representation in EEPROM to frequency | 1638 | * Translate binary channel representation in EEPROM to frequency |
@@ -2043,50 +2038,6 @@ static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | |||
2043 | } | 2038 | } |
2044 | 2039 | ||
2045 | /* | 2040 | /* |
2046 | * Read/Write regulatory domain | ||
2047 | */ | ||
2048 | static bool ath5k_eeprom_regulation_domain(struct ath5k_hw *ah, bool write, | ||
2049 | enum ath5k_regdom *regdomain) | ||
2050 | { | ||
2051 | u16 ee_regdomain; | ||
2052 | |||
2053 | /* Read current value */ | ||
2054 | if (write != true) { | ||
2055 | ee_regdomain = ah->ah_capabilities.cap_eeprom.ee_regdomain; | ||
2056 | *regdomain = ath5k_regdom_to_ieee(ee_regdomain); | ||
2057 | return true; | ||
2058 | } | ||
2059 | |||
2060 | ee_regdomain = ath5k_regdom_from_ieee(*regdomain); | ||
2061 | |||
2062 | /* Try to write a new value */ | ||
2063 | if (ah->ah_capabilities.cap_eeprom.ee_protect & | ||
2064 | AR5K_EEPROM_PROTECT_WR_128_191) | ||
2065 | return false; | ||
2066 | if (ath5k_hw_eeprom_write(ah, AR5K_EEPROM_REG_DOMAIN, ee_regdomain)!=0) | ||
2067 | return false; | ||
2068 | |||
2069 | ah->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain; | ||
2070 | |||
2071 | return true; | ||
2072 | } | ||
2073 | |||
2074 | /* | ||
2075 | * Use the above to write a new regulatory domain | ||
2076 | */ | ||
2077 | int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain) | ||
2078 | { | ||
2079 | enum ath5k_regdom ieee_regdomain; | ||
2080 | |||
2081 | ieee_regdomain = ath5k_regdom_to_ieee(regdomain); | ||
2082 | |||
2083 | if (ath5k_eeprom_regulation_domain(ah, true, &ieee_regdomain) == true) | ||
2084 | return 0; | ||
2085 | |||
2086 | return -EIO; | ||
2087 | } | ||
2088 | |||
2089 | /* | ||
2090 | * Fill the capabilities struct | 2041 | * Fill the capabilities struct |
2091 | */ | 2042 | */ |
2092 | static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | 2043 | static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) |
@@ -2108,8 +2059,8 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | |||
2108 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; | 2059 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; |
2109 | 2060 | ||
2110 | /* Set supported modes */ | 2061 | /* Set supported modes */ |
2111 | __set_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode); | 2062 | __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); |
2112 | __set_bit(MODE_ATHEROS_TURBO, ah->ah_capabilities.cap_mode); | 2063 | __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode); |
2113 | } else { | 2064 | } else { |
2114 | /* | 2065 | /* |
2115 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz | 2066 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz |
@@ -2131,12 +2082,12 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | |||
2131 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; | 2082 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; |
2132 | 2083 | ||
2133 | /* Set supported modes */ | 2084 | /* Set supported modes */ |
2134 | __set_bit(MODE_IEEE80211A, | 2085 | __set_bit(AR5K_MODE_11A, |
2135 | ah->ah_capabilities.cap_mode); | 2086 | ah->ah_capabilities.cap_mode); |
2136 | __set_bit(MODE_ATHEROS_TURBO, | 2087 | __set_bit(AR5K_MODE_11A_TURBO, |
2137 | ah->ah_capabilities.cap_mode); | 2088 | ah->ah_capabilities.cap_mode); |
2138 | if (ah->ah_version == AR5K_AR5212) | 2089 | if (ah->ah_version == AR5K_AR5212) |
2139 | __set_bit(MODE_ATHEROS_TURBOG, | 2090 | __set_bit(AR5K_MODE_11G_TURBO, |
2140 | ah->ah_capabilities.cap_mode); | 2091 | ah->ah_capabilities.cap_mode); |
2141 | } | 2092 | } |
2142 | 2093 | ||
@@ -2148,11 +2099,11 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | |||
2148 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; | 2099 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; |
2149 | 2100 | ||
2150 | if (AR5K_EEPROM_HDR_11B(ee_header)) | 2101 | if (AR5K_EEPROM_HDR_11B(ee_header)) |
2151 | __set_bit(MODE_IEEE80211B, | 2102 | __set_bit(AR5K_MODE_11B, |
2152 | ah->ah_capabilities.cap_mode); | 2103 | ah->ah_capabilities.cap_mode); |
2153 | 2104 | ||
2154 | if (AR5K_EEPROM_HDR_11G(ee_header)) | 2105 | if (AR5K_EEPROM_HDR_11G(ee_header)) |
2155 | __set_bit(MODE_IEEE80211G, | 2106 | __set_bit(AR5K_MODE_11G, |
2156 | ah->ah_capabilities.cap_mode); | 2107 | ah->ah_capabilities.cap_mode); |
2157 | } | 2108 | } |
2158 | } | 2109 | } |
@@ -4248,35 +4199,6 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, | |||
4248 | } | 4199 | } |
4249 | 4200 | ||
4250 | 4201 | ||
4251 | /*********************************\ | ||
4252 | Regulatory Domain/Channels Setup | ||
4253 | \*********************************/ | ||
4254 | |||
4255 | u16 ath5k_get_regdomain(struct ath5k_hw *ah) | ||
4256 | { | ||
4257 | u16 regdomain; | ||
4258 | enum ath5k_regdom ieee_regdomain; | ||
4259 | #ifdef COUNTRYCODE | ||
4260 | u16 code; | ||
4261 | #endif | ||
4262 | |||
4263 | ath5k_eeprom_regulation_domain(ah, false, &ieee_regdomain); | ||
4264 | ah->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain; | ||
4265 | |||
4266 | #ifdef COUNTRYCODE | ||
4267 | /* | ||
4268 | * Get the regulation domain by country code. This will ignore | ||
4269 | * the settings found in the EEPROM. | ||
4270 | */ | ||
4271 | code = ieee80211_name2countrycode(COUNTRYCODE); | ||
4272 | ieee_regdomain = ieee80211_countrycode2regdomain(code); | ||
4273 | #endif | ||
4274 | |||
4275 | regdomain = ath5k_regdom_from_ieee(ieee_regdomain); | ||
4276 | ah->ah_capabilities.cap_regdomain.reg_current = regdomain; | ||
4277 | |||
4278 | return regdomain; | ||
4279 | } | ||
4280 | 4202 | ||
4281 | 4203 | ||
4282 | /****************\ | 4204 | /****************\ |