diff options
244 files changed, 12283 insertions, 6490 deletions
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 84206898f77d..3510de2cf622 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -159,6 +159,11 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) | |||
159 | rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211); | 159 | rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211); |
160 | 160 | ||
161 | /* | 161 | /* |
162 | * Set default Tx frame to Tx data start delay | ||
163 | */ | ||
164 | txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT; | ||
165 | |||
166 | /* | ||
162 | * 5210 initvals don't include usec settings | 167 | * 5210 initvals don't include usec settings |
163 | * so we need to use magic values here for | 168 | * so we need to use magic values here for |
164 | * tx/rx latencies | 169 | * tx/rx latencies |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 5193ed58a17b..61956392f2da 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -21,11 +21,15 @@ | |||
21 | #include <linux/ath9k_platform.h> | 21 | #include <linux/ath9k_platform.h> |
22 | #include "ath9k.h" | 22 | #include "ath9k.h" |
23 | 23 | ||
24 | const struct platform_device_id ath9k_platform_id_table[] = { | 24 | static const struct platform_device_id ath9k_platform_id_table[] = { |
25 | { | 25 | { |
26 | .name = "ath9k", | 26 | .name = "ath9k", |
27 | .driver_data = AR5416_AR9100_DEVID, | 27 | .driver_data = AR5416_AR9100_DEVID, |
28 | }, | 28 | }, |
29 | { | ||
30 | .name = "ar934x_wmac", | ||
31 | .driver_data = AR9300_DEVID_AR9340, | ||
32 | }, | ||
29 | {}, | 33 | {}, |
30 | }; | 34 | }; |
31 | 35 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 2e31c775351f..5a1f4f511bc1 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -899,12 +899,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah) | |||
899 | * check here default level should not modify INI setting. | 899 | * check here default level should not modify INI setting. |
900 | */ | 900 | */ |
901 | if (use_new_ani(ah)) { | 901 | if (use_new_ani(ah)) { |
902 | const struct ani_ofdm_level_entry *entry_ofdm; | ||
903 | const struct ani_cck_level_entry *entry_cck; | ||
904 | |||
905 | entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL]; | ||
906 | entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL]; | ||
907 | |||
908 | ah->aniperiod = ATH9K_ANI_PERIOD_NEW; | 902 | ah->aniperiod = ATH9K_ANI_PERIOD_NEW; |
909 | ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; | 903 | ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; |
910 | } else { | 904 | } else { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 4a4cd88429c0..f276cb922b4d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -18,13 +18,13 @@ | |||
18 | #include "hw-ops.h" | 18 | #include "hw-ops.h" |
19 | #include "ar9003_phy.h" | 19 | #include "ar9003_phy.h" |
20 | 20 | ||
21 | #define MPASS 3 | ||
22 | #define MAX_MEASUREMENT 8 | 21 | #define MAX_MEASUREMENT 8 |
23 | #define MAX_DIFFERENCE 10 | 22 | #define MAX_MAG_DELTA 11 |
23 | #define MAX_PHS_DELTA 10 | ||
24 | 24 | ||
25 | struct coeff { | 25 | struct coeff { |
26 | int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; | 26 | int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; |
27 | int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; | 27 | int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; |
28 | int iqc_coeff[2]; | 28 | int iqc_coeff[2]; |
29 | }; | 29 | }; |
30 | 30 | ||
@@ -185,17 +185,19 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah) | |||
185 | 185 | ||
186 | /* Accumulate IQ cal measures for active chains */ | 186 | /* Accumulate IQ cal measures for active chains */ |
187 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | 187 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { |
188 | ah->totalPowerMeasI[i] += | 188 | if (ah->txchainmask & BIT(i)) { |
189 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | 189 | ah->totalPowerMeasI[i] += |
190 | ah->totalPowerMeasQ[i] += | 190 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); |
191 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | 191 | ah->totalPowerMeasQ[i] += |
192 | ah->totalIqCorrMeas[i] += | 192 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); |
193 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | 193 | ah->totalIqCorrMeas[i] += |
194 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | 194 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); |
195 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | 195 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, |
196 | ah->cal_samples, i, ah->totalPowerMeasI[i], | 196 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", |
197 | ah->totalPowerMeasQ[i], | 197 | ah->cal_samples, i, ah->totalPowerMeasI[i], |
198 | ah->totalIqCorrMeas[i]); | 198 | ah->totalPowerMeasQ[i], |
199 | ah->totalIqCorrMeas[i]); | ||
200 | } | ||
199 | } | 201 | } |
200 | } | 202 | } |
201 | 203 | ||
@@ -608,36 +610,48 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
608 | return true; | 610 | return true; |
609 | } | 611 | } |
610 | 612 | ||
611 | static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg) | 613 | static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, |
614 | int max_delta) | ||
612 | { | 615 | { |
613 | int diff[MPASS]; | 616 | int mp_max = -64, max_idx = 0; |
614 | 617 | int mp_min = 63, min_idx = 0; | |
615 | diff[0] = abs(mp_coeff[0] - mp_coeff[1]); | 618 | int mp_avg = 0, i, outlier_idx = 0; |
616 | diff[1] = abs(mp_coeff[1] - mp_coeff[2]); | 619 | |
617 | diff[2] = abs(mp_coeff[2] - mp_coeff[0]); | 620 | /* find min/max mismatch across all calibrated gains */ |
618 | 621 | for (i = 0; i < nmeasurement; i++) { | |
619 | if (diff[0] > MAX_DIFFERENCE && | 622 | mp_avg += mp_coeff[i]; |
620 | diff[1] > MAX_DIFFERENCE && | 623 | if (mp_coeff[i] > mp_max) { |
621 | diff[2] > MAX_DIFFERENCE) | 624 | mp_max = mp_coeff[i]; |
622 | return false; | 625 | max_idx = i; |
626 | } else if (mp_coeff[i] < mp_min) { | ||
627 | mp_min = mp_coeff[i]; | ||
628 | min_idx = i; | ||
629 | } | ||
630 | } | ||
623 | 631 | ||
624 | if (diff[0] <= diff[1] && diff[0] <= diff[2]) | 632 | /* find average (exclude max abs value) */ |
625 | *mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2; | 633 | for (i = 0; i < nmeasurement; i++) { |
626 | else if (diff[1] <= diff[2]) | 634 | if ((abs(mp_coeff[i]) < abs(mp_max)) || |
627 | *mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2; | 635 | (abs(mp_coeff[i]) < abs(mp_min))) |
628 | else | 636 | mp_avg += mp_coeff[i]; |
629 | *mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2; | 637 | } |
638 | mp_avg /= (nmeasurement - 1); | ||
630 | 639 | ||
631 | return true; | 640 | /* detect outlier */ |
641 | if (abs(mp_max - mp_min) > max_delta) { | ||
642 | if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg)) | ||
643 | outlier_idx = max_idx; | ||
644 | else | ||
645 | outlier_idx = min_idx; | ||
646 | } | ||
647 | mp_coeff[outlier_idx] = mp_avg; | ||
632 | } | 648 | } |
633 | 649 | ||
634 | static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | 650 | static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, |
635 | u8 num_chains, | 651 | u8 num_chains, |
636 | struct coeff *coeff) | 652 | struct coeff *coeff) |
637 | { | 653 | { |
638 | struct ath_common *common = ath9k_hw_common(ah); | ||
639 | int i, im, nmeasurement; | 654 | int i, im, nmeasurement; |
640 | int magnitude, phase; | ||
641 | u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; | 655 | u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; |
642 | 656 | ||
643 | memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); | 657 | memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); |
@@ -657,37 +671,28 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
657 | 671 | ||
658 | /* Load the average of 2 passes */ | 672 | /* Load the average of 2 passes */ |
659 | for (i = 0; i < num_chains; i++) { | 673 | for (i = 0; i < num_chains; i++) { |
660 | if (AR_SREV_9485(ah)) | 674 | nmeasurement = REG_READ_FIELD(ah, |
661 | nmeasurement = REG_READ_FIELD(ah, | 675 | AR_PHY_TX_IQCAL_STATUS_B0, |
662 | AR_PHY_TX_IQCAL_STATUS_B0_9485, | 676 | AR_PHY_CALIBRATED_GAINS_0); |
663 | AR_PHY_CALIBRATED_GAINS_0); | ||
664 | else | ||
665 | nmeasurement = REG_READ_FIELD(ah, | ||
666 | AR_PHY_TX_IQCAL_STATUS_B0, | ||
667 | AR_PHY_CALIBRATED_GAINS_0); | ||
668 | 677 | ||
669 | if (nmeasurement > MAX_MEASUREMENT) | 678 | if (nmeasurement > MAX_MEASUREMENT) |
670 | nmeasurement = MAX_MEASUREMENT; | 679 | nmeasurement = MAX_MEASUREMENT; |
671 | 680 | ||
672 | for (im = 0; im < nmeasurement; im++) { | 681 | /* detect outlier only if nmeasurement > 1 */ |
673 | /* | 682 | if (nmeasurement > 1) { |
674 | * Determine which 2 passes are closest and compute avg | 683 | /* Detect magnitude outlier */ |
675 | * magnitude | 684 | ar9003_hw_detect_outlier(coeff->mag_coeff[i], |
676 | */ | 685 | nmeasurement, MAX_MAG_DELTA); |
677 | if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im], | ||
678 | &magnitude)) | ||
679 | goto disable_txiqcal; | ||
680 | 686 | ||
681 | /* | 687 | /* Detect phase outlier */ |
682 | * Determine which 2 passes are closest and compute avg | 688 | ar9003_hw_detect_outlier(coeff->phs_coeff[i], |
683 | * phase | 689 | nmeasurement, MAX_PHS_DELTA); |
684 | */ | 690 | } |
685 | if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im], | 691 | |
686 | &phase)) | 692 | for (im = 0; im < nmeasurement; im++) { |
687 | goto disable_txiqcal; | ||
688 | 693 | ||
689 | coeff->iqc_coeff[0] = (magnitude & 0x7f) | | 694 | coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) | |
690 | ((phase & 0x7f) << 7); | 695 | ((coeff->phs_coeff[i][im] & 0x7f) << 7); |
691 | 696 | ||
692 | if ((im % 2) == 0) | 697 | if ((im % 2) == 0) |
693 | REG_RMW_FIELD(ah, tx_corr_coeff[im][i], | 698 | REG_RMW_FIELD(ah, tx_corr_coeff[im][i], |
@@ -707,141 +712,37 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
707 | 712 | ||
708 | return; | 713 | return; |
709 | 714 | ||
710 | disable_txiqcal: | ||
711 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, | ||
712 | AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0); | ||
713 | REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, | ||
714 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0); | ||
715 | |||
716 | ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n"); | ||
717 | } | 715 | } |
718 | 716 | ||
719 | static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) | 717 | static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) |
720 | { | 718 | { |
721 | struct ath_common *common = ath9k_hw_common(ah); | 719 | struct ath_common *common = ath9k_hw_common(ah); |
722 | static const u32 txiqcal_status[AR9300_MAX_CHAINS] = { | ||
723 | AR_PHY_TX_IQCAL_STATUS_B0, | ||
724 | AR_PHY_TX_IQCAL_STATUS_B1, | ||
725 | AR_PHY_TX_IQCAL_STATUS_B2, | ||
726 | }; | ||
727 | static const u32 chan_info_tab[] = { | ||
728 | AR_PHY_CHAN_INFO_TAB_0, | ||
729 | AR_PHY_CHAN_INFO_TAB_1, | ||
730 | AR_PHY_CHAN_INFO_TAB_2, | ||
731 | }; | ||
732 | struct coeff coeff; | ||
733 | s32 iq_res[6]; | ||
734 | s32 i, j, ip, im, nmeasurement; | ||
735 | u8 nchains = get_streams(common->tx_chainmask); | ||
736 | |||
737 | for (ip = 0; ip < MPASS; ip++) { | ||
738 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, | ||
739 | AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, | ||
740 | DELPT); | ||
741 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, | ||
742 | AR_PHY_TX_IQCAL_START_DO_CAL, | ||
743 | AR_PHY_TX_IQCAL_START_DO_CAL); | ||
744 | |||
745 | if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, | ||
746 | AR_PHY_TX_IQCAL_START_DO_CAL, | ||
747 | 0, AH_WAIT_TIMEOUT)) { | ||
748 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
749 | "Tx IQ Cal not complete.\n"); | ||
750 | goto TX_IQ_CAL_FAILED; | ||
751 | } | ||
752 | |||
753 | nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0, | ||
754 | AR_PHY_CALIBRATED_GAINS_0); | ||
755 | if (nmeasurement > MAX_MEASUREMENT) | ||
756 | nmeasurement = MAX_MEASUREMENT; | ||
757 | |||
758 | for (i = 0; i < nchains; i++) { | ||
759 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
760 | "Doing Tx IQ Cal for chain %d.\n", i); | ||
761 | for (im = 0; im < nmeasurement; im++) { | ||
762 | if (REG_READ(ah, txiqcal_status[i]) & | ||
763 | AR_PHY_TX_IQCAL_STATUS_FAILED) { | ||
764 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
765 | "Tx IQ Cal failed for chain %d.\n", i); | ||
766 | goto TX_IQ_CAL_FAILED; | ||
767 | } | ||
768 | |||
769 | for (j = 0; j < 3; j++) { | ||
770 | u8 idx = 2 * j, | ||
771 | offset = 4 * (3 * im + j); | ||
772 | |||
773 | REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, | ||
774 | AR_PHY_CHAN_INFO_TAB_S2_READ, | ||
775 | 0); | ||
776 | |||
777 | /* 32 bits */ | ||
778 | iq_res[idx] = REG_READ(ah, | ||
779 | chan_info_tab[i] + | ||
780 | offset); | ||
781 | |||
782 | REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, | ||
783 | AR_PHY_CHAN_INFO_TAB_S2_READ, | ||
784 | 1); | ||
785 | |||
786 | /* 16 bits */ | ||
787 | iq_res[idx+1] = 0xffff & REG_READ(ah, | ||
788 | chan_info_tab[i] + | ||
789 | offset); | ||
790 | |||
791 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
792 | "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", | ||
793 | idx, iq_res[idx], idx+1, iq_res[idx+1]); | ||
794 | } | ||
795 | |||
796 | if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, | ||
797 | coeff.iqc_coeff)) { | ||
798 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
799 | "Failed in calculation of IQ correction.\n"); | ||
800 | goto TX_IQ_CAL_FAILED; | ||
801 | } | ||
802 | coeff.mag_coeff[i][im][ip] = | ||
803 | coeff.iqc_coeff[0] & 0x7f; | ||
804 | coeff.phs_coeff[i][im][ip] = | ||
805 | (coeff.iqc_coeff[0] >> 7) & 0x7f; | ||
806 | |||
807 | if (coeff.mag_coeff[i][im][ip] > 63) | ||
808 | coeff.mag_coeff[i][im][ip] -= 128; | ||
809 | if (coeff.phs_coeff[i][im][ip] > 63) | ||
810 | coeff.phs_coeff[i][im][ip] -= 128; | ||
811 | |||
812 | } | ||
813 | } | ||
814 | } | ||
815 | |||
816 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff); | ||
817 | |||
818 | return; | ||
819 | |||
820 | TX_IQ_CAL_FAILED: | ||
821 | ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); | ||
822 | } | ||
823 | |||
824 | static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) | ||
825 | { | ||
826 | u8 tx_gain_forced; | 720 | u8 tx_gain_forced; |
827 | 721 | ||
828 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485, | ||
829 | AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT); | ||
830 | tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN, | 722 | tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN, |
831 | AR_PHY_TXGAIN_FORCE); | 723 | AR_PHY_TXGAIN_FORCE); |
832 | if (tx_gain_forced) | 724 | if (tx_gain_forced) |
833 | REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, | 725 | REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, |
834 | AR_PHY_TXGAIN_FORCE, 0); | 726 | AR_PHY_TXGAIN_FORCE, 0); |
835 | 727 | ||
836 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485, | 728 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, |
837 | AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1); | 729 | AR_PHY_TX_IQCAL_START_DO_CAL, 1); |
730 | |||
731 | if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, | ||
732 | AR_PHY_TX_IQCAL_START_DO_CAL, 0, | ||
733 | AH_WAIT_TIMEOUT)) { | ||
734 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
735 | "Tx IQ Cal is not completed.\n"); | ||
736 | return false; | ||
737 | } | ||
738 | return true; | ||
838 | } | 739 | } |
839 | 740 | ||
840 | static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) | 741 | static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) |
841 | { | 742 | { |
842 | struct ath_common *common = ath9k_hw_common(ah); | 743 | struct ath_common *common = ath9k_hw_common(ah); |
843 | const u32 txiqcal_status[AR9300_MAX_CHAINS] = { | 744 | const u32 txiqcal_status[AR9300_MAX_CHAINS] = { |
844 | AR_PHY_TX_IQCAL_STATUS_B0_9485, | 745 | AR_PHY_TX_IQCAL_STATUS_B0, |
845 | AR_PHY_TX_IQCAL_STATUS_B1, | 746 | AR_PHY_TX_IQCAL_STATUS_B1, |
846 | AR_PHY_TX_IQCAL_STATUS_B2, | 747 | AR_PHY_TX_IQCAL_STATUS_B2, |
847 | }; | 748 | }; |
@@ -853,7 +754,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) | |||
853 | struct coeff coeff; | 754 | struct coeff coeff; |
854 | s32 iq_res[6]; | 755 | s32 iq_res[6]; |
855 | u8 num_chains = 0; | 756 | u8 num_chains = 0; |
856 | int i, ip, im, j; | 757 | int i, im, j; |
857 | int nmeasurement; | 758 | int nmeasurement; |
858 | 759 | ||
859 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 760 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
@@ -861,71 +762,69 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) | |||
861 | num_chains++; | 762 | num_chains++; |
862 | } | 763 | } |
863 | 764 | ||
864 | for (ip = 0; ip < MPASS; ip++) { | 765 | for (i = 0; i < num_chains; i++) { |
865 | for (i = 0; i < num_chains; i++) { | 766 | nmeasurement = REG_READ_FIELD(ah, |
866 | nmeasurement = REG_READ_FIELD(ah, | 767 | AR_PHY_TX_IQCAL_STATUS_B0, |
867 | AR_PHY_TX_IQCAL_STATUS_B0_9485, | 768 | AR_PHY_CALIBRATED_GAINS_0); |
868 | AR_PHY_CALIBRATED_GAINS_0); | 769 | if (nmeasurement > MAX_MEASUREMENT) |
869 | if (nmeasurement > MAX_MEASUREMENT) | 770 | nmeasurement = MAX_MEASUREMENT; |
870 | nmeasurement = MAX_MEASUREMENT; | ||
871 | 771 | ||
872 | for (im = 0; im < nmeasurement; im++) { | 772 | for (im = 0; im < nmeasurement; im++) { |
873 | ath_dbg(common, ATH_DBG_CALIBRATE, | 773 | ath_dbg(common, ATH_DBG_CALIBRATE, |
874 | "Doing Tx IQ Cal for chain %d.\n", i); | 774 | "Doing Tx IQ Cal for chain %d.\n", i); |
875 | 775 | ||
876 | if (REG_READ(ah, txiqcal_status[i]) & | 776 | if (REG_READ(ah, txiqcal_status[i]) & |
877 | AR_PHY_TX_IQCAL_STATUS_FAILED) { | 777 | AR_PHY_TX_IQCAL_STATUS_FAILED) { |
878 | ath_dbg(common, ATH_DBG_CALIBRATE, | 778 | ath_dbg(common, ATH_DBG_CALIBRATE, |
879 | "Tx IQ Cal failed for chain %d.\n", i); | 779 | "Tx IQ Cal failed for chain %d.\n", i); |
880 | goto tx_iqcal_fail; | 780 | goto tx_iqcal_fail; |
881 | } | 781 | } |
882 | 782 | ||
883 | for (j = 0; j < 3; j++) { | 783 | for (j = 0; j < 3; j++) { |
884 | u32 idx = 2 * j, offset = 4 * (3 * im + j); | 784 | u32 idx = 2 * j, offset = 4 * (3 * im + j); |
885 | 785 | ||
886 | REG_RMW_FIELD(ah, | 786 | REG_RMW_FIELD(ah, |
887 | AR_PHY_CHAN_INFO_MEMORY, | 787 | AR_PHY_CHAN_INFO_MEMORY, |
888 | AR_PHY_CHAN_INFO_TAB_S2_READ, | 788 | AR_PHY_CHAN_INFO_TAB_S2_READ, |
889 | 0); | 789 | 0); |
890 | 790 | ||
891 | /* 32 bits */ | 791 | /* 32 bits */ |
892 | iq_res[idx] = REG_READ(ah, | 792 | iq_res[idx] = REG_READ(ah, |
893 | chan_info_tab[i] + | 793 | chan_info_tab[i] + |
894 | offset); | 794 | offset); |
895 | 795 | ||
896 | REG_RMW_FIELD(ah, | 796 | REG_RMW_FIELD(ah, |
897 | AR_PHY_CHAN_INFO_MEMORY, | 797 | AR_PHY_CHAN_INFO_MEMORY, |
898 | AR_PHY_CHAN_INFO_TAB_S2_READ, | 798 | AR_PHY_CHAN_INFO_TAB_S2_READ, |
899 | 1); | 799 | 1); |
900 | 800 | ||
901 | /* 16 bits */ | 801 | /* 16 bits */ |
902 | iq_res[idx + 1] = 0xffff & REG_READ(ah, | 802 | iq_res[idx + 1] = 0xffff & REG_READ(ah, |
903 | chan_info_tab[i] + offset); | 803 | chan_info_tab[i] + offset); |
904 | 804 | ||
905 | ath_dbg(common, ATH_DBG_CALIBRATE, | 805 | ath_dbg(common, ATH_DBG_CALIBRATE, |
906 | "IQ RES[%d]=0x%x" | 806 | "IQ RES[%d]=0x%x" |
907 | "IQ_RES[%d]=0x%x\n", | 807 | "IQ_RES[%d]=0x%x\n", |
908 | idx, iq_res[idx], idx + 1, | 808 | idx, iq_res[idx], idx + 1, |
909 | iq_res[idx + 1]); | 809 | iq_res[idx + 1]); |
910 | } | 810 | } |
911 | 811 | ||
912 | if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, | 812 | if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, |
913 | coeff.iqc_coeff)) { | 813 | coeff.iqc_coeff)) { |
914 | ath_dbg(common, ATH_DBG_CALIBRATE, | 814 | ath_dbg(common, ATH_DBG_CALIBRATE, |
915 | "Failed in calculation of IQ correction.\n"); | 815 | "Failed in calculation of \ |
916 | goto tx_iqcal_fail; | 816 | IQ correction.\n"); |
917 | } | 817 | goto tx_iqcal_fail; |
818 | } | ||
918 | 819 | ||
919 | coeff.mag_coeff[i][im][ip] = | 820 | coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f; |
920 | coeff.iqc_coeff[0] & 0x7f; | 821 | coeff.phs_coeff[i][im] = |
921 | coeff.phs_coeff[i][im][ip] = | 822 | (coeff.iqc_coeff[0] >> 7) & 0x7f; |
922 | (coeff.iqc_coeff[0] >> 7) & 0x7f; | ||
923 | 823 | ||
924 | if (coeff.mag_coeff[i][im][ip] > 63) | 824 | if (coeff.mag_coeff[i][im] > 63) |
925 | coeff.mag_coeff[i][im][ip] -= 128; | 825 | coeff.mag_coeff[i][im] -= 128; |
926 | if (coeff.phs_coeff[i][im][ip] > 63) | 826 | if (coeff.phs_coeff[i][im] > 63) |
927 | coeff.phs_coeff[i][im][ip] -= 128; | 827 | coeff.phs_coeff[i][im] -= 128; |
928 | } | ||
929 | } | 828 | } |
930 | } | 829 | } |
931 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff); | 830 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff); |
@@ -940,31 +839,37 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
940 | struct ath9k_channel *chan) | 839 | struct ath9k_channel *chan) |
941 | { | 840 | { |
942 | struct ath_common *common = ath9k_hw_common(ah); | 841 | struct ath_common *common = ath9k_hw_common(ah); |
842 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
943 | int val; | 843 | int val; |
844 | bool txiqcal_done = false; | ||
944 | 845 | ||
945 | val = REG_READ(ah, AR_ENT_OTP); | 846 | val = REG_READ(ah, AR_ENT_OTP); |
946 | ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); | 847 | ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); |
947 | 848 | ||
948 | if (AR_SREV_9485(ah)) | 849 | /* Configure rx/tx chains before running AGC/TxiQ cals */ |
949 | ar9003_hw_set_chain_masks(ah, 0x1, 0x1); | 850 | if (val & AR_ENT_OTP_CHAIN2_DISABLE) |
950 | else if (val & AR_ENT_OTP_CHAIN2_DISABLE) | ||
951 | ar9003_hw_set_chain_masks(ah, 0x3, 0x3); | 851 | ar9003_hw_set_chain_masks(ah, 0x3, 0x3); |
952 | else | 852 | else |
953 | /* | 853 | ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask, |
954 | * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain | 854 | pCap->tx_chainmask); |
955 | * mode before running AGC/TxIQ cals | ||
956 | */ | ||
957 | ar9003_hw_set_chain_masks(ah, 0x7, 0x7); | ||
958 | 855 | ||
959 | /* Do Tx IQ Calibration */ | 856 | /* Do Tx IQ Calibration */ |
960 | if (AR_SREV_9485(ah)) | 857 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, |
961 | ar9003_hw_tx_iq_cal_run(ah); | 858 | AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, |
962 | else | 859 | DELPT); |
963 | ar9003_hw_tx_iq_cal(ah); | ||
964 | 860 | ||
965 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | 861 | /* |
966 | udelay(5); | 862 | * For AR9485 or later chips, TxIQ cal runs as part of |
967 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | 863 | * AGC calibration |
864 | */ | ||
865 | if (AR_SREV_9485_OR_LATER(ah)) | ||
866 | txiqcal_done = true; | ||
867 | else { | ||
868 | txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); | ||
869 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | ||
870 | udelay(5); | ||
871 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
872 | } | ||
968 | 873 | ||
969 | /* Calibrate the AGC */ | 874 | /* Calibrate the AGC */ |
970 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | 875 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, |
@@ -979,7 +884,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
979 | return false; | 884 | return false; |
980 | } | 885 | } |
981 | 886 | ||
982 | if (AR_SREV_9485(ah)) | 887 | if (txiqcal_done) |
983 | ar9003_hw_tx_iq_cal_post_proc(ah); | 888 | ar9003_hw_tx_iq_cal_post_proc(ah); |
984 | 889 | ||
985 | /* Revert chainmasks to their original values before NF cal */ | 890 | /* Revert chainmasks to their original values before NF cal */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 6eadf975ae48..fb892e5d141a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -3217,7 +3217,6 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
3217 | u8 *word, int length, int mdata_size) | 3217 | u8 *word, int length, int mdata_size) |
3218 | { | 3218 | { |
3219 | struct ath_common *common = ath9k_hw_common(ah); | 3219 | struct ath_common *common = ath9k_hw_common(ah); |
3220 | u8 *dptr; | ||
3221 | const struct ar9300_eeprom *eep = NULL; | 3220 | const struct ar9300_eeprom *eep = NULL; |
3222 | 3221 | ||
3223 | switch (code) { | 3222 | switch (code) { |
@@ -3235,7 +3234,6 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
3235 | break; | 3234 | break; |
3236 | case _CompressBlock: | 3235 | case _CompressBlock: |
3237 | if (reference == 0) { | 3236 | if (reference == 0) { |
3238 | dptr = mptr; | ||
3239 | } else { | 3237 | } else { |
3240 | eep = ar9003_eeprom_struct_find_by_id(reference); | 3238 | eep = ar9003_eeprom_struct_find_by_id(reference); |
3241 | if (eep == NULL) { | 3239 | if (eep == NULL) { |
@@ -3448,9 +3446,13 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) | |||
3448 | REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); | 3446 | REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); |
3449 | else { | 3447 | else { |
3450 | REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); | 3448 | REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); |
3451 | REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, | 3449 | if (!AR_SREV_9340(ah)) { |
3452 | bias >> 2); | 3450 | REG_RMW_FIELD(ah, AR_CH0_THERM, |
3453 | REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1); | 3451 | AR_CH0_THERM_XPABIASLVL_MSB, |
3452 | bias >> 2); | ||
3453 | REG_RMW_FIELD(ah, AR_CH0_THERM, | ||
3454 | AR_CH0_THERM_XPASHORT2GND, 1); | ||
3455 | } | ||
3454 | } | 3456 | } |
3455 | } | 3457 | } |
3456 | 3458 | ||
@@ -3497,23 +3499,28 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, | |||
3497 | 3499 | ||
3498 | static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | 3500 | static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) |
3499 | { | 3501 | { |
3502 | int chain; | ||
3503 | static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = { | ||
3504 | AR_PHY_SWITCH_CHAIN_0, | ||
3505 | AR_PHY_SWITCH_CHAIN_1, | ||
3506 | AR_PHY_SWITCH_CHAIN_2, | ||
3507 | }; | ||
3508 | |||
3500 | u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); | 3509 | u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); |
3510 | |||
3501 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); | 3511 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); |
3502 | 3512 | ||
3503 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); | 3513 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); |
3504 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); | 3514 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); |
3505 | 3515 | ||
3506 | value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz); | 3516 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
3507 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); | 3517 | if ((ah->rxchainmask & BIT(chain)) || |
3508 | 3518 | (ah->txchainmask & BIT(chain))) { | |
3509 | if (!AR_SREV_9485(ah)) { | 3519 | value = ar9003_hw_ant_ctrl_chain_get(ah, chain, |
3510 | value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); | 3520 | is2ghz); |
3511 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, | 3521 | REG_RMW_FIELD(ah, switch_chain_reg[chain], |
3512 | value); | 3522 | AR_SWITCH_TABLE_ALL, value); |
3513 | 3523 | } | |
3514 | value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz); | ||
3515 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, | ||
3516 | value); | ||
3517 | } | 3524 | } |
3518 | 3525 | ||
3519 | if (AR_SREV_9485(ah)) { | 3526 | if (AR_SREV_9485(ah)) { |
@@ -3634,13 +3641,16 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan) | |||
3634 | 3641 | ||
3635 | /* Test value. if 0 then attenuation is unused. Don't load anything. */ | 3642 | /* Test value. if 0 then attenuation is unused. Don't load anything. */ |
3636 | for (i = 0; i < 3; i++) { | 3643 | for (i = 0; i < 3; i++) { |
3637 | value = ar9003_hw_atten_chain_get(ah, i, chan); | 3644 | if (ah->txchainmask & BIT(i)) { |
3638 | REG_RMW_FIELD(ah, ext_atten_reg[i], | 3645 | value = ar9003_hw_atten_chain_get(ah, i, chan); |
3639 | AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); | 3646 | REG_RMW_FIELD(ah, ext_atten_reg[i], |
3640 | 3647 | AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); | |
3641 | value = ar9003_hw_atten_chain_get_margin(ah, i, chan); | 3648 | |
3642 | REG_RMW_FIELD(ah, ext_atten_reg[i], | 3649 | value = ar9003_hw_atten_chain_get_margin(ah, i, chan); |
3643 | AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); | 3650 | REG_RMW_FIELD(ah, ext_atten_reg[i], |
3651 | AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, | ||
3652 | value); | ||
3653 | } | ||
3644 | } | 3654 | } |
3645 | } | 3655 | } |
3646 | 3656 | ||
@@ -3749,8 +3759,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | |||
3749 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); | 3759 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); |
3750 | ar9003_hw_drive_strength_apply(ah); | 3760 | ar9003_hw_drive_strength_apply(ah); |
3751 | ar9003_hw_atten_apply(ah, chan); | 3761 | ar9003_hw_atten_apply(ah, chan); |
3752 | ar9003_hw_internal_regulator_apply(ah); | 3762 | if (!AR_SREV_9340(ah)) |
3753 | if (AR_SREV_9485(ah)) | 3763 | ar9003_hw_internal_regulator_apply(ah); |
3764 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | ||
3754 | ar9003_hw_apply_tuning_caps(ah); | 3765 | ar9003_hw_apply_tuning_caps(ah); |
3755 | } | 3766 | } |
3756 | 3767 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index aebaad97b190..a55eddbb2589 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "ar9003_mac.h" | 18 | #include "ar9003_mac.h" |
19 | #include "ar9003_2p2_initvals.h" | 19 | #include "ar9003_2p2_initvals.h" |
20 | #include "ar9485_initvals.h" | 20 | #include "ar9485_initvals.h" |
21 | #include "ar9340_initvals.h" | ||
21 | 22 | ||
22 | /* General hardware code for the AR9003 hadware family */ | 23 | /* General hardware code for the AR9003 hadware family */ |
23 | 24 | ||
@@ -28,7 +29,63 @@ | |||
28 | */ | 29 | */ |
29 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | 30 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) |
30 | { | 31 | { |
31 | if (AR_SREV_9485_11(ah)) { | 32 | if (AR_SREV_9340(ah)) { |
33 | /* mac */ | ||
34 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
35 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | ||
36 | ar9340_1p0_mac_core, | ||
37 | ARRAY_SIZE(ar9340_1p0_mac_core), 2); | ||
38 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | ||
39 | ar9340_1p0_mac_postamble, | ||
40 | ARRAY_SIZE(ar9340_1p0_mac_postamble), 5); | ||
41 | |||
42 | /* bb */ | ||
43 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
44 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | ||
45 | ar9340_1p0_baseband_core, | ||
46 | ARRAY_SIZE(ar9340_1p0_baseband_core), 2); | ||
47 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | ||
48 | ar9340_1p0_baseband_postamble, | ||
49 | ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5); | ||
50 | |||
51 | /* radio */ | ||
52 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
53 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | ||
54 | ar9340_1p0_radio_core, | ||
55 | ARRAY_SIZE(ar9340_1p0_radio_core), 2); | ||
56 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | ||
57 | ar9340_1p0_radio_postamble, | ||
58 | ARRAY_SIZE(ar9340_1p0_radio_postamble), 5); | ||
59 | |||
60 | /* soc */ | ||
61 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | ||
62 | ar9340_1p0_soc_preamble, | ||
63 | ARRAY_SIZE(ar9340_1p0_soc_preamble), 2); | ||
64 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
65 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | ||
66 | ar9340_1p0_soc_postamble, | ||
67 | ARRAY_SIZE(ar9340_1p0_soc_postamble), 5); | ||
68 | |||
69 | /* rx/tx gain */ | ||
70 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
71 | ar9340Common_wo_xlna_rx_gain_table_1p0, | ||
72 | ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), | ||
73 | 5); | ||
74 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
75 | ar9340Modes_high_ob_db_tx_gain_table_1p0, | ||
76 | ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0), | ||
77 | 5); | ||
78 | |||
79 | INIT_INI_ARRAY(&ah->iniModesAdditional, | ||
80 | ar9340Modes_fast_clock_1p0, | ||
81 | ARRAY_SIZE(ar9340Modes_fast_clock_1p0), | ||
82 | 3); | ||
83 | |||
84 | INIT_INI_ARRAY(&ah->iniModesAdditional_40M, | ||
85 | ar9340_1p0_radio_core_40M, | ||
86 | ARRAY_SIZE(ar9340_1p0_radio_core_40M), | ||
87 | 2); | ||
88 | } else if (AR_SREV_9485_11(ah)) { | ||
32 | /* mac */ | 89 | /* mac */ |
33 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | 90 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); |
34 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 91 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
@@ -163,7 +220,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
163 | switch (ar9003_hw_get_tx_gain_idx(ah)) { | 220 | switch (ar9003_hw_get_tx_gain_idx(ah)) { |
164 | case 0: | 221 | case 0: |
165 | default: | 222 | default: |
166 | if (AR_SREV_9485_11(ah)) | 223 | if (AR_SREV_9340(ah)) |
224 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
225 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | ||
226 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||
227 | 5); | ||
228 | else if (AR_SREV_9485_11(ah)) | ||
167 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 229 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
168 | ar9485_modes_lowest_ob_db_tx_gain_1_1, | 230 | ar9485_modes_lowest_ob_db_tx_gain_1_1, |
169 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), | 231 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), |
@@ -175,7 +237,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
175 | 5); | 237 | 5); |
176 | break; | 238 | break; |
177 | case 1: | 239 | case 1: |
178 | if (AR_SREV_9485_11(ah)) | 240 | if (AR_SREV_9340(ah)) |
241 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
242 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | ||
243 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||
244 | 5); | ||
245 | else if (AR_SREV_9485_11(ah)) | ||
179 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 246 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
180 | ar9485Modes_high_ob_db_tx_gain_1_1, | 247 | ar9485Modes_high_ob_db_tx_gain_1_1, |
181 | ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), | 248 | ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), |
@@ -187,7 +254,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
187 | 5); | 254 | 5); |
188 | break; | 255 | break; |
189 | case 2: | 256 | case 2: |
190 | if (AR_SREV_9485_11(ah)) | 257 | if (AR_SREV_9340(ah)) |
258 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
259 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | ||
260 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||
261 | 5); | ||
262 | else if (AR_SREV_9485_11(ah)) | ||
191 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 263 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
192 | ar9485Modes_low_ob_db_tx_gain_1_1, | 264 | ar9485Modes_low_ob_db_tx_gain_1_1, |
193 | ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), | 265 | ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), |
@@ -199,7 +271,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
199 | 5); | 271 | 5); |
200 | break; | 272 | break; |
201 | case 3: | 273 | case 3: |
202 | if (AR_SREV_9485_11(ah)) | 274 | if (AR_SREV_9340(ah)) |
275 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
276 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | ||
277 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||
278 | 5); | ||
279 | else if (AR_SREV_9485_11(ah)) | ||
203 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 280 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
204 | ar9485Modes_high_power_tx_gain_1_1, | 281 | ar9485Modes_high_power_tx_gain_1_1, |
205 | ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), | 282 | ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), |
@@ -218,7 +295,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
218 | switch (ar9003_hw_get_rx_gain_idx(ah)) { | 295 | switch (ar9003_hw_get_rx_gain_idx(ah)) { |
219 | case 0: | 296 | case 0: |
220 | default: | 297 | default: |
221 | if (AR_SREV_9485_11(ah)) | 298 | if (AR_SREV_9340(ah)) |
299 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
300 | ar9340Common_rx_gain_table_1p0, | ||
301 | ARRAY_SIZE(ar9340Common_rx_gain_table_1p0), | ||
302 | 2); | ||
303 | else if (AR_SREV_9485_11(ah)) | ||
222 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 304 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
223 | ar9485Common_wo_xlna_rx_gain_1_1, | 305 | ar9485Common_wo_xlna_rx_gain_1_1, |
224 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), | 306 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), |
@@ -230,7 +312,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
230 | 2); | 312 | 2); |
231 | break; | 313 | break; |
232 | case 1: | 314 | case 1: |
233 | if (AR_SREV_9485_11(ah)) | 315 | if (AR_SREV_9340(ah)) |
316 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
317 | ar9340Common_wo_xlna_rx_gain_table_1p0, | ||
318 | ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), | ||
319 | 2); | ||
320 | else if (AR_SREV_9485_11(ah)) | ||
234 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 321 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
235 | ar9485Common_wo_xlna_rx_gain_1_1, | 322 | ar9485Common_wo_xlna_rx_gain_1_1, |
236 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), | 323 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 1bc33f51e466..c83be2dd5718 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -86,14 +86,31 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
86 | channelSel = (freq * 4) / 120; | 86 | channelSel = (freq * 4) / 120; |
87 | chan_frac = (((freq * 4) % 120) * 0x20000) / 120; | 87 | chan_frac = (((freq * 4) % 120) * 0x20000) / 120; |
88 | channelSel = (channelSel << 17) | chan_frac; | 88 | channelSel = (channelSel << 17) | chan_frac; |
89 | } else if (AR_SREV_9340(ah)) { | ||
90 | if (ah->is_clk_25mhz) { | ||
91 | u32 chan_frac; | ||
92 | |||
93 | channelSel = (freq * 2) / 75; | ||
94 | chan_frac = (((freq * 2) % 75) * 0x20000) / 75; | ||
95 | channelSel = (channelSel << 17) | chan_frac; | ||
96 | } else | ||
97 | channelSel = CHANSEL_2G(freq) >> 1; | ||
89 | } else | 98 | } else |
90 | channelSel = CHANSEL_2G(freq); | 99 | channelSel = CHANSEL_2G(freq); |
91 | /* Set to 2G mode */ | 100 | /* Set to 2G mode */ |
92 | bMode = 1; | 101 | bMode = 1; |
93 | } else { | 102 | } else { |
94 | channelSel = CHANSEL_5G(freq); | 103 | if (AR_SREV_9340(ah) && ah->is_clk_25mhz) { |
95 | /* Doubler is ON, so, divide channelSel by 2. */ | 104 | u32 chan_frac; |
96 | channelSel >>= 1; | 105 | |
106 | channelSel = (freq * 2) / 75; | ||
107 | chan_frac = ((freq % 75) * 0x20000) / 75; | ||
108 | channelSel = (channelSel << 17) | chan_frac; | ||
109 | } else { | ||
110 | channelSel = CHANSEL_5G(freq); | ||
111 | /* Doubler is ON, so, divide channelSel by 2. */ | ||
112 | channelSel >>= 1; | ||
113 | } | ||
97 | /* Set to 5G mode */ | 114 | /* Set to 5G mode */ |
98 | bMode = 0; | 115 | bMode = 0; |
99 | } | 116 | } |
@@ -151,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
151 | * is out-of-band and can be ignored. | 168 | * is out-of-band and can be ignored. |
152 | */ | 169 | */ |
153 | 170 | ||
154 | if (AR_SREV_9485(ah)) { | 171 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) { |
155 | spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, | 172 | spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, |
156 | IS_CHAN_2GHZ(chan)); | 173 | IS_CHAN_2GHZ(chan)); |
157 | if (spur_fbin_ptr[0] == 0) /* No spur */ | 174 | if (spur_fbin_ptr[0] == 0) /* No spur */ |
@@ -176,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
176 | 193 | ||
177 | for (i = 0; i < max_spur_cnts; i++) { | 194 | for (i = 0; i < max_spur_cnts; i++) { |
178 | negative = 0; | 195 | negative = 0; |
179 | if (AR_SREV_9485(ah)) | 196 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) |
180 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], | 197 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], |
181 | IS_CHAN_2GHZ(chan)) - synth_freq; | 198 | IS_CHAN_2GHZ(chan)) - synth_freq; |
182 | else | 199 | else |
@@ -599,29 +616,25 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
599 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | 616 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
600 | unsigned int regWrites = 0, i; | 617 | unsigned int regWrites = 0, i; |
601 | struct ieee80211_channel *channel = chan->chan; | 618 | struct ieee80211_channel *channel = chan->chan; |
602 | u32 modesIndex, freqIndex; | 619 | u32 modesIndex; |
603 | 620 | ||
604 | switch (chan->chanmode) { | 621 | switch (chan->chanmode) { |
605 | case CHANNEL_A: | 622 | case CHANNEL_A: |
606 | case CHANNEL_A_HT20: | 623 | case CHANNEL_A_HT20: |
607 | modesIndex = 1; | 624 | modesIndex = 1; |
608 | freqIndex = 1; | ||
609 | break; | 625 | break; |
610 | case CHANNEL_A_HT40PLUS: | 626 | case CHANNEL_A_HT40PLUS: |
611 | case CHANNEL_A_HT40MINUS: | 627 | case CHANNEL_A_HT40MINUS: |
612 | modesIndex = 2; | 628 | modesIndex = 2; |
613 | freqIndex = 1; | ||
614 | break; | 629 | break; |
615 | case CHANNEL_G: | 630 | case CHANNEL_G: |
616 | case CHANNEL_G_HT20: | 631 | case CHANNEL_G_HT20: |
617 | case CHANNEL_B: | 632 | case CHANNEL_B: |
618 | modesIndex = 4; | 633 | modesIndex = 4; |
619 | freqIndex = 2; | ||
620 | break; | 634 | break; |
621 | case CHANNEL_G_HT40PLUS: | 635 | case CHANNEL_G_HT40PLUS: |
622 | case CHANNEL_G_HT40MINUS: | 636 | case CHANNEL_G_HT40MINUS: |
623 | modesIndex = 3; | 637 | modesIndex = 3; |
624 | freqIndex = 2; | ||
625 | break; | 638 | break; |
626 | 639 | ||
627 | default: | 640 | default: |
@@ -646,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
646 | REG_WRITE_ARRAY(&ah->iniModesAdditional, | 659 | REG_WRITE_ARRAY(&ah->iniModesAdditional, |
647 | modesIndex, regWrites); | 660 | modesIndex, regWrites); |
648 | 661 | ||
662 | if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) | ||
663 | REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); | ||
664 | |||
649 | ar9003_hw_override_ini(ah); | 665 | ar9003_hw_override_ini(ah); |
650 | ar9003_hw_set_channel_regs(ah, chan); | 666 | ar9003_hw_set_channel_regs(ah, chan); |
651 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | 667 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 8bdda2cf9dd7..2a0d5cbb7e76 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -548,15 +548,12 @@ | |||
548 | 548 | ||
549 | #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) | 549 | #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) |
550 | 550 | ||
551 | #define AR_PHY_TX_IQCAL_START_9485 (AR_SM_BASE + 0x3c4) | 551 | #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \ |
552 | #define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000 | 552 | 0x3c8 : 0x448) |
553 | #define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31 | 553 | #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \ |
554 | #define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8) | 554 | 0x3c4 : 0x440) |
555 | #define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0) | 555 | #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \ |
556 | 556 | 0x3f0 : 0x48c) | |
557 | #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448) | ||
558 | #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440) | ||
559 | #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) | ||
560 | #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \ | 557 | #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \ |
561 | (AR_SREV_9485(ah) ? \ | 558 | (AR_SREV_9485(ah) ? \ |
562 | 0x3d0 : 0x450) + ((_i) << 2)) | 559 | 0x3d0 : 0x450) + ((_i) << 2)) |
@@ -588,7 +585,7 @@ | |||
588 | #define AR_PHY_65NM_CH0_BIAS2 0x160c4 | 585 | #define AR_PHY_65NM_CH0_BIAS2 0x160c4 |
589 | #define AR_PHY_65NM_CH0_BIAS4 0x160cc | 586 | #define AR_PHY_65NM_CH0_BIAS4 0x160cc |
590 | #define AR_PHY_65NM_CH0_RXTX4 0x1610c | 587 | #define AR_PHY_65NM_CH0_RXTX4 0x1610c |
591 | #define AR_PHY_65NM_CH0_THERM (AR_SREV_9485(ah) ? 0x1628c : 0x16290) | 588 | #define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : 0x1628c) |
592 | 589 | ||
593 | #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 | 590 | #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 |
594 | #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 | 591 | #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 |
@@ -758,10 +755,10 @@ | |||
758 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 | 755 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 |
759 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 | 756 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 |
760 | #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 | 757 | #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 |
761 | #define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000 | 758 | #define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000 |
762 | #define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18 | 759 | #define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18 |
763 | #define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001 | 760 | #define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001 |
764 | #define AR_PHY_TX_IQCAL_START_DO_CAL_S 0 | 761 | #define AR_PHY_TX_IQCAL_START_DO_CAL_S 0 |
765 | 762 | ||
766 | #define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001 | 763 | #define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001 |
767 | #define AR_PHY_CALIBRATED_GAINS_0 0x3e | 764 | #define AR_PHY_CALIBRATED_GAINS_0 0x3e |
diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h new file mode 100644 index 000000000000..815a8af1beef --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h | |||
@@ -0,0 +1,1525 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef INITVALS_9340_H | ||
18 | #define INITVALS_9340_H | ||
19 | |||
20 | static const u32 ar9340_1p0_radio_postamble[][5] = { | ||
21 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
22 | {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800}, | ||
23 | {0x0001610c, 0x08000000, 0x08000000, 0x00000000, 0x00000000}, | ||
24 | {0x00016140, 0x10804000, 0x10804000, 0x50804000, 0x50804000}, | ||
25 | {0x0001650c, 0x08000000, 0x08000000, 0x00000000, 0x00000000}, | ||
26 | {0x00016540, 0x10804000, 0x10804000, 0x50804000, 0x50804000}, | ||
27 | }; | ||
28 | |||
29 | static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = { | ||
30 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
31 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
32 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
33 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
34 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
35 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
36 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
37 | {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, | ||
38 | {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, | ||
39 | {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, | ||
40 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, | ||
41 | {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, | ||
42 | {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, | ||
43 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, | ||
44 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, | ||
45 | {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, | ||
46 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | ||
47 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | ||
48 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | ||
49 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | ||
50 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | ||
51 | {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, | ||
52 | {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, | ||
53 | {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, | ||
54 | {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, | ||
55 | {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, | ||
56 | {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, | ||
57 | {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
58 | {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
59 | {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
60 | {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
61 | {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
62 | {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
63 | {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
64 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
65 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | ||
66 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | ||
67 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | ||
68 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, | ||
69 | {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, | ||
70 | {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, | ||
71 | {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, | ||
72 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, | ||
73 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, | ||
74 | {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, | ||
75 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, | ||
76 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, | ||
77 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, | ||
78 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, | ||
79 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, | ||
80 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, | ||
81 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, | ||
82 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, | ||
83 | {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, | ||
84 | {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, | ||
85 | {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, | ||
86 | {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, | ||
87 | {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, | ||
88 | {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, | ||
89 | {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
90 | {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
91 | {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
92 | {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
93 | {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
94 | {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
95 | {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
96 | {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
97 | {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
98 | {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
99 | {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
100 | }; | ||
101 | |||
102 | static const u32 ar9340Modes_fast_clock_1p0[][3] = { | ||
103 | /* Addr 5G_HT20 5G_HT40 */ | ||
104 | {0x00001030, 0x00000268, 0x000004d0}, | ||
105 | {0x00001070, 0x0000018c, 0x00000318}, | ||
106 | {0x000010b0, 0x00000fd0, 0x00001fa0}, | ||
107 | {0x00008014, 0x044c044c, 0x08980898}, | ||
108 | {0x0000801c, 0x148ec02b, 0x148ec057}, | ||
109 | {0x00008318, 0x000044c0, 0x00008980}, | ||
110 | {0x00009e00, 0x03721821, 0x03721821}, | ||
111 | {0x0000a230, 0x0000000b, 0x00000016}, | ||
112 | {0x0000a254, 0x00000898, 0x00001130}, | ||
113 | }; | ||
114 | |||
115 | static const u32 ar9340_1p0_radio_core[][2] = { | ||
116 | /* Addr allmodes */ | ||
117 | {0x00016000, 0x36db6db6}, | ||
118 | {0x00016004, 0x6db6db40}, | ||
119 | {0x00016008, 0x73f00000}, | ||
120 | {0x0001600c, 0x00000000}, | ||
121 | {0x00016040, 0x7f80fff8}, | ||
122 | {0x00016044, 0x03b6d2db}, | ||
123 | {0x00016048, 0x24925266}, | ||
124 | {0x0001604c, 0x000f0278}, | ||
125 | {0x00016050, 0x6db6db6c}, | ||
126 | {0x00016054, 0x6db60000}, | ||
127 | {0x00016080, 0x00080000}, | ||
128 | {0x00016084, 0x0e48048c}, | ||
129 | {0x00016088, 0x14214514}, | ||
130 | {0x0001608c, 0x119f081c}, | ||
131 | {0x00016090, 0x24926490}, | ||
132 | {0x00016094, 0x00000000}, | ||
133 | {0x00016098, 0xd411eb84}, | ||
134 | {0x0001609c, 0x03e47f32}, | ||
135 | {0x000160a0, 0xc2108ffe}, | ||
136 | {0x000160a4, 0x812fc370}, | ||
137 | {0x000160a8, 0x423c8000}, | ||
138 | {0x000160ac, 0xa4646800}, | ||
139 | {0x000160b0, 0x00fe7f46}, | ||
140 | {0x000160b4, 0x92480000}, | ||
141 | {0x000160c0, 0x006db6db}, | ||
142 | {0x000160c4, 0x6db6db60}, | ||
143 | {0x000160c8, 0x6db6db6c}, | ||
144 | {0x000160cc, 0x6de6db6c}, | ||
145 | {0x000160d0, 0xb6da4924}, | ||
146 | {0x00016100, 0x04cb0001}, | ||
147 | {0x00016104, 0xfff80000}, | ||
148 | {0x00016108, 0x00080010}, | ||
149 | {0x0001610c, 0x00000000}, | ||
150 | {0x00016140, 0x50804008}, | ||
151 | {0x00016144, 0x01884080}, | ||
152 | {0x00016148, 0x000080c0}, | ||
153 | {0x00016280, 0x01000015}, | ||
154 | {0x00016284, 0x05530000}, | ||
155 | {0x00016288, 0x00318000}, | ||
156 | {0x0001628c, 0x50000000}, | ||
157 | {0x00016290, 0x4080294f}, | ||
158 | {0x00016380, 0x00000000}, | ||
159 | {0x00016384, 0x00000000}, | ||
160 | {0x00016388, 0x00800700}, | ||
161 | {0x0001638c, 0x00800700}, | ||
162 | {0x00016390, 0x00800700}, | ||
163 | {0x00016394, 0x00000000}, | ||
164 | {0x00016398, 0x00000000}, | ||
165 | {0x0001639c, 0x00000000}, | ||
166 | {0x000163a0, 0x00000001}, | ||
167 | {0x000163a4, 0x00000001}, | ||
168 | {0x000163a8, 0x00000000}, | ||
169 | {0x000163ac, 0x00000000}, | ||
170 | {0x000163b0, 0x00000000}, | ||
171 | {0x000163b4, 0x00000000}, | ||
172 | {0x000163b8, 0x00000000}, | ||
173 | {0x000163bc, 0x00000000}, | ||
174 | {0x000163c0, 0x000000a0}, | ||
175 | {0x000163c4, 0x000c0000}, | ||
176 | {0x000163c8, 0x14021402}, | ||
177 | {0x000163cc, 0x00001402}, | ||
178 | {0x000163d0, 0x00000000}, | ||
179 | {0x000163d4, 0x00000000}, | ||
180 | {0x00016400, 0x36db6db6}, | ||
181 | {0x00016404, 0x6db6db40}, | ||
182 | {0x00016408, 0x73f00000}, | ||
183 | {0x0001640c, 0x00000000}, | ||
184 | {0x00016440, 0x7f80fff8}, | ||
185 | {0x00016444, 0x03b6d2db}, | ||
186 | {0x00016448, 0x24927266}, | ||
187 | {0x0001644c, 0x000f0278}, | ||
188 | {0x00016450, 0x6db6db6c}, | ||
189 | {0x00016454, 0x6db60000}, | ||
190 | {0x00016500, 0x04cb0001}, | ||
191 | {0x00016504, 0xfff80000}, | ||
192 | {0x00016508, 0x00080010}, | ||
193 | {0x0001650c, 0x00000000}, | ||
194 | {0x00016540, 0x50804008}, | ||
195 | {0x00016544, 0x01884080}, | ||
196 | {0x00016548, 0x000080c0}, | ||
197 | {0x00016780, 0x00000000}, | ||
198 | {0x00016784, 0x00000000}, | ||
199 | {0x00016788, 0x00800700}, | ||
200 | {0x0001678c, 0x00800700}, | ||
201 | {0x00016790, 0x00800700}, | ||
202 | {0x00016794, 0x00000000}, | ||
203 | {0x00016798, 0x00000000}, | ||
204 | {0x0001679c, 0x00000000}, | ||
205 | {0x000167a0, 0x00000001}, | ||
206 | {0x000167a4, 0x00000001}, | ||
207 | {0x000167a8, 0x00000000}, | ||
208 | {0x000167ac, 0x00000000}, | ||
209 | {0x000167b0, 0x00000000}, | ||
210 | {0x000167b4, 0x00000000}, | ||
211 | {0x000167b8, 0x00000000}, | ||
212 | {0x000167bc, 0x00000000}, | ||
213 | {0x000167c0, 0x000000a0}, | ||
214 | {0x000167c4, 0x000c0000}, | ||
215 | {0x000167c8, 0x14021402}, | ||
216 | {0x000167cc, 0x00001402}, | ||
217 | {0x000167d0, 0x00000000}, | ||
218 | {0x000167d4, 0x00000000}, | ||
219 | }; | ||
220 | |||
221 | static const u32 ar9340_1p0_radio_core_40M[][2] = { | ||
222 | {0x0001609c, 0x02566f3a}, | ||
223 | {0x000160ac, 0xa4647c00}, | ||
224 | {0x000160b0, 0x01885f5a}, | ||
225 | }; | ||
226 | |||
227 | static const u32 ar9340_1p0_mac_postamble[][5] = { | ||
228 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
229 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | ||
230 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, | ||
231 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, | ||
232 | {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, | ||
233 | {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, | ||
234 | {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, | ||
235 | {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, | ||
236 | {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, | ||
237 | }; | ||
238 | |||
239 | static const u32 ar9340_1p0_soc_postamble[][5] = { | ||
240 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
241 | {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, | ||
242 | }; | ||
243 | |||
244 | static const u32 ar9340_1p0_baseband_postamble[][5] = { | ||
245 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
246 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, | ||
247 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e}, | ||
248 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | ||
249 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | ||
250 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | ||
251 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, | ||
252 | {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044}, | ||
253 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, | ||
254 | {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, | ||
255 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | ||
256 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e}, | ||
257 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, | ||
258 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
259 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | ||
260 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | ||
261 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | ||
262 | {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, | ||
263 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, | ||
264 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | ||
265 | {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0}, | ||
266 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | ||
267 | {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, | ||
268 | {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, | ||
269 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | ||
270 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | ||
271 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | ||
272 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, | ||
273 | {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, | ||
274 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, | ||
275 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | ||
276 | {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, | ||
277 | {0x0000a288, 0x00000220, 0x00000220, 0x00000110, 0x00000110}, | ||
278 | {0x0000a28c, 0x00011111, 0x00011111, 0x00022222, 0x00022222}, | ||
279 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | ||
280 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, | ||
281 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, | ||
282 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
283 | {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
284 | {0x0000ae04, 0x00180000, 0x00180000, 0x00180000, 0x00180000}, | ||
285 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
286 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
287 | {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | ||
288 | {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, | ||
289 | }; | ||
290 | |||
291 | static const u32 ar9340_1p0_baseband_core[][2] = { | ||
292 | /* Addr allmodes */ | ||
293 | {0x00009800, 0xafe68e30}, | ||
294 | {0x00009804, 0xfd14e000}, | ||
295 | {0x00009808, 0x9c0a9f6b}, | ||
296 | {0x0000980c, 0x04900000}, | ||
297 | {0x00009814, 0xb280c00a}, | ||
298 | {0x00009818, 0x00000000}, | ||
299 | {0x0000981c, 0x00020028}, | ||
300 | {0x00009834, 0x5f3ca3de}, | ||
301 | {0x00009838, 0x0108ecff}, | ||
302 | {0x0000983c, 0x14750600}, | ||
303 | {0x00009880, 0x201fff00}, | ||
304 | {0x00009884, 0x00001042}, | ||
305 | {0x000098a4, 0x00200400}, | ||
306 | {0x000098b0, 0x52440bbe}, | ||
307 | {0x000098d0, 0x004b6a8e}, | ||
308 | {0x000098d4, 0x00000820}, | ||
309 | {0x000098dc, 0x00000000}, | ||
310 | {0x000098f0, 0x00000000}, | ||
311 | {0x000098f4, 0x00000000}, | ||
312 | {0x00009c04, 0xff55ff55}, | ||
313 | {0x00009c08, 0x0320ff55}, | ||
314 | {0x00009c0c, 0x00000000}, | ||
315 | {0x00009c10, 0x00000000}, | ||
316 | {0x00009c14, 0x00046384}, | ||
317 | {0x00009c18, 0x05b6b440}, | ||
318 | {0x00009c1c, 0x00b6b440}, | ||
319 | {0x00009d00, 0xc080a333}, | ||
320 | {0x00009d04, 0x40206c10}, | ||
321 | {0x00009d08, 0x009c4060}, | ||
322 | {0x00009d0c, 0x9883800a}, | ||
323 | {0x00009d10, 0x01834061}, | ||
324 | {0x00009d14, 0x00c0040b}, | ||
325 | {0x00009d18, 0x00000000}, | ||
326 | {0x00009e08, 0x0038230c}, | ||
327 | {0x00009e24, 0x990bb515}, | ||
328 | {0x00009e28, 0x0c6f0000}, | ||
329 | {0x00009e30, 0x06336f77}, | ||
330 | {0x00009e34, 0x6af6532f}, | ||
331 | {0x00009e38, 0x0cc80c00}, | ||
332 | {0x00009e3c, 0xcf946222}, | ||
333 | {0x00009e40, 0x0d261820}, | ||
334 | {0x00009e4c, 0x00001004}, | ||
335 | {0x00009e50, 0x00ff03f1}, | ||
336 | {0x00009e54, 0x00000000}, | ||
337 | {0x00009fc0, 0x803e4788}, | ||
338 | {0x00009fc4, 0x0001efb5}, | ||
339 | {0x00009fcc, 0x40000014}, | ||
340 | {0x00009fd0, 0x01193b93}, | ||
341 | {0x0000a20c, 0x00000000}, | ||
342 | {0x0000a220, 0x00000000}, | ||
343 | {0x0000a224, 0x00000000}, | ||
344 | {0x0000a228, 0x10002310}, | ||
345 | {0x0000a22c, 0x01036a1e}, | ||
346 | {0x0000a234, 0x10000fff}, | ||
347 | {0x0000a23c, 0x00000000}, | ||
348 | {0x0000a244, 0x0c000000}, | ||
349 | {0x0000a2a0, 0x00000001}, | ||
350 | {0x0000a2c0, 0x00000001}, | ||
351 | {0x0000a2c8, 0x00000000}, | ||
352 | {0x0000a2cc, 0x18c43433}, | ||
353 | {0x0000a2d4, 0x00000000}, | ||
354 | {0x0000a2dc, 0x00000000}, | ||
355 | {0x0000a2e0, 0x00000000}, | ||
356 | {0x0000a2e4, 0x00000000}, | ||
357 | {0x0000a2e8, 0x00000000}, | ||
358 | {0x0000a2ec, 0x00000000}, | ||
359 | {0x0000a2f0, 0x00000000}, | ||
360 | {0x0000a2f4, 0x00000000}, | ||
361 | {0x0000a2f8, 0x00000000}, | ||
362 | {0x0000a344, 0x00000000}, | ||
363 | {0x0000a34c, 0x00000000}, | ||
364 | {0x0000a350, 0x0000a000}, | ||
365 | {0x0000a364, 0x00000000}, | ||
366 | {0x0000a370, 0x00000000}, | ||
367 | {0x0000a390, 0x00000001}, | ||
368 | {0x0000a394, 0x00000444}, | ||
369 | {0x0000a398, 0x001f0e0f}, | ||
370 | {0x0000a39c, 0x0075393f}, | ||
371 | {0x0000a3a0, 0xb79f6427}, | ||
372 | {0x0000a3a4, 0x00000000}, | ||
373 | {0x0000a3a8, 0xaaaaaaaa}, | ||
374 | {0x0000a3ac, 0x3c466478}, | ||
375 | {0x0000a3c0, 0x20202020}, | ||
376 | {0x0000a3c4, 0x22222220}, | ||
377 | {0x0000a3c8, 0x20200020}, | ||
378 | {0x0000a3cc, 0x20202020}, | ||
379 | {0x0000a3d0, 0x20202020}, | ||
380 | {0x0000a3d4, 0x20202020}, | ||
381 | {0x0000a3d8, 0x20202020}, | ||
382 | {0x0000a3dc, 0x20202020}, | ||
383 | {0x0000a3e0, 0x20202020}, | ||
384 | {0x0000a3e4, 0x20202020}, | ||
385 | {0x0000a3e8, 0x20202020}, | ||
386 | {0x0000a3ec, 0x20202020}, | ||
387 | {0x0000a3f0, 0x00000000}, | ||
388 | {0x0000a3f4, 0x00000246}, | ||
389 | {0x0000a3f8, 0x0cdbd380}, | ||
390 | {0x0000a3fc, 0x000f0f01}, | ||
391 | {0x0000a400, 0x8fa91f01}, | ||
392 | {0x0000a404, 0x00000000}, | ||
393 | {0x0000a408, 0x0e79e5c6}, | ||
394 | {0x0000a40c, 0x00820820}, | ||
395 | {0x0000a414, 0x1ce739ce}, | ||
396 | {0x0000a418, 0x2d001dce}, | ||
397 | {0x0000a41c, 0x1ce739ce}, | ||
398 | {0x0000a420, 0x000001ce}, | ||
399 | {0x0000a424, 0x1ce739ce}, | ||
400 | {0x0000a428, 0x000001ce}, | ||
401 | {0x0000a42c, 0x1ce739ce}, | ||
402 | {0x0000a430, 0x1ce739ce}, | ||
403 | {0x0000a434, 0x00000000}, | ||
404 | {0x0000a438, 0x00001801}, | ||
405 | {0x0000a43c, 0x00000000}, | ||
406 | {0x0000a440, 0x00000000}, | ||
407 | {0x0000a444, 0x00000000}, | ||
408 | {0x0000a448, 0x04000080}, | ||
409 | {0x0000a44c, 0x00000001}, | ||
410 | {0x0000a450, 0x00010000}, | ||
411 | {0x0000a458, 0x00000000}, | ||
412 | {0x0000a600, 0x00000000}, | ||
413 | {0x0000a604, 0x00000000}, | ||
414 | {0x0000a608, 0x00000000}, | ||
415 | {0x0000a60c, 0x00000000}, | ||
416 | {0x0000a610, 0x00000000}, | ||
417 | {0x0000a614, 0x00000000}, | ||
418 | {0x0000a618, 0x00000000}, | ||
419 | {0x0000a61c, 0x00000000}, | ||
420 | {0x0000a620, 0x00000000}, | ||
421 | {0x0000a624, 0x00000000}, | ||
422 | {0x0000a628, 0x00000000}, | ||
423 | {0x0000a62c, 0x00000000}, | ||
424 | {0x0000a630, 0x00000000}, | ||
425 | {0x0000a634, 0x00000000}, | ||
426 | {0x0000a638, 0x00000000}, | ||
427 | {0x0000a63c, 0x00000000}, | ||
428 | {0x0000a640, 0x00000000}, | ||
429 | {0x0000a644, 0x3fad9d74}, | ||
430 | {0x0000a648, 0x0048060a}, | ||
431 | {0x0000a64c, 0x00000637}, | ||
432 | {0x0000a670, 0x03020100}, | ||
433 | {0x0000a674, 0x09080504}, | ||
434 | {0x0000a678, 0x0d0c0b0a}, | ||
435 | {0x0000a67c, 0x13121110}, | ||
436 | {0x0000a680, 0x31301514}, | ||
437 | {0x0000a684, 0x35343332}, | ||
438 | {0x0000a688, 0x00000036}, | ||
439 | {0x0000a690, 0x00000838}, | ||
440 | {0x0000a7c0, 0x00000000}, | ||
441 | {0x0000a7c4, 0xfffffffc}, | ||
442 | {0x0000a7c8, 0x00000000}, | ||
443 | {0x0000a7cc, 0x00000000}, | ||
444 | {0x0000a7d0, 0x00000000}, | ||
445 | {0x0000a7d4, 0x00000004}, | ||
446 | {0x0000a7dc, 0x00000000}, | ||
447 | {0x0000a8d0, 0x004b6a8e}, | ||
448 | {0x0000a8d4, 0x00000820}, | ||
449 | {0x0000a8dc, 0x00000000}, | ||
450 | {0x0000a8f0, 0x00000000}, | ||
451 | {0x0000a8f4, 0x00000000}, | ||
452 | {0x0000b2d0, 0x00000080}, | ||
453 | {0x0000b2d4, 0x00000000}, | ||
454 | {0x0000b2dc, 0x00000000}, | ||
455 | {0x0000b2e0, 0x00000000}, | ||
456 | {0x0000b2e4, 0x00000000}, | ||
457 | {0x0000b2e8, 0x00000000}, | ||
458 | {0x0000b2ec, 0x00000000}, | ||
459 | {0x0000b2f0, 0x00000000}, | ||
460 | {0x0000b2f4, 0x00000000}, | ||
461 | {0x0000b2f8, 0x00000000}, | ||
462 | {0x0000b408, 0x0e79e5c0}, | ||
463 | {0x0000b40c, 0x00820820}, | ||
464 | {0x0000b420, 0x00000000}, | ||
465 | }; | ||
466 | |||
467 | static const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = { | ||
468 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
469 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | ||
470 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
471 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | ||
472 | {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, | ||
473 | {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, | ||
474 | {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, | ||
475 | {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, | ||
476 | {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, | ||
477 | {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, | ||
478 | {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, | ||
479 | {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, | ||
480 | {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, | ||
481 | {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, | ||
482 | {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, | ||
483 | {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, | ||
484 | {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, | ||
485 | {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, | ||
486 | {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, | ||
487 | {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, | ||
488 | {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, | ||
489 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, | ||
490 | {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, | ||
491 | {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, | ||
492 | {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, | ||
493 | {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, | ||
494 | {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, | ||
495 | {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
496 | {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
497 | {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
498 | {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
499 | {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
500 | {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
501 | {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
502 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, | ||
503 | {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, | ||
504 | {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, | ||
505 | {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, | ||
506 | {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, | ||
507 | {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, | ||
508 | {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, | ||
509 | {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, | ||
510 | {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, | ||
511 | {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, | ||
512 | {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, | ||
513 | {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, | ||
514 | {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, | ||
515 | {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, | ||
516 | {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, | ||
517 | {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, | ||
518 | {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, | ||
519 | {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, | ||
520 | {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, | ||
521 | {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, | ||
522 | {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, | ||
523 | {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, | ||
524 | {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, | ||
525 | {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, | ||
526 | {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, | ||
527 | {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
528 | {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
529 | {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
530 | {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
531 | {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
532 | {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
533 | {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
534 | {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
535 | {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
536 | {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
537 | {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
538 | }; | ||
539 | |||
540 | static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = { | ||
541 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
542 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | ||
543 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
544 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | ||
545 | {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, | ||
546 | {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, | ||
547 | {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, | ||
548 | {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, | ||
549 | {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, | ||
550 | {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, | ||
551 | {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, | ||
552 | {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, | ||
553 | {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, | ||
554 | {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, | ||
555 | {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, | ||
556 | {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, | ||
557 | {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, | ||
558 | {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, | ||
559 | {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, | ||
560 | {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, | ||
561 | {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, | ||
562 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, | ||
563 | {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, | ||
564 | {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, | ||
565 | {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, | ||
566 | {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, | ||
567 | {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, | ||
568 | {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
569 | {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
570 | {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
571 | {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
572 | {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
573 | {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
574 | {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
575 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, | ||
576 | {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, | ||
577 | {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, | ||
578 | {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, | ||
579 | {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, | ||
580 | {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, | ||
581 | {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, | ||
582 | {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, | ||
583 | {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, | ||
584 | {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, | ||
585 | {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, | ||
586 | {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, | ||
587 | {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, | ||
588 | {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, | ||
589 | {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, | ||
590 | {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, | ||
591 | {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, | ||
592 | {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, | ||
593 | {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, | ||
594 | {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, | ||
595 | {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, | ||
596 | {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, | ||
597 | {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, | ||
598 | {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, | ||
599 | {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, | ||
600 | {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
601 | {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
602 | {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
603 | {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
604 | {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
605 | {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
606 | {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
607 | {0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, | ||
608 | {0x00016048, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266}, | ||
609 | {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, | ||
610 | {0x00016448, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266}, | ||
611 | }; | ||
612 | static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = { | ||
613 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
614 | {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, | ||
615 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
616 | {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, | ||
617 | {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, | ||
618 | {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, | ||
619 | {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, | ||
620 | {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, | ||
621 | {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, | ||
622 | {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, | ||
623 | {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, | ||
624 | {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, | ||
625 | {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, | ||
626 | {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, | ||
627 | {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, | ||
628 | {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, | ||
629 | {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, | ||
630 | {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, | ||
631 | {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, | ||
632 | {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, | ||
633 | {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, | ||
634 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, | ||
635 | {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, | ||
636 | {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, | ||
637 | {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, | ||
638 | {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, | ||
639 | {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, | ||
640 | {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
641 | {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
642 | {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
643 | {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
644 | {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
645 | {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
646 | {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, | ||
647 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, | ||
648 | {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, | ||
649 | {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, | ||
650 | {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, | ||
651 | {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, | ||
652 | {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, | ||
653 | {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, | ||
654 | {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, | ||
655 | {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, | ||
656 | {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, | ||
657 | {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, | ||
658 | {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, | ||
659 | {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, | ||
660 | {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, | ||
661 | {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, | ||
662 | {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, | ||
663 | {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, | ||
664 | {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, | ||
665 | {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, | ||
666 | {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, | ||
667 | {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, | ||
668 | {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, | ||
669 | {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, | ||
670 | {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, | ||
671 | {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, | ||
672 | {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
673 | {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
674 | {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
675 | {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
676 | {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
677 | {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
678 | {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, | ||
679 | {0x00016044, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db}, | ||
680 | {0x00016048, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266}, | ||
681 | {0x00016444, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db}, | ||
682 | {0x00016448, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266}, | ||
683 | }; | ||
684 | |||
685 | |||
686 | static const u32 ar9340Common_rx_gain_table_1p0[][2] = { | ||
687 | /* Addr allmodes */ | ||
688 | {0x0000a000, 0x00010000}, | ||
689 | {0x0000a004, 0x00030002}, | ||
690 | {0x0000a008, 0x00050004}, | ||
691 | {0x0000a00c, 0x00810080}, | ||
692 | {0x0000a010, 0x00830082}, | ||
693 | {0x0000a014, 0x01810180}, | ||
694 | {0x0000a018, 0x01830182}, | ||
695 | {0x0000a01c, 0x01850184}, | ||
696 | {0x0000a020, 0x01890188}, | ||
697 | {0x0000a024, 0x018b018a}, | ||
698 | {0x0000a028, 0x018d018c}, | ||
699 | {0x0000a02c, 0x01910190}, | ||
700 | {0x0000a030, 0x01930192}, | ||
701 | {0x0000a034, 0x01950194}, | ||
702 | {0x0000a038, 0x038a0196}, | ||
703 | {0x0000a03c, 0x038c038b}, | ||
704 | {0x0000a040, 0x0390038d}, | ||
705 | {0x0000a044, 0x03920391}, | ||
706 | {0x0000a048, 0x03940393}, | ||
707 | {0x0000a04c, 0x03960395}, | ||
708 | {0x0000a050, 0x00000000}, | ||
709 | {0x0000a054, 0x00000000}, | ||
710 | {0x0000a058, 0x00000000}, | ||
711 | {0x0000a05c, 0x00000000}, | ||
712 | {0x0000a060, 0x00000000}, | ||
713 | {0x0000a064, 0x00000000}, | ||
714 | {0x0000a068, 0x00000000}, | ||
715 | {0x0000a06c, 0x00000000}, | ||
716 | {0x0000a070, 0x00000000}, | ||
717 | {0x0000a074, 0x00000000}, | ||
718 | {0x0000a078, 0x00000000}, | ||
719 | {0x0000a07c, 0x00000000}, | ||
720 | {0x0000a080, 0x22222229}, | ||
721 | {0x0000a084, 0x1d1d1d1d}, | ||
722 | {0x0000a088, 0x1d1d1d1d}, | ||
723 | {0x0000a08c, 0x1d1d1d1d}, | ||
724 | {0x0000a090, 0x171d1d1d}, | ||
725 | {0x0000a094, 0x11111717}, | ||
726 | {0x0000a098, 0x00030311}, | ||
727 | {0x0000a09c, 0x00000000}, | ||
728 | {0x0000a0a0, 0x00000000}, | ||
729 | {0x0000a0a4, 0x00000000}, | ||
730 | {0x0000a0a8, 0x00000000}, | ||
731 | {0x0000a0ac, 0x00000000}, | ||
732 | {0x0000a0b0, 0x00000000}, | ||
733 | {0x0000a0b4, 0x00000000}, | ||
734 | {0x0000a0b8, 0x00000000}, | ||
735 | {0x0000a0bc, 0x00000000}, | ||
736 | {0x0000a0c0, 0x001f0000}, | ||
737 | {0x0000a0c4, 0x01000101}, | ||
738 | {0x0000a0c8, 0x011e011f}, | ||
739 | {0x0000a0cc, 0x011c011d}, | ||
740 | {0x0000a0d0, 0x02030204}, | ||
741 | {0x0000a0d4, 0x02010202}, | ||
742 | {0x0000a0d8, 0x021f0200}, | ||
743 | {0x0000a0dc, 0x0302021e}, | ||
744 | {0x0000a0e0, 0x03000301}, | ||
745 | {0x0000a0e4, 0x031e031f}, | ||
746 | {0x0000a0e8, 0x0402031d}, | ||
747 | {0x0000a0ec, 0x04000401}, | ||
748 | {0x0000a0f0, 0x041e041f}, | ||
749 | {0x0000a0f4, 0x0502041d}, | ||
750 | {0x0000a0f8, 0x05000501}, | ||
751 | {0x0000a0fc, 0x051e051f}, | ||
752 | {0x0000a100, 0x06010602}, | ||
753 | {0x0000a104, 0x061f0600}, | ||
754 | {0x0000a108, 0x061d061e}, | ||
755 | {0x0000a10c, 0x07020703}, | ||
756 | {0x0000a110, 0x07000701}, | ||
757 | {0x0000a114, 0x00000000}, | ||
758 | {0x0000a118, 0x00000000}, | ||
759 | {0x0000a11c, 0x00000000}, | ||
760 | {0x0000a120, 0x00000000}, | ||
761 | {0x0000a124, 0x00000000}, | ||
762 | {0x0000a128, 0x00000000}, | ||
763 | {0x0000a12c, 0x00000000}, | ||
764 | {0x0000a130, 0x00000000}, | ||
765 | {0x0000a134, 0x00000000}, | ||
766 | {0x0000a138, 0x00000000}, | ||
767 | {0x0000a13c, 0x00000000}, | ||
768 | {0x0000a140, 0x001f0000}, | ||
769 | {0x0000a144, 0x01000101}, | ||
770 | {0x0000a148, 0x011e011f}, | ||
771 | {0x0000a14c, 0x011c011d}, | ||
772 | {0x0000a150, 0x02030204}, | ||
773 | {0x0000a154, 0x02010202}, | ||
774 | {0x0000a158, 0x021f0200}, | ||
775 | {0x0000a15c, 0x0302021e}, | ||
776 | {0x0000a160, 0x03000301}, | ||
777 | {0x0000a164, 0x031e031f}, | ||
778 | {0x0000a168, 0x0402031d}, | ||
779 | {0x0000a16c, 0x04000401}, | ||
780 | {0x0000a170, 0x041e041f}, | ||
781 | {0x0000a174, 0x0502041d}, | ||
782 | {0x0000a178, 0x05000501}, | ||
783 | {0x0000a17c, 0x051e051f}, | ||
784 | {0x0000a180, 0x06010602}, | ||
785 | {0x0000a184, 0x061f0600}, | ||
786 | {0x0000a188, 0x061d061e}, | ||
787 | {0x0000a18c, 0x07020703}, | ||
788 | {0x0000a190, 0x07000701}, | ||
789 | {0x0000a194, 0x00000000}, | ||
790 | {0x0000a198, 0x00000000}, | ||
791 | {0x0000a19c, 0x00000000}, | ||
792 | {0x0000a1a0, 0x00000000}, | ||
793 | {0x0000a1a4, 0x00000000}, | ||
794 | {0x0000a1a8, 0x00000000}, | ||
795 | {0x0000a1ac, 0x00000000}, | ||
796 | {0x0000a1b0, 0x00000000}, | ||
797 | {0x0000a1b4, 0x00000000}, | ||
798 | {0x0000a1b8, 0x00000000}, | ||
799 | {0x0000a1bc, 0x00000000}, | ||
800 | {0x0000a1c0, 0x00000000}, | ||
801 | {0x0000a1c4, 0x00000000}, | ||
802 | {0x0000a1c8, 0x00000000}, | ||
803 | {0x0000a1cc, 0x00000000}, | ||
804 | {0x0000a1d0, 0x00000000}, | ||
805 | {0x0000a1d4, 0x00000000}, | ||
806 | {0x0000a1d8, 0x00000000}, | ||
807 | {0x0000a1dc, 0x00000000}, | ||
808 | {0x0000a1e0, 0x00000000}, | ||
809 | {0x0000a1e4, 0x00000000}, | ||
810 | {0x0000a1e8, 0x00000000}, | ||
811 | {0x0000a1ec, 0x00000000}, | ||
812 | {0x0000a1f0, 0x00000396}, | ||
813 | {0x0000a1f4, 0x00000396}, | ||
814 | {0x0000a1f8, 0x00000396}, | ||
815 | {0x0000a1fc, 0x00000196}, | ||
816 | {0x0000b000, 0x00010000}, | ||
817 | {0x0000b004, 0x00030002}, | ||
818 | {0x0000b008, 0x00050004}, | ||
819 | {0x0000b00c, 0x00810080}, | ||
820 | {0x0000b010, 0x00830082}, | ||
821 | {0x0000b014, 0x01810180}, | ||
822 | {0x0000b018, 0x01830182}, | ||
823 | {0x0000b01c, 0x01850184}, | ||
824 | {0x0000b020, 0x02810280}, | ||
825 | {0x0000b024, 0x02830282}, | ||
826 | {0x0000b028, 0x02850284}, | ||
827 | {0x0000b02c, 0x02890288}, | ||
828 | {0x0000b030, 0x028b028a}, | ||
829 | {0x0000b034, 0x0388028c}, | ||
830 | {0x0000b038, 0x038a0389}, | ||
831 | {0x0000b03c, 0x038c038b}, | ||
832 | {0x0000b040, 0x0390038d}, | ||
833 | {0x0000b044, 0x03920391}, | ||
834 | {0x0000b048, 0x03940393}, | ||
835 | {0x0000b04c, 0x03960395}, | ||
836 | {0x0000b050, 0x00000000}, | ||
837 | {0x0000b054, 0x00000000}, | ||
838 | {0x0000b058, 0x00000000}, | ||
839 | {0x0000b05c, 0x00000000}, | ||
840 | {0x0000b060, 0x00000000}, | ||
841 | {0x0000b064, 0x00000000}, | ||
842 | {0x0000b068, 0x00000000}, | ||
843 | {0x0000b06c, 0x00000000}, | ||
844 | {0x0000b070, 0x00000000}, | ||
845 | {0x0000b074, 0x00000000}, | ||
846 | {0x0000b078, 0x00000000}, | ||
847 | {0x0000b07c, 0x00000000}, | ||
848 | {0x0000b080, 0x32323232}, | ||
849 | {0x0000b084, 0x2f2f3232}, | ||
850 | {0x0000b088, 0x23282a2d}, | ||
851 | {0x0000b08c, 0x1c1e2123}, | ||
852 | {0x0000b090, 0x14171919}, | ||
853 | {0x0000b094, 0x0e0e1214}, | ||
854 | {0x0000b098, 0x03050707}, | ||
855 | {0x0000b09c, 0x00030303}, | ||
856 | {0x0000b0a0, 0x00000000}, | ||
857 | {0x0000b0a4, 0x00000000}, | ||
858 | {0x0000b0a8, 0x00000000}, | ||
859 | {0x0000b0ac, 0x00000000}, | ||
860 | {0x0000b0b0, 0x00000000}, | ||
861 | {0x0000b0b4, 0x00000000}, | ||
862 | {0x0000b0b8, 0x00000000}, | ||
863 | {0x0000b0bc, 0x00000000}, | ||
864 | {0x0000b0c0, 0x003f0020}, | ||
865 | {0x0000b0c4, 0x00400041}, | ||
866 | {0x0000b0c8, 0x0140005f}, | ||
867 | {0x0000b0cc, 0x0160015f}, | ||
868 | {0x0000b0d0, 0x017e017f}, | ||
869 | {0x0000b0d4, 0x02410242}, | ||
870 | {0x0000b0d8, 0x025f0240}, | ||
871 | {0x0000b0dc, 0x027f0260}, | ||
872 | {0x0000b0e0, 0x0341027e}, | ||
873 | {0x0000b0e4, 0x035f0340}, | ||
874 | {0x0000b0e8, 0x037f0360}, | ||
875 | {0x0000b0ec, 0x04400441}, | ||
876 | {0x0000b0f0, 0x0460045f}, | ||
877 | {0x0000b0f4, 0x0541047f}, | ||
878 | {0x0000b0f8, 0x055f0540}, | ||
879 | {0x0000b0fc, 0x057f0560}, | ||
880 | {0x0000b100, 0x06400641}, | ||
881 | {0x0000b104, 0x0660065f}, | ||
882 | {0x0000b108, 0x067e067f}, | ||
883 | {0x0000b10c, 0x07410742}, | ||
884 | {0x0000b110, 0x075f0740}, | ||
885 | {0x0000b114, 0x077f0760}, | ||
886 | {0x0000b118, 0x07800781}, | ||
887 | {0x0000b11c, 0x07a0079f}, | ||
888 | {0x0000b120, 0x07c107bf}, | ||
889 | {0x0000b124, 0x000007c0}, | ||
890 | {0x0000b128, 0x00000000}, | ||
891 | {0x0000b12c, 0x00000000}, | ||
892 | {0x0000b130, 0x00000000}, | ||
893 | {0x0000b134, 0x00000000}, | ||
894 | {0x0000b138, 0x00000000}, | ||
895 | {0x0000b13c, 0x00000000}, | ||
896 | {0x0000b140, 0x003f0020}, | ||
897 | {0x0000b144, 0x00400041}, | ||
898 | {0x0000b148, 0x0140005f}, | ||
899 | {0x0000b14c, 0x0160015f}, | ||
900 | {0x0000b150, 0x017e017f}, | ||
901 | {0x0000b154, 0x02410242}, | ||
902 | {0x0000b158, 0x025f0240}, | ||
903 | {0x0000b15c, 0x027f0260}, | ||
904 | {0x0000b160, 0x0341027e}, | ||
905 | {0x0000b164, 0x035f0340}, | ||
906 | {0x0000b168, 0x037f0360}, | ||
907 | {0x0000b16c, 0x04400441}, | ||
908 | {0x0000b170, 0x0460045f}, | ||
909 | {0x0000b174, 0x0541047f}, | ||
910 | {0x0000b178, 0x055f0540}, | ||
911 | {0x0000b17c, 0x057f0560}, | ||
912 | {0x0000b180, 0x06400641}, | ||
913 | {0x0000b184, 0x0660065f}, | ||
914 | {0x0000b188, 0x067e067f}, | ||
915 | {0x0000b18c, 0x07410742}, | ||
916 | {0x0000b190, 0x075f0740}, | ||
917 | {0x0000b194, 0x077f0760}, | ||
918 | {0x0000b198, 0x07800781}, | ||
919 | {0x0000b19c, 0x07a0079f}, | ||
920 | {0x0000b1a0, 0x07c107bf}, | ||
921 | {0x0000b1a4, 0x000007c0}, | ||
922 | {0x0000b1a8, 0x00000000}, | ||
923 | {0x0000b1ac, 0x00000000}, | ||
924 | {0x0000b1b0, 0x00000000}, | ||
925 | {0x0000b1b4, 0x00000000}, | ||
926 | {0x0000b1b8, 0x00000000}, | ||
927 | {0x0000b1bc, 0x00000000}, | ||
928 | {0x0000b1c0, 0x00000000}, | ||
929 | {0x0000b1c4, 0x00000000}, | ||
930 | {0x0000b1c8, 0x00000000}, | ||
931 | {0x0000b1cc, 0x00000000}, | ||
932 | {0x0000b1d0, 0x00000000}, | ||
933 | {0x0000b1d4, 0x00000000}, | ||
934 | {0x0000b1d8, 0x00000000}, | ||
935 | {0x0000b1dc, 0x00000000}, | ||
936 | {0x0000b1e0, 0x00000000}, | ||
937 | {0x0000b1e4, 0x00000000}, | ||
938 | {0x0000b1e8, 0x00000000}, | ||
939 | {0x0000b1ec, 0x00000000}, | ||
940 | {0x0000b1f0, 0x00000396}, | ||
941 | {0x0000b1f4, 0x00000396}, | ||
942 | {0x0000b1f8, 0x00000396}, | ||
943 | {0x0000b1fc, 0x00000196}, | ||
944 | }; | ||
945 | |||
946 | static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { | ||
947 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
948 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
949 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
950 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
951 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
952 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
953 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
954 | {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, | ||
955 | {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, | ||
956 | {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, | ||
957 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, | ||
958 | {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, | ||
959 | {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, | ||
960 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, | ||
961 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, | ||
962 | {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, | ||
963 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | ||
964 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | ||
965 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | ||
966 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | ||
967 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | ||
968 | {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, | ||
969 | {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, | ||
970 | {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, | ||
971 | {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, | ||
972 | {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, | ||
973 | {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, | ||
974 | {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
975 | {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
976 | {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
977 | {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
978 | {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
979 | {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
980 | {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
981 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
982 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | ||
983 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | ||
984 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | ||
985 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, | ||
986 | {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, | ||
987 | {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, | ||
988 | {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, | ||
989 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, | ||
990 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, | ||
991 | {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, | ||
992 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, | ||
993 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, | ||
994 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, | ||
995 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, | ||
996 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, | ||
997 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, | ||
998 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, | ||
999 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, | ||
1000 | {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, | ||
1001 | {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, | ||
1002 | {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, | ||
1003 | {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, | ||
1004 | {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, | ||
1005 | {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, | ||
1006 | {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1007 | {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1008 | {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1009 | {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1010 | {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1011 | {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1012 | {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1013 | {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
1014 | {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
1015 | {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, | ||
1016 | {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, | ||
1017 | }; | ||
1018 | |||
1019 | static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { | ||
1020 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1021 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
1022 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1023 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
1024 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
1025 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
1026 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
1027 | {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400}, | ||
1028 | {0x0000a518, 0x21020220, 0x21020220, 0x15000402, 0x15000402}, | ||
1029 | {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, | ||
1030 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603}, | ||
1031 | {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02}, | ||
1032 | {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04}, | ||
1033 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20}, | ||
1034 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20}, | ||
1035 | {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22}, | ||
1036 | {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24}, | ||
1037 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640}, | ||
1038 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660}, | ||
1039 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861}, | ||
1040 | {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81}, | ||
1041 | {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x42001a83, 0x42001a83}, | ||
1042 | {0x0000a550, 0x61042a6c, 0x61042a6c, 0x44001c84, 0x44001c84}, | ||
1043 | {0x0000a554, 0x66062a6c, 0x66062a6c, 0x48001ce3, 0x48001ce3}, | ||
1044 | {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x4c001ce5, 0x4c001ce5}, | ||
1045 | {0x0000a55c, 0x7006308c, 0x7006308c, 0x50001ce9, 0x50001ce9}, | ||
1046 | {0x0000a560, 0x730a308a, 0x730a308a, 0x54001ceb, 0x54001ceb}, | ||
1047 | {0x0000a564, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1048 | {0x0000a568, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1049 | {0x0000a56c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1050 | {0x0000a570, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1051 | {0x0000a574, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1052 | {0x0000a578, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1053 | {0x0000a57c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, | ||
1054 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
1055 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | ||
1056 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | ||
1057 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | ||
1058 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, | ||
1059 | {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400}, | ||
1060 | {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402}, | ||
1061 | {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, | ||
1062 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603}, | ||
1063 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02}, | ||
1064 | {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04}, | ||
1065 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20}, | ||
1066 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20}, | ||
1067 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22}, | ||
1068 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24}, | ||
1069 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640}, | ||
1070 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660}, | ||
1071 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861}, | ||
1072 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81}, | ||
1073 | {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83}, | ||
1074 | {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84}, | ||
1075 | {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3}, | ||
1076 | {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5}, | ||
1077 | {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9}, | ||
1078 | {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb}, | ||
1079 | {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1080 | {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1081 | {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1082 | {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1083 | {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1084 | {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1085 | {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, | ||
1086 | {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, | ||
1087 | {0x00016048, 0x24927266, 0x24927266, 0x8e483266, 0x8e483266}, | ||
1088 | {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, | ||
1089 | {0x00016448, 0x24927266, 0x24927266, 0x8e482266, 0x8e482266}, | ||
1090 | }; | ||
1091 | |||
1092 | static const u32 ar9340_1p0_mac_core[][2] = { | ||
1093 | /* Addr allmodes */ | ||
1094 | {0x00000008, 0x00000000}, | ||
1095 | {0x00000030, 0x00020085}, | ||
1096 | {0x00000034, 0x00000005}, | ||
1097 | {0x00000040, 0x00000000}, | ||
1098 | {0x00000044, 0x00000000}, | ||
1099 | {0x00000048, 0x00000008}, | ||
1100 | {0x0000004c, 0x00000010}, | ||
1101 | {0x00000050, 0x00000000}, | ||
1102 | {0x00001040, 0x002ffc0f}, | ||
1103 | {0x00001044, 0x002ffc0f}, | ||
1104 | {0x00001048, 0x002ffc0f}, | ||
1105 | {0x0000104c, 0x002ffc0f}, | ||
1106 | {0x00001050, 0x002ffc0f}, | ||
1107 | {0x00001054, 0x002ffc0f}, | ||
1108 | {0x00001058, 0x002ffc0f}, | ||
1109 | {0x0000105c, 0x002ffc0f}, | ||
1110 | {0x00001060, 0x002ffc0f}, | ||
1111 | {0x00001064, 0x002ffc0f}, | ||
1112 | {0x000010f0, 0x00000100}, | ||
1113 | {0x00001270, 0x00000000}, | ||
1114 | {0x000012b0, 0x00000000}, | ||
1115 | {0x000012f0, 0x00000000}, | ||
1116 | {0x0000143c, 0x00000000}, | ||
1117 | {0x0000147c, 0x00000000}, | ||
1118 | {0x00008000, 0x00000000}, | ||
1119 | {0x00008004, 0x00000000}, | ||
1120 | {0x00008008, 0x00000000}, | ||
1121 | {0x0000800c, 0x00000000}, | ||
1122 | {0x00008018, 0x00000000}, | ||
1123 | {0x00008020, 0x00000000}, | ||
1124 | {0x00008038, 0x00000000}, | ||
1125 | {0x0000803c, 0x00000000}, | ||
1126 | {0x00008040, 0x00000000}, | ||
1127 | {0x00008044, 0x00000000}, | ||
1128 | {0x00008048, 0x00000000}, | ||
1129 | {0x0000804c, 0xffffffff}, | ||
1130 | {0x00008054, 0x00000000}, | ||
1131 | {0x00008058, 0x00000000}, | ||
1132 | {0x0000805c, 0x000fc78f}, | ||
1133 | {0x00008060, 0x0000000f}, | ||
1134 | {0x00008064, 0x00000000}, | ||
1135 | {0x00008070, 0x00000310}, | ||
1136 | {0x00008074, 0x00000020}, | ||
1137 | {0x00008078, 0x00000000}, | ||
1138 | {0x0000809c, 0x0000000f}, | ||
1139 | {0x000080a0, 0x00000000}, | ||
1140 | {0x000080a4, 0x02ff0000}, | ||
1141 | {0x000080a8, 0x0e070605}, | ||
1142 | {0x000080ac, 0x0000000d}, | ||
1143 | {0x000080b0, 0x00000000}, | ||
1144 | {0x000080b4, 0x00000000}, | ||
1145 | {0x000080b8, 0x00000000}, | ||
1146 | {0x000080bc, 0x00000000}, | ||
1147 | {0x000080c0, 0x2a800000}, | ||
1148 | {0x000080c4, 0x06900168}, | ||
1149 | {0x000080c8, 0x13881c20}, | ||
1150 | {0x000080cc, 0x01f40000}, | ||
1151 | {0x000080d0, 0x00252500}, | ||
1152 | {0x000080d4, 0x00a00000}, | ||
1153 | {0x000080d8, 0x00400000}, | ||
1154 | {0x000080dc, 0x00000000}, | ||
1155 | {0x000080e0, 0xffffffff}, | ||
1156 | {0x000080e4, 0x0000ffff}, | ||
1157 | {0x000080e8, 0x3f3f3f3f}, | ||
1158 | {0x000080ec, 0x00000000}, | ||
1159 | {0x000080f0, 0x00000000}, | ||
1160 | {0x000080f4, 0x00000000}, | ||
1161 | {0x000080fc, 0x00020000}, | ||
1162 | {0x00008100, 0x00000000}, | ||
1163 | {0x00008108, 0x00000052}, | ||
1164 | {0x0000810c, 0x00000000}, | ||
1165 | {0x00008110, 0x00000000}, | ||
1166 | {0x00008114, 0x000007ff}, | ||
1167 | {0x00008118, 0x000000aa}, | ||
1168 | {0x0000811c, 0x00003210}, | ||
1169 | {0x00008124, 0x00000000}, | ||
1170 | {0x00008128, 0x00000000}, | ||
1171 | {0x0000812c, 0x00000000}, | ||
1172 | {0x00008130, 0x00000000}, | ||
1173 | {0x00008134, 0x00000000}, | ||
1174 | {0x00008138, 0x00000000}, | ||
1175 | {0x0000813c, 0x0000ffff}, | ||
1176 | {0x00008144, 0xffffffff}, | ||
1177 | {0x00008168, 0x00000000}, | ||
1178 | {0x0000816c, 0x00000000}, | ||
1179 | {0x00008170, 0x18486200}, | ||
1180 | {0x00008174, 0x33332210}, | ||
1181 | {0x00008178, 0x00000000}, | ||
1182 | {0x0000817c, 0x00020000}, | ||
1183 | {0x000081c0, 0x00000000}, | ||
1184 | {0x000081c4, 0x33332210}, | ||
1185 | {0x000081c8, 0x00000000}, | ||
1186 | {0x000081cc, 0x00000000}, | ||
1187 | {0x000081d4, 0x00000000}, | ||
1188 | {0x000081ec, 0x00000000}, | ||
1189 | {0x000081f0, 0x00000000}, | ||
1190 | {0x000081f4, 0x00000000}, | ||
1191 | {0x000081f8, 0x00000000}, | ||
1192 | {0x000081fc, 0x00000000}, | ||
1193 | {0x00008240, 0x00100000}, | ||
1194 | {0x00008244, 0x0010f424}, | ||
1195 | {0x00008248, 0x00000800}, | ||
1196 | {0x0000824c, 0x0001e848}, | ||
1197 | {0x00008250, 0x00000000}, | ||
1198 | {0x00008254, 0x00000000}, | ||
1199 | {0x00008258, 0x00000000}, | ||
1200 | {0x0000825c, 0x40000000}, | ||
1201 | {0x00008260, 0x00080922}, | ||
1202 | {0x00008264, 0x9d400010}, | ||
1203 | {0x00008268, 0xffffffff}, | ||
1204 | {0x0000826c, 0x0000ffff}, | ||
1205 | {0x00008270, 0x00000000}, | ||
1206 | {0x00008274, 0x40000000}, | ||
1207 | {0x00008278, 0x003e4180}, | ||
1208 | {0x0000827c, 0x00000004}, | ||
1209 | {0x00008284, 0x0000002c}, | ||
1210 | {0x00008288, 0x0000002c}, | ||
1211 | {0x0000828c, 0x000000ff}, | ||
1212 | {0x00008294, 0x00000000}, | ||
1213 | {0x00008298, 0x00000000}, | ||
1214 | {0x0000829c, 0x00000000}, | ||
1215 | {0x00008300, 0x00000140}, | ||
1216 | {0x00008314, 0x00000000}, | ||
1217 | {0x0000831c, 0x0000010d}, | ||
1218 | {0x00008328, 0x00000000}, | ||
1219 | {0x0000832c, 0x00000007}, | ||
1220 | {0x00008330, 0x00000302}, | ||
1221 | {0x00008334, 0x00000700}, | ||
1222 | {0x00008338, 0x00ff0000}, | ||
1223 | {0x0000833c, 0x02400000}, | ||
1224 | {0x00008340, 0x000107ff}, | ||
1225 | {0x00008344, 0xaa48105b}, | ||
1226 | {0x00008348, 0x008f0000}, | ||
1227 | {0x0000835c, 0x00000000}, | ||
1228 | {0x00008360, 0xffffffff}, | ||
1229 | {0x00008364, 0xffffffff}, | ||
1230 | {0x00008368, 0x00000000}, | ||
1231 | {0x00008370, 0x00000000}, | ||
1232 | {0x00008374, 0x000000ff}, | ||
1233 | {0x00008378, 0x00000000}, | ||
1234 | {0x0000837c, 0x00000000}, | ||
1235 | {0x00008380, 0xffffffff}, | ||
1236 | {0x00008384, 0xffffffff}, | ||
1237 | {0x00008390, 0xffffffff}, | ||
1238 | {0x00008394, 0xffffffff}, | ||
1239 | {0x00008398, 0x00000000}, | ||
1240 | {0x0000839c, 0x00000000}, | ||
1241 | {0x000083a0, 0x00000000}, | ||
1242 | {0x000083a4, 0x0000fa14}, | ||
1243 | {0x000083a8, 0x000f0c00}, | ||
1244 | {0x000083ac, 0x33332210}, | ||
1245 | {0x000083b0, 0x33332210}, | ||
1246 | {0x000083b4, 0x33332210}, | ||
1247 | {0x000083b8, 0x33332210}, | ||
1248 | {0x000083bc, 0x00000000}, | ||
1249 | {0x000083c0, 0x00000000}, | ||
1250 | {0x000083c4, 0x00000000}, | ||
1251 | {0x000083c8, 0x00000000}, | ||
1252 | {0x000083cc, 0x00000200}, | ||
1253 | {0x000083d0, 0x000301ff}, | ||
1254 | }; | ||
1255 | |||
1256 | static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = { | ||
1257 | /* Addr allmodes */ | ||
1258 | {0x0000a000, 0x00010000}, | ||
1259 | {0x0000a004, 0x00030002}, | ||
1260 | {0x0000a008, 0x00050004}, | ||
1261 | {0x0000a00c, 0x00810080}, | ||
1262 | {0x0000a010, 0x00830082}, | ||
1263 | {0x0000a014, 0x01810180}, | ||
1264 | {0x0000a018, 0x01830182}, | ||
1265 | {0x0000a01c, 0x01850184}, | ||
1266 | {0x0000a020, 0x01890188}, | ||
1267 | {0x0000a024, 0x018b018a}, | ||
1268 | {0x0000a028, 0x018d018c}, | ||
1269 | {0x0000a02c, 0x03820190}, | ||
1270 | {0x0000a030, 0x03840383}, | ||
1271 | {0x0000a034, 0x03880385}, | ||
1272 | {0x0000a038, 0x038a0389}, | ||
1273 | {0x0000a03c, 0x038c038b}, | ||
1274 | {0x0000a040, 0x0390038d}, | ||
1275 | {0x0000a044, 0x03920391}, | ||
1276 | {0x0000a048, 0x03940393}, | ||
1277 | {0x0000a04c, 0x03960395}, | ||
1278 | {0x0000a050, 0x00000000}, | ||
1279 | {0x0000a054, 0x00000000}, | ||
1280 | {0x0000a058, 0x00000000}, | ||
1281 | {0x0000a05c, 0x00000000}, | ||
1282 | {0x0000a060, 0x00000000}, | ||
1283 | {0x0000a064, 0x00000000}, | ||
1284 | {0x0000a068, 0x00000000}, | ||
1285 | {0x0000a06c, 0x00000000}, | ||
1286 | {0x0000a070, 0x00000000}, | ||
1287 | {0x0000a074, 0x00000000}, | ||
1288 | {0x0000a078, 0x00000000}, | ||
1289 | {0x0000a07c, 0x00000000}, | ||
1290 | {0x0000a080, 0x29292929}, | ||
1291 | {0x0000a084, 0x29292929}, | ||
1292 | {0x0000a088, 0x29292929}, | ||
1293 | {0x0000a08c, 0x29292929}, | ||
1294 | {0x0000a090, 0x22292929}, | ||
1295 | {0x0000a094, 0x1d1d2222}, | ||
1296 | {0x0000a098, 0x0c111117}, | ||
1297 | {0x0000a09c, 0x00030303}, | ||
1298 | {0x0000a0a0, 0x00000000}, | ||
1299 | {0x0000a0a4, 0x00000000}, | ||
1300 | {0x0000a0a8, 0x00000000}, | ||
1301 | {0x0000a0ac, 0x00000000}, | ||
1302 | {0x0000a0b0, 0x00000000}, | ||
1303 | {0x0000a0b4, 0x00000000}, | ||
1304 | {0x0000a0b8, 0x00000000}, | ||
1305 | {0x0000a0bc, 0x00000000}, | ||
1306 | {0x0000a0c0, 0x001f0000}, | ||
1307 | {0x0000a0c4, 0x01000101}, | ||
1308 | {0x0000a0c8, 0x011e011f}, | ||
1309 | {0x0000a0cc, 0x011c011d}, | ||
1310 | {0x0000a0d0, 0x02030204}, | ||
1311 | {0x0000a0d4, 0x02010202}, | ||
1312 | {0x0000a0d8, 0x021f0200}, | ||
1313 | {0x0000a0dc, 0x0302021e}, | ||
1314 | {0x0000a0e0, 0x03000301}, | ||
1315 | {0x0000a0e4, 0x031e031f}, | ||
1316 | {0x0000a0e8, 0x0402031d}, | ||
1317 | {0x0000a0ec, 0x04000401}, | ||
1318 | {0x0000a0f0, 0x041e041f}, | ||
1319 | {0x0000a0f4, 0x0502041d}, | ||
1320 | {0x0000a0f8, 0x05000501}, | ||
1321 | {0x0000a0fc, 0x051e051f}, | ||
1322 | {0x0000a100, 0x06010602}, | ||
1323 | {0x0000a104, 0x061f0600}, | ||
1324 | {0x0000a108, 0x061d061e}, | ||
1325 | {0x0000a10c, 0x07020703}, | ||
1326 | {0x0000a110, 0x07000701}, | ||
1327 | {0x0000a114, 0x00000000}, | ||
1328 | {0x0000a118, 0x00000000}, | ||
1329 | {0x0000a11c, 0x00000000}, | ||
1330 | {0x0000a120, 0x00000000}, | ||
1331 | {0x0000a124, 0x00000000}, | ||
1332 | {0x0000a128, 0x00000000}, | ||
1333 | {0x0000a12c, 0x00000000}, | ||
1334 | {0x0000a130, 0x00000000}, | ||
1335 | {0x0000a134, 0x00000000}, | ||
1336 | {0x0000a138, 0x00000000}, | ||
1337 | {0x0000a13c, 0x00000000}, | ||
1338 | {0x0000a140, 0x001f0000}, | ||
1339 | {0x0000a144, 0x01000101}, | ||
1340 | {0x0000a148, 0x011e011f}, | ||
1341 | {0x0000a14c, 0x011c011d}, | ||
1342 | {0x0000a150, 0x02030204}, | ||
1343 | {0x0000a154, 0x02010202}, | ||
1344 | {0x0000a158, 0x021f0200}, | ||
1345 | {0x0000a15c, 0x0302021e}, | ||
1346 | {0x0000a160, 0x03000301}, | ||
1347 | {0x0000a164, 0x031e031f}, | ||
1348 | {0x0000a168, 0x0402031d}, | ||
1349 | {0x0000a16c, 0x04000401}, | ||
1350 | {0x0000a170, 0x041e041f}, | ||
1351 | {0x0000a174, 0x0502041d}, | ||
1352 | {0x0000a178, 0x05000501}, | ||
1353 | {0x0000a17c, 0x051e051f}, | ||
1354 | {0x0000a180, 0x06010602}, | ||
1355 | {0x0000a184, 0x061f0600}, | ||
1356 | {0x0000a188, 0x061d061e}, | ||
1357 | {0x0000a18c, 0x07020703}, | ||
1358 | {0x0000a190, 0x07000701}, | ||
1359 | {0x0000a194, 0x00000000}, | ||
1360 | {0x0000a198, 0x00000000}, | ||
1361 | {0x0000a19c, 0x00000000}, | ||
1362 | {0x0000a1a0, 0x00000000}, | ||
1363 | {0x0000a1a4, 0x00000000}, | ||
1364 | {0x0000a1a8, 0x00000000}, | ||
1365 | {0x0000a1ac, 0x00000000}, | ||
1366 | {0x0000a1b0, 0x00000000}, | ||
1367 | {0x0000a1b4, 0x00000000}, | ||
1368 | {0x0000a1b8, 0x00000000}, | ||
1369 | {0x0000a1bc, 0x00000000}, | ||
1370 | {0x0000a1c0, 0x00000000}, | ||
1371 | {0x0000a1c4, 0x00000000}, | ||
1372 | {0x0000a1c8, 0x00000000}, | ||
1373 | {0x0000a1cc, 0x00000000}, | ||
1374 | {0x0000a1d0, 0x00000000}, | ||
1375 | {0x0000a1d4, 0x00000000}, | ||
1376 | {0x0000a1d8, 0x00000000}, | ||
1377 | {0x0000a1dc, 0x00000000}, | ||
1378 | {0x0000a1e0, 0x00000000}, | ||
1379 | {0x0000a1e4, 0x00000000}, | ||
1380 | {0x0000a1e8, 0x00000000}, | ||
1381 | {0x0000a1ec, 0x00000000}, | ||
1382 | {0x0000a1f0, 0x00000396}, | ||
1383 | {0x0000a1f4, 0x00000396}, | ||
1384 | {0x0000a1f8, 0x00000396}, | ||
1385 | {0x0000a1fc, 0x00000196}, | ||
1386 | {0x0000b000, 0x00010000}, | ||
1387 | {0x0000b004, 0x00030002}, | ||
1388 | {0x0000b008, 0x00050004}, | ||
1389 | {0x0000b00c, 0x00810080}, | ||
1390 | {0x0000b010, 0x00830082}, | ||
1391 | {0x0000b014, 0x01810180}, | ||
1392 | {0x0000b018, 0x01830182}, | ||
1393 | {0x0000b01c, 0x01850184}, | ||
1394 | {0x0000b020, 0x02810280}, | ||
1395 | {0x0000b024, 0x02830282}, | ||
1396 | {0x0000b028, 0x02850284}, | ||
1397 | {0x0000b02c, 0x02890288}, | ||
1398 | {0x0000b030, 0x028b028a}, | ||
1399 | {0x0000b034, 0x0388028c}, | ||
1400 | {0x0000b038, 0x038a0389}, | ||
1401 | {0x0000b03c, 0x038c038b}, | ||
1402 | {0x0000b040, 0x0390038d}, | ||
1403 | {0x0000b044, 0x03920391}, | ||
1404 | {0x0000b048, 0x03940393}, | ||
1405 | {0x0000b04c, 0x03960395}, | ||
1406 | {0x0000b050, 0x00000000}, | ||
1407 | {0x0000b054, 0x00000000}, | ||
1408 | {0x0000b058, 0x00000000}, | ||
1409 | {0x0000b05c, 0x00000000}, | ||
1410 | {0x0000b060, 0x00000000}, | ||
1411 | {0x0000b064, 0x00000000}, | ||
1412 | {0x0000b068, 0x00000000}, | ||
1413 | {0x0000b06c, 0x00000000}, | ||
1414 | {0x0000b070, 0x00000000}, | ||
1415 | {0x0000b074, 0x00000000}, | ||
1416 | {0x0000b078, 0x00000000}, | ||
1417 | {0x0000b07c, 0x00000000}, | ||
1418 | {0x0000b080, 0x32323232}, | ||
1419 | {0x0000b084, 0x2f2f3232}, | ||
1420 | {0x0000b088, 0x23282a2d}, | ||
1421 | {0x0000b08c, 0x1c1e2123}, | ||
1422 | {0x0000b090, 0x14171919}, | ||
1423 | {0x0000b094, 0x0e0e1214}, | ||
1424 | {0x0000b098, 0x03050707}, | ||
1425 | {0x0000b09c, 0x00030303}, | ||
1426 | {0x0000b0a0, 0x00000000}, | ||
1427 | {0x0000b0a4, 0x00000000}, | ||
1428 | {0x0000b0a8, 0x00000000}, | ||
1429 | {0x0000b0ac, 0x00000000}, | ||
1430 | {0x0000b0b0, 0x00000000}, | ||
1431 | {0x0000b0b4, 0x00000000}, | ||
1432 | {0x0000b0b8, 0x00000000}, | ||
1433 | {0x0000b0bc, 0x00000000}, | ||
1434 | {0x0000b0c0, 0x003f0020}, | ||
1435 | {0x0000b0c4, 0x00400041}, | ||
1436 | {0x0000b0c8, 0x0140005f}, | ||
1437 | {0x0000b0cc, 0x0160015f}, | ||
1438 | {0x0000b0d0, 0x017e017f}, | ||
1439 | {0x0000b0d4, 0x02410242}, | ||
1440 | {0x0000b0d8, 0x025f0240}, | ||
1441 | {0x0000b0dc, 0x027f0260}, | ||
1442 | {0x0000b0e0, 0x0341027e}, | ||
1443 | {0x0000b0e4, 0x035f0340}, | ||
1444 | {0x0000b0e8, 0x037f0360}, | ||
1445 | {0x0000b0ec, 0x04400441}, | ||
1446 | {0x0000b0f0, 0x0460045f}, | ||
1447 | {0x0000b0f4, 0x0541047f}, | ||
1448 | {0x0000b0f8, 0x055f0540}, | ||
1449 | {0x0000b0fc, 0x057f0560}, | ||
1450 | {0x0000b100, 0x06400641}, | ||
1451 | {0x0000b104, 0x0660065f}, | ||
1452 | {0x0000b108, 0x067e067f}, | ||
1453 | {0x0000b10c, 0x07410742}, | ||
1454 | {0x0000b110, 0x075f0740}, | ||
1455 | {0x0000b114, 0x077f0760}, | ||
1456 | {0x0000b118, 0x07800781}, | ||
1457 | {0x0000b11c, 0x07a0079f}, | ||
1458 | {0x0000b120, 0x07c107bf}, | ||
1459 | {0x0000b124, 0x000007c0}, | ||
1460 | {0x0000b128, 0x00000000}, | ||
1461 | {0x0000b12c, 0x00000000}, | ||
1462 | {0x0000b130, 0x00000000}, | ||
1463 | {0x0000b134, 0x00000000}, | ||
1464 | {0x0000b138, 0x00000000}, | ||
1465 | {0x0000b13c, 0x00000000}, | ||
1466 | {0x0000b140, 0x003f0020}, | ||
1467 | {0x0000b144, 0x00400041}, | ||
1468 | {0x0000b148, 0x0140005f}, | ||
1469 | {0x0000b14c, 0x0160015f}, | ||
1470 | {0x0000b150, 0x017e017f}, | ||
1471 | {0x0000b154, 0x02410242}, | ||
1472 | {0x0000b158, 0x025f0240}, | ||
1473 | {0x0000b15c, 0x027f0260}, | ||
1474 | {0x0000b160, 0x0341027e}, | ||
1475 | {0x0000b164, 0x035f0340}, | ||
1476 | {0x0000b168, 0x037f0360}, | ||
1477 | {0x0000b16c, 0x04400441}, | ||
1478 | {0x0000b170, 0x0460045f}, | ||
1479 | {0x0000b174, 0x0541047f}, | ||
1480 | {0x0000b178, 0x055f0540}, | ||
1481 | {0x0000b17c, 0x057f0560}, | ||
1482 | {0x0000b180, 0x06400641}, | ||
1483 | {0x0000b184, 0x0660065f}, | ||
1484 | {0x0000b188, 0x067e067f}, | ||
1485 | {0x0000b18c, 0x07410742}, | ||
1486 | {0x0000b190, 0x075f0740}, | ||
1487 | {0x0000b194, 0x077f0760}, | ||
1488 | {0x0000b198, 0x07800781}, | ||
1489 | {0x0000b19c, 0x07a0079f}, | ||
1490 | {0x0000b1a0, 0x07c107bf}, | ||
1491 | {0x0000b1a4, 0x000007c0}, | ||
1492 | {0x0000b1a8, 0x00000000}, | ||
1493 | {0x0000b1ac, 0x00000000}, | ||
1494 | {0x0000b1b0, 0x00000000}, | ||
1495 | {0x0000b1b4, 0x00000000}, | ||
1496 | {0x0000b1b8, 0x00000000}, | ||
1497 | {0x0000b1bc, 0x00000000}, | ||
1498 | {0x0000b1c0, 0x00000000}, | ||
1499 | {0x0000b1c4, 0x00000000}, | ||
1500 | {0x0000b1c8, 0x00000000}, | ||
1501 | {0x0000b1cc, 0x00000000}, | ||
1502 | {0x0000b1d0, 0x00000000}, | ||
1503 | {0x0000b1d4, 0x00000000}, | ||
1504 | {0x0000b1d8, 0x00000000}, | ||
1505 | {0x0000b1dc, 0x00000000}, | ||
1506 | {0x0000b1e0, 0x00000000}, | ||
1507 | {0x0000b1e4, 0x00000000}, | ||
1508 | {0x0000b1e8, 0x00000000}, | ||
1509 | {0x0000b1ec, 0x00000000}, | ||
1510 | {0x0000b1f0, 0x00000396}, | ||
1511 | {0x0000b1f4, 0x00000396}, | ||
1512 | {0x0000b1f8, 0x00000396}, | ||
1513 | {0x0000b1fc, 0x00000196}, | ||
1514 | }; | ||
1515 | |||
1516 | static const u32 ar9340_1p0_soc_preamble[][2] = { | ||
1517 | /* Addr allmodes */ | ||
1518 | {0x000040a4, 0x00a0c1c9}, | ||
1519 | {0x00007008, 0x00000000}, | ||
1520 | {0x00007020, 0x00000000}, | ||
1521 | {0x00007034, 0x00000002}, | ||
1522 | {0x00007038, 0x000004c2}, | ||
1523 | }; | ||
1524 | |||
1525 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a6b538802251..0312aa091807 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -423,6 +423,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | |||
423 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ | 423 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ |
424 | 424 | ||
425 | void ath_hw_check(struct work_struct *work); | 425 | void ath_hw_check(struct work_struct *work); |
426 | void ath_hw_pll_work(struct work_struct *work); | ||
426 | void ath_paprd_calibrate(struct work_struct *work); | 427 | void ath_paprd_calibrate(struct work_struct *work); |
427 | void ath_ani_calibrate(unsigned long data); | 428 | void ath_ani_calibrate(unsigned long data); |
428 | 429 | ||
@@ -453,6 +454,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); | |||
453 | 454 | ||
454 | #define ATH_LED_PIN_DEF 1 | 455 | #define ATH_LED_PIN_DEF 1 |
455 | #define ATH_LED_PIN_9287 8 | 456 | #define ATH_LED_PIN_9287 8 |
457 | #define ATH_LED_PIN_9300 10 | ||
456 | #define ATH_LED_PIN_9485 6 | 458 | #define ATH_LED_PIN_9485 6 |
457 | 459 | ||
458 | #ifdef CONFIG_MAC80211_LEDS | 460 | #ifdef CONFIG_MAC80211_LEDS |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 24f565ba9988..22cd241a098b 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -781,12 +781,6 @@ void ath_set_beacon(struct ath_softc *sc) | |||
781 | break; | 781 | break; |
782 | case NL80211_IFTYPE_STATION: | 782 | case NL80211_IFTYPE_STATION: |
783 | ath_beacon_config_sta(sc, cur_conf); | 783 | ath_beacon_config_sta(sc, cur_conf); |
784 | /* | ||
785 | * Request a re-configuration of Beacon related timers | ||
786 | * on the receipt of the first Beacon frame (i.e., | ||
787 | * after time sync with the AP). | ||
788 | */ | ||
789 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
790 | break; | 784 | break; |
791 | default: | 785 | default: |
792 | ath_dbg(common, ATH_DBG_CONFIG, | 786 | ath_dbg(common, ATH_DBG_CONFIG, |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index d33bf204c995..23f15a7ca7f1 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c | |||
@@ -51,6 +51,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) | |||
51 | .bt_hold_rx_clear = true, | 51 | .bt_hold_rx_clear = true, |
52 | }; | 52 | }; |
53 | u32 i; | 53 | u32 i; |
54 | bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; | ||
55 | |||
56 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
57 | rxclear_polarity = !ath_bt_config.bt_rxclear_polarity; | ||
54 | 58 | ||
55 | btcoex_hw->bt_coex_mode = | 59 | btcoex_hw->bt_coex_mode = |
56 | (btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) | | 60 | (btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) | |
@@ -59,7 +63,7 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) | |||
59 | SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) | | 63 | SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) | |
60 | SM(ath_bt_config.bt_mode, AR_BT_MODE) | | 64 | SM(ath_bt_config.bt_mode, AR_BT_MODE) | |
61 | SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) | | 65 | SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) | |
62 | SM(ath_bt_config.bt_rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) | | 66 | SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) | |
63 | SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) | | 67 | SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) | |
64 | SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) | | 68 | SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) | |
65 | SM(qnum, AR_BT_QCU_THRESH); | 69 | SM(qnum, AR_BT_QCU_THRESH); |
@@ -142,6 +146,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, | |||
142 | } | 146 | } |
143 | EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); | 147 | EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); |
144 | 148 | ||
149 | |||
145 | static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) | 150 | static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) |
146 | { | 151 | { |
147 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 152 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
@@ -152,9 +157,22 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) | |||
152 | * enable coex 3-wire | 157 | * enable coex 3-wire |
153 | */ | 158 | */ |
154 | REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode); | 159 | REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode); |
155 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); | ||
156 | REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); | 160 | REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); |
157 | 161 | ||
162 | |||
163 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
164 | REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, ah->bt_coex_wlan_weight[0]); | ||
165 | REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, ah->bt_coex_wlan_weight[1]); | ||
166 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, ah->bt_coex_bt_weight[0]); | ||
167 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, ah->bt_coex_bt_weight[1]); | ||
168 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, ah->bt_coex_bt_weight[2]); | ||
169 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, ah->bt_coex_bt_weight[3]); | ||
170 | |||
171 | } else | ||
172 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); | ||
173 | |||
174 | |||
175 | |||
158 | if (AR_SREV_9271(ah)) { | 176 | if (AR_SREV_9271(ah)) { |
159 | val = REG_READ(ah, 0x50040); | 177 | val = REG_READ(ah, 0x50040); |
160 | val &= 0xFFFFFEFF; | 178 | val &= 0xFFFFFEFF; |
@@ -202,10 +220,86 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) | |||
202 | 220 | ||
203 | if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) { | 221 | if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) { |
204 | REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE); | 222 | REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE); |
205 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0); | ||
206 | REG_WRITE(ah, AR_BT_COEX_MODE2, 0); | 223 | REG_WRITE(ah, AR_BT_COEX_MODE2, 0); |
224 | |||
225 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
226 | REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0); | ||
227 | REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0); | ||
228 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, 0); | ||
229 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, 0); | ||
230 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, 0); | ||
231 | REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, 0); | ||
232 | } else | ||
233 | REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0); | ||
234 | |||
207 | } | 235 | } |
208 | 236 | ||
209 | ah->btcoex_hw.enabled = false; | 237 | ah->btcoex_hw.enabled = false; |
210 | } | 238 | } |
211 | EXPORT_SYMBOL(ath9k_hw_btcoex_disable); | 239 | EXPORT_SYMBOL(ath9k_hw_btcoex_disable); |
240 | |||
241 | static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, | ||
242 | enum ath_stomp_type stomp_type) | ||
243 | { | ||
244 | ah->bt_coex_bt_weight[0] = AR9300_BT_WGHT; | ||
245 | ah->bt_coex_bt_weight[1] = AR9300_BT_WGHT; | ||
246 | ah->bt_coex_bt_weight[2] = AR9300_BT_WGHT; | ||
247 | ah->bt_coex_bt_weight[3] = AR9300_BT_WGHT; | ||
248 | |||
249 | |||
250 | switch (stomp_type) { | ||
251 | case ATH_BTCOEX_STOMP_ALL: | ||
252 | ah->bt_coex_wlan_weight[0] = AR9300_STOMP_ALL_WLAN_WGHT0; | ||
253 | ah->bt_coex_wlan_weight[1] = AR9300_STOMP_ALL_WLAN_WGHT1; | ||
254 | break; | ||
255 | case ATH_BTCOEX_STOMP_LOW: | ||
256 | ah->bt_coex_wlan_weight[0] = AR9300_STOMP_LOW_WLAN_WGHT0; | ||
257 | ah->bt_coex_wlan_weight[1] = AR9300_STOMP_LOW_WLAN_WGHT1; | ||
258 | break; | ||
259 | case ATH_BTCOEX_STOMP_NONE: | ||
260 | ah->bt_coex_wlan_weight[0] = AR9300_STOMP_NONE_WLAN_WGHT0; | ||
261 | ah->bt_coex_wlan_weight[1] = AR9300_STOMP_NONE_WLAN_WGHT1; | ||
262 | break; | ||
263 | |||
264 | default: | ||
265 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
266 | "Invalid Stomptype\n"); | ||
267 | break; | ||
268 | } | ||
269 | |||
270 | ath9k_hw_btcoex_enable(ah); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * Configures appropriate weight based on stomp type. | ||
275 | */ | ||
276 | void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, | ||
277 | enum ath_stomp_type stomp_type) | ||
278 | { | ||
279 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
280 | ar9003_btcoex_bt_stomp(ah, stomp_type); | ||
281 | return; | ||
282 | } | ||
283 | |||
284 | switch (stomp_type) { | ||
285 | case ATH_BTCOEX_STOMP_ALL: | ||
286 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
287 | AR_STOMP_ALL_WLAN_WGHT); | ||
288 | break; | ||
289 | case ATH_BTCOEX_STOMP_LOW: | ||
290 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
291 | AR_STOMP_LOW_WLAN_WGHT); | ||
292 | break; | ||
293 | case ATH_BTCOEX_STOMP_NONE: | ||
294 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
295 | AR_STOMP_NONE_WLAN_WGHT); | ||
296 | break; | ||
297 | default: | ||
298 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||
299 | "Invalid Stomptype\n"); | ||
300 | break; | ||
301 | } | ||
302 | |||
303 | ath9k_hw_btcoex_enable(ah); | ||
304 | } | ||
305 | EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp); | ||
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 588dfd464dd1..a9efca83d676 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h | |||
@@ -19,9 +19,13 @@ | |||
19 | 19 | ||
20 | #include "hw.h" | 20 | #include "hw.h" |
21 | 21 | ||
22 | #define ATH_WLANACTIVE_GPIO 5 | 22 | #define ATH_WLANACTIVE_GPIO_9280 5 |
23 | #define ATH_BTACTIVE_GPIO 6 | 23 | #define ATH_BTACTIVE_GPIO_9280 6 |
24 | #define ATH_BTPRIORITY_GPIO 7 | 24 | #define ATH_BTPRIORITY_GPIO_9285 7 |
25 | |||
26 | #define ATH_WLANACTIVE_GPIO_9300 5 | ||
27 | #define ATH_BTACTIVE_GPIO_9300 4 | ||
28 | #define ATH_BTPRIORITY_GPIO_9300 8 | ||
25 | 29 | ||
26 | #define ATH_BTCOEX_DEF_BT_PERIOD 45 | 30 | #define ATH_BTCOEX_DEF_BT_PERIOD 45 |
27 | #define ATH_BTCOEX_DEF_DUTY_CYCLE 55 | 31 | #define ATH_BTCOEX_DEF_DUTY_CYCLE 55 |
@@ -32,6 +36,14 @@ | |||
32 | #define ATH_BT_CNT_THRESHOLD 3 | 36 | #define ATH_BT_CNT_THRESHOLD 3 |
33 | #define ATH_BT_CNT_SCAN_THRESHOLD 15 | 37 | #define ATH_BT_CNT_SCAN_THRESHOLD 15 |
34 | 38 | ||
39 | /* Defines the BT AR_BT_COEX_WGHT used */ | ||
40 | enum ath_stomp_type { | ||
41 | ATH_BTCOEX_NO_STOMP, | ||
42 | ATH_BTCOEX_STOMP_ALL, | ||
43 | ATH_BTCOEX_STOMP_LOW, | ||
44 | ATH_BTCOEX_STOMP_NONE | ||
45 | }; | ||
46 | |||
35 | enum ath_btcoex_scheme { | 47 | enum ath_btcoex_scheme { |
36 | ATH_BTCOEX_CFG_NONE, | 48 | ATH_BTCOEX_CFG_NONE, |
37 | ATH_BTCOEX_CFG_2WIRE, | 49 | ATH_BTCOEX_CFG_2WIRE, |
@@ -57,5 +69,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, | |||
57 | u32 wlan_weight); | 69 | u32 wlan_weight); |
58 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); | 70 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); |
59 | void ath9k_hw_btcoex_disable(struct ath_hw *ah); | 71 | void ath9k_hw_btcoex_disable(struct ath_hw *ah); |
72 | void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, | ||
73 | enum ath_stomp_type stomp_type); | ||
60 | 74 | ||
61 | #endif | 75 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 16ba8c67fbd5..74535e6dfb82 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -158,37 +158,6 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max) | |||
158 | } | 158 | } |
159 | EXPORT_SYMBOL(ath9k_cmn_count_streams); | 159 | EXPORT_SYMBOL(ath9k_cmn_count_streams); |
160 | 160 | ||
161 | /* | ||
162 | * Configures appropriate weight based on stomp type. | ||
163 | */ | ||
164 | void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, | ||
165 | enum ath_stomp_type stomp_type) | ||
166 | { | ||
167 | struct ath_hw *ah = common->ah; | ||
168 | |||
169 | switch (stomp_type) { | ||
170 | case ATH_BTCOEX_STOMP_ALL: | ||
171 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
172 | AR_STOMP_ALL_WLAN_WGHT); | ||
173 | break; | ||
174 | case ATH_BTCOEX_STOMP_LOW: | ||
175 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
176 | AR_STOMP_LOW_WLAN_WGHT); | ||
177 | break; | ||
178 | case ATH_BTCOEX_STOMP_NONE: | ||
179 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||
180 | AR_STOMP_NONE_WLAN_WGHT); | ||
181 | break; | ||
182 | default: | ||
183 | ath_dbg(common, ATH_DBG_BTCOEX, | ||
184 | "Invalid Stomptype\n"); | ||
185 | break; | ||
186 | } | ||
187 | |||
188 | ath9k_hw_btcoex_enable(ah); | ||
189 | } | ||
190 | EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp); | ||
191 | |||
192 | void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, | 161 | void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, |
193 | u16 new_txpow, u16 *txpower) | 162 | u16 new_txpow, u16 *txpower) |
194 | { | 163 | { |
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index b2f7b5f89097..5124f1420b3a 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -50,14 +50,6 @@ | |||
50 | #define ATH_EP_RND(x, mul) \ | 50 | #define ATH_EP_RND(x, mul) \ |
51 | ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) | 51 | ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) |
52 | 52 | ||
53 | /* Defines the BT AR_BT_COEX_WGHT used */ | ||
54 | enum ath_stomp_type { | ||
55 | ATH_BTCOEX_NO_STOMP, | ||
56 | ATH_BTCOEX_STOMP_ALL, | ||
57 | ATH_BTCOEX_STOMP_LOW, | ||
58 | ATH_BTCOEX_STOMP_NONE | ||
59 | }; | ||
60 | |||
61 | int ath9k_cmn_padpos(__le16 frame_control); | 53 | int ath9k_cmn_padpos(__le16 frame_control); |
62 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); | 54 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); |
63 | void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, | 55 | void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 34f191ec8e8c..bad1a87249b6 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -326,6 +326,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) | |||
326 | sc->debug.stats.istats.dtimsync++; | 326 | sc->debug.stats.istats.dtimsync++; |
327 | if (status & ATH9K_INT_DTIM) | 327 | if (status & ATH9K_INT_DTIM) |
328 | sc->debug.stats.istats.dtim++; | 328 | sc->debug.stats.istats.dtim++; |
329 | if (status & ATH9K_INT_TSFOOR) | ||
330 | sc->debug.stats.istats.tsfoor++; | ||
329 | } | 331 | } |
330 | 332 | ||
331 | static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | 333 | static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, |
@@ -380,8 +382,11 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | |||
380 | len += snprintf(buf + len, sizeof(buf) - len, | 382 | len += snprintf(buf + len, sizeof(buf) - len, |
381 | "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); | 383 | "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); |
382 | len += snprintf(buf + len, sizeof(buf) - len, | 384 | len += snprintf(buf + len, sizeof(buf) - len, |
385 | "%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor); | ||
386 | len += snprintf(buf + len, sizeof(buf) - len, | ||
383 | "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); | 387 | "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); |
384 | 388 | ||
389 | |||
385 | if (len > sizeof(buf)) | 390 | if (len > sizeof(buf)) |
386 | len = sizeof(buf); | 391 | len = sizeof(buf); |
387 | 392 | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 1f9f8eada465..5488a324cc10 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -54,6 +54,9 @@ struct ath_buf; | |||
54 | * @dtimsync: DTIM sync lossage | 54 | * @dtimsync: DTIM sync lossage |
55 | * @dtim: RX Beacon with DTIM | 55 | * @dtim: RX Beacon with DTIM |
56 | * @bb_watchdog: Baseband watchdog | 56 | * @bb_watchdog: Baseband watchdog |
57 | * @tsfoor: TSF out of range, indicates that the corrected TSF received | ||
58 | * from a beacon differs from the PCU's internal TSF by more than a | ||
59 | * (programmable) threshold | ||
57 | */ | 60 | */ |
58 | struct ath_interrupt_stats { | 61 | struct ath_interrupt_stats { |
59 | u32 total; | 62 | u32 total; |
@@ -78,6 +81,7 @@ struct ath_interrupt_stats { | |||
78 | u32 dtimsync; | 81 | u32 dtimsync; |
79 | u32 dtim; | 82 | u32 dtim; |
80 | u32 bb_watchdog; | 83 | u32 bb_watchdog; |
84 | u32 tsfoor; | ||
81 | }; | 85 | }; |
82 | 86 | ||
83 | /** | 87 | /** |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 13579752a300..b87db4763098 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -319,10 +319,9 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, | |||
319 | u16 numXpdGain, xpdMask; | 319 | u16 numXpdGain, xpdMask; |
320 | u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0}; | 320 | u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0}; |
321 | u32 reg32, regOffset, regChainOffset, regval; | 321 | u32 reg32, regOffset, regChainOffset, regval; |
322 | int16_t modalIdx, diff = 0; | 322 | int16_t diff = 0; |
323 | struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; | 323 | struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; |
324 | 324 | ||
325 | modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; | ||
326 | xpdMask = pEepData->modalHeader.xpdGain; | 325 | xpdMask = pEepData->modalHeader.xpdGain; |
327 | 326 | ||
328 | if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= | 327 | if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 995949ddd63e..c031854b569f 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -231,6 +231,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
231 | integer = swab32(pModal->antCtrlChain[i]); | 231 | integer = swab32(pModal->antCtrlChain[i]); |
232 | pModal->antCtrlChain[i] = integer; | 232 | pModal->antCtrlChain[i] = integer; |
233 | } | 233 | } |
234 | for (i = 0; i < 3; i++) { | ||
235 | word = swab16(pModal->xpaBiasLvlFreq[i]); | ||
236 | pModal->xpaBiasLvlFreq[i] = word; | ||
237 | } | ||
234 | 238 | ||
235 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | 239 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { |
236 | word = swab16(pModal->spurChans[i].spurChan); | 240 | word = swab16(pModal->spurChans[i].spurChan); |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 44a0a886124d..0349b3a1cc58 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -46,6 +46,8 @@ void ath_init_leds(struct ath_softc *sc) | |||
46 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; | 46 | sc->sc_ah->led_pin = ATH_LED_PIN_9287; |
47 | else if (AR_SREV_9485(sc->sc_ah)) | 47 | else if (AR_SREV_9485(sc->sc_ah)) |
48 | sc->sc_ah->led_pin = ATH_LED_PIN_9485; | 48 | sc->sc_ah->led_pin = ATH_LED_PIN_9485; |
49 | else if (AR_SREV_9300(sc->sc_ah)) | ||
50 | sc->sc_ah->led_pin = ATH_LED_PIN_9300; | ||
49 | else | 51 | else |
50 | sc->sc_ah->led_pin = ATH_LED_PIN_DEF; | 52 | sc->sc_ah->led_pin = ATH_LED_PIN_DEF; |
51 | } | 53 | } |
@@ -138,10 +140,10 @@ static void ath_detect_bt_priority(struct ath_softc *sc) | |||
138 | 140 | ||
139 | static void ath9k_gen_timer_start(struct ath_hw *ah, | 141 | static void ath9k_gen_timer_start(struct ath_hw *ah, |
140 | struct ath_gen_timer *timer, | 142 | struct ath_gen_timer *timer, |
141 | u32 timer_next, | 143 | u32 trig_timeout, |
142 | u32 timer_period) | 144 | u32 timer_period) |
143 | { | 145 | { |
144 | ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); | 146 | ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period); |
145 | 147 | ||
146 | if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { | 148 | if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { |
147 | ath9k_hw_disable_interrupts(ah); | 149 | ath9k_hw_disable_interrupts(ah); |
@@ -174,17 +176,17 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
174 | struct ath_softc *sc = (struct ath_softc *) data; | 176 | struct ath_softc *sc = (struct ath_softc *) data; |
175 | struct ath_hw *ah = sc->sc_ah; | 177 | struct ath_hw *ah = sc->sc_ah; |
176 | struct ath_btcoex *btcoex = &sc->btcoex; | 178 | struct ath_btcoex *btcoex = &sc->btcoex; |
177 | struct ath_common *common = ath9k_hw_common(ah); | ||
178 | u32 timer_period; | 179 | u32 timer_period; |
179 | bool is_btscan; | 180 | bool is_btscan; |
180 | 181 | ||
182 | ath9k_ps_wakeup(sc); | ||
181 | ath_detect_bt_priority(sc); | 183 | ath_detect_bt_priority(sc); |
182 | 184 | ||
183 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | 185 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; |
184 | 186 | ||
185 | spin_lock_bh(&btcoex->btcoex_lock); | 187 | spin_lock_bh(&btcoex->btcoex_lock); |
186 | 188 | ||
187 | ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : | 189 | ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : |
188 | btcoex->bt_stomp_type); | 190 | btcoex->bt_stomp_type); |
189 | 191 | ||
190 | spin_unlock_bh(&btcoex->btcoex_lock); | 192 | spin_unlock_bh(&btcoex->btcoex_lock); |
@@ -195,11 +197,12 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
195 | 197 | ||
196 | timer_period = is_btscan ? btcoex->btscan_no_stomp : | 198 | timer_period = is_btscan ? btcoex->btscan_no_stomp : |
197 | btcoex->btcoex_no_stomp; | 199 | btcoex->btcoex_no_stomp; |
198 | ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0, | 200 | ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period, |
199 | timer_period * 10); | 201 | timer_period * 10); |
200 | btcoex->hw_timer_enabled = true; | 202 | btcoex->hw_timer_enabled = true; |
201 | } | 203 | } |
202 | 204 | ||
205 | ath9k_ps_restore(sc); | ||
203 | mod_timer(&btcoex->period_timer, jiffies + | 206 | mod_timer(&btcoex->period_timer, jiffies + |
204 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | 207 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); |
205 | } | 208 | } |
@@ -219,14 +222,16 @@ static void ath_btcoex_no_stomp_timer(void *arg) | |||
219 | ath_dbg(common, ATH_DBG_BTCOEX, | 222 | ath_dbg(common, ATH_DBG_BTCOEX, |
220 | "no stomp timer running\n"); | 223 | "no stomp timer running\n"); |
221 | 224 | ||
225 | ath9k_ps_wakeup(sc); | ||
222 | spin_lock_bh(&btcoex->btcoex_lock); | 226 | spin_lock_bh(&btcoex->btcoex_lock); |
223 | 227 | ||
224 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | 228 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) |
225 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); | 229 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
226 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | 230 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) |
227 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); | 231 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); |
228 | 232 | ||
229 | spin_unlock_bh(&btcoex->btcoex_lock); | 233 | spin_unlock_bh(&btcoex->btcoex_lock); |
234 | ath9k_ps_restore(sc); | ||
230 | } | 235 | } |
231 | 236 | ||
232 | int ath_init_btcoex_timer(struct ath_softc *sc) | 237 | int ath_init_btcoex_timer(struct ath_softc *sc) |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index f59df48a86e2..2bdcdbc14b1e 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h | |||
@@ -17,6 +17,9 @@ | |||
17 | #ifndef HTC_USB_H | 17 | #ifndef HTC_USB_H |
18 | #define HTC_USB_H | 18 | #define HTC_USB_H |
19 | 19 | ||
20 | #define MAJOR_VERSION_REQ 1 | ||
21 | #define MINOR_VERSION_REQ 2 | ||
22 | |||
20 | #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) | 23 | #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) |
21 | 24 | ||
22 | #define AR9271_FIRMWARE 0x501000 | 25 | #define AR9271_FIRMWARE 0x501000 |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 48a885575085..dfc7a982fc7e 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -66,8 +66,6 @@ enum htc_opmode { | |||
66 | HTC_M_WDS = 2 | 66 | HTC_M_WDS = 2 |
67 | }; | 67 | }; |
68 | 68 | ||
69 | #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) | ||
70 | |||
71 | #define ATH9K_HTC_AMPDU 1 | 69 | #define ATH9K_HTC_AMPDU 1 |
72 | #define ATH9K_HTC_NORMAL 2 | 70 | #define ATH9K_HTC_NORMAL 2 |
73 | #define ATH9K_HTC_BEACON 3 | 71 | #define ATH9K_HTC_BEACON 3 |
@@ -75,7 +73,6 @@ enum htc_opmode { | |||
75 | 73 | ||
76 | #define ATH9K_HTC_TX_CTSONLY 0x1 | 74 | #define ATH9K_HTC_TX_CTSONLY 0x1 |
77 | #define ATH9K_HTC_TX_RTSCTS 0x2 | 75 | #define ATH9K_HTC_TX_RTSCTS 0x2 |
78 | #define ATH9K_HTC_TX_USE_MIN_RATE 0x100 | ||
79 | 76 | ||
80 | struct tx_frame_hdr { | 77 | struct tx_frame_hdr { |
81 | u8 data_type; | 78 | u8 data_type; |
@@ -106,15 +103,14 @@ struct tx_beacon_header { | |||
106 | u16 rev; | 103 | u16 rev; |
107 | } __packed; | 104 | } __packed; |
108 | 105 | ||
106 | #define MAX_TX_AMPDU_SUBFRAMES_9271 17 | ||
107 | #define MAX_TX_AMPDU_SUBFRAMES_7010 22 | ||
108 | |||
109 | struct ath9k_htc_cap_target { | 109 | struct ath9k_htc_cap_target { |
110 | u32 flags; | 110 | __be32 ampdu_limit; |
111 | u32 flags_ext; | ||
112 | u32 ampdu_limit; | ||
113 | u8 ampdu_subframes; | 111 | u8 ampdu_subframes; |
112 | u8 enable_coex; | ||
114 | u8 tx_chainmask; | 113 | u8 tx_chainmask; |
115 | u8 tx_chainmask_legacy; | ||
116 | u8 rtscts_ratecode; | ||
117 | u8 protmode; | ||
118 | u8 pad; | 114 | u8 pad; |
119 | } __packed; | 115 | } __packed; |
120 | 116 | ||
@@ -175,6 +171,13 @@ struct ath9k_htc_target_rate { | |||
175 | struct ath9k_htc_rate rates; | 171 | struct ath9k_htc_rate rates; |
176 | }; | 172 | }; |
177 | 173 | ||
174 | struct ath9k_htc_target_rate_mask { | ||
175 | u8 vif_index; | ||
176 | u8 band; | ||
177 | __be32 mask; | ||
178 | u16 pad; | ||
179 | } __packed; | ||
180 | |||
178 | struct ath9k_htc_target_int_stats { | 181 | struct ath9k_htc_target_int_stats { |
179 | __be32 rx; | 182 | __be32 rx; |
180 | __be32 rxorn; | 183 | __be32 rxorn; |
@@ -382,25 +385,6 @@ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | |||
382 | #define ATH_LED_PIN_9287 10 | 385 | #define ATH_LED_PIN_9287 10 |
383 | #define ATH_LED_PIN_9271 15 | 386 | #define ATH_LED_PIN_9271 15 |
384 | #define ATH_LED_PIN_7010 12 | 387 | #define ATH_LED_PIN_7010 12 |
385 | #define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ | ||
386 | #define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ | ||
387 | |||
388 | enum ath_led_type { | ||
389 | ATH_LED_RADIO, | ||
390 | ATH_LED_ASSOC, | ||
391 | ATH_LED_TX, | ||
392 | ATH_LED_RX | ||
393 | }; | ||
394 | |||
395 | struct ath_led { | ||
396 | struct ath9k_htc_priv *priv; | ||
397 | struct led_classdev led_cdev; | ||
398 | enum ath_led_type led_type; | ||
399 | struct delayed_work brightness_work; | ||
400 | char name[32]; | ||
401 | bool registered; | ||
402 | int brightness; | ||
403 | }; | ||
404 | 388 | ||
405 | #define BSTUCK_THRESHOLD 10 | 389 | #define BSTUCK_THRESHOLD 10 |
406 | 390 | ||
@@ -434,14 +418,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); | |||
434 | 418 | ||
435 | #define OP_INVALID BIT(0) | 419 | #define OP_INVALID BIT(0) |
436 | #define OP_SCANNING BIT(1) | 420 | #define OP_SCANNING BIT(1) |
437 | #define OP_LED_ASSOCIATED BIT(2) | 421 | #define OP_ENABLE_BEACON BIT(2) |
438 | #define OP_LED_ON BIT(3) | 422 | #define OP_BT_PRIORITY_DETECTED BIT(3) |
439 | #define OP_ENABLE_BEACON BIT(4) | 423 | #define OP_BT_SCAN BIT(4) |
440 | #define OP_LED_DEINIT BIT(5) | 424 | #define OP_ANI_RUNNING BIT(5) |
441 | #define OP_BT_PRIORITY_DETECTED BIT(6) | 425 | #define OP_TSF_RESET BIT(6) |
442 | #define OP_BT_SCAN BIT(7) | ||
443 | #define OP_ANI_RUNNING BIT(8) | ||
444 | #define OP_TSF_RESET BIT(9) | ||
445 | 426 | ||
446 | struct ath9k_htc_priv { | 427 | struct ath9k_htc_priv { |
447 | struct device *dev; | 428 | struct device *dev; |
@@ -501,15 +482,13 @@ struct ath9k_htc_priv { | |||
501 | bool ps_enabled; | 482 | bool ps_enabled; |
502 | bool ps_idle; | 483 | bool ps_idle; |
503 | 484 | ||
504 | struct ath_led radio_led; | 485 | #ifdef CONFIG_MAC80211_LEDS |
505 | struct ath_led assoc_led; | 486 | enum led_brightness brightness; |
506 | struct ath_led tx_led; | 487 | bool led_registered; |
507 | struct ath_led rx_led; | 488 | char led_name[32]; |
508 | struct delayed_work ath9k_led_blink_work; | 489 | struct led_classdev led_cdev; |
509 | int led_on_duration; | 490 | struct work_struct led_work; |
510 | int led_off_duration; | 491 | #endif |
511 | int led_on_cnt; | ||
512 | int led_off_cnt; | ||
513 | 492 | ||
514 | int beaconq; | 493 | int beaconq; |
515 | int cabq; | 494 | int cabq; |
@@ -551,7 +530,8 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, | |||
551 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | 530 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, |
552 | enum htc_endpoint_id ep_id, bool txok); | 531 | enum htc_endpoint_id ep_id, bool txok); |
553 | 532 | ||
554 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv); | 533 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv, |
534 | u8 enable_coex); | ||
555 | void ath9k_htc_station_work(struct work_struct *work); | 535 | void ath9k_htc_station_work(struct work_struct *work); |
556 | void ath9k_htc_aggr_work(struct work_struct *work); | 536 | void ath9k_htc_aggr_work(struct work_struct *work); |
557 | void ath9k_htc_ani_work(struct work_struct *work); | 537 | void ath9k_htc_ani_work(struct work_struct *work); |
@@ -593,9 +573,24 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); | |||
593 | void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); | 573 | void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); |
594 | void ath9k_htc_radio_enable(struct ieee80211_hw *hw); | 574 | void ath9k_htc_radio_enable(struct ieee80211_hw *hw); |
595 | void ath9k_htc_radio_disable(struct ieee80211_hw *hw); | 575 | void ath9k_htc_radio_disable(struct ieee80211_hw *hw); |
596 | void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv); | 576 | |
577 | #ifdef CONFIG_MAC80211_LEDS | ||
597 | void ath9k_init_leds(struct ath9k_htc_priv *priv); | 578 | void ath9k_init_leds(struct ath9k_htc_priv *priv); |
598 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv); | 579 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv); |
580 | void ath9k_led_work(struct work_struct *work); | ||
581 | #else | ||
582 | static inline void ath9k_init_leds(struct ath9k_htc_priv *priv) | ||
583 | { | ||
584 | } | ||
585 | |||
586 | static inline void ath9k_deinit_leds(struct ath9k_htc_priv *priv) | ||
587 | { | ||
588 | } | ||
589 | |||
590 | static inline void ath9k_led_work(struct work_struct *work) | ||
591 | { | ||
592 | } | ||
593 | #endif | ||
599 | 594 | ||
600 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | 595 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, |
601 | u16 devid, char *product, u32 drv_info); | 596 | u16 devid, char *product, u32 drv_info); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index a157107b3f3b..0ded2c66d5ff 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -74,7 +74,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | |||
74 | __be32 htc_imask = 0; | 74 | __be32 htc_imask = 0; |
75 | u64 tsf; | 75 | u64 tsf; |
76 | int num_beacons, offset, dtim_dec_count, cfp_dec_count; | 76 | int num_beacons, offset, dtim_dec_count, cfp_dec_count; |
77 | int ret; | 77 | int ret __attribute__ ((unused)); |
78 | u8 cmd_rsp; | 78 | u8 cmd_rsp; |
79 | 79 | ||
80 | memset(&bs, 0, sizeof(bs)); | 80 | memset(&bs, 0, sizeof(bs)); |
@@ -190,7 +190,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
190 | enum ath9k_int imask = 0; | 190 | enum ath9k_int imask = 0; |
191 | u32 nexttbtt, intval, tsftu; | 191 | u32 nexttbtt, intval, tsftu; |
192 | __be32 htc_imask = 0; | 192 | __be32 htc_imask = 0; |
193 | int ret; | 193 | int ret __attribute__ ((unused)); |
194 | u8 cmd_rsp; | 194 | u8 cmd_rsp; |
195 | u64 tsf; | 195 | u64 tsf; |
196 | 196 | ||
@@ -246,7 +246,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | |||
246 | enum ath9k_int imask = 0; | 246 | enum ath9k_int imask = 0; |
247 | u32 nexttbtt, intval, tsftu; | 247 | u32 nexttbtt, intval, tsftu; |
248 | __be32 htc_imask = 0; | 248 | __be32 htc_imask = 0; |
249 | int ret; | 249 | int ret __attribute__ ((unused)); |
250 | u8 cmd_rsp; | 250 | u8 cmd_rsp; |
251 | u64 tsf; | 251 | u64 tsf; |
252 | 252 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index eca777497fe5..aa48b3abbc48 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c | |||
@@ -33,9 +33,15 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, | |||
33 | 33 | ||
34 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | 34 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); |
35 | 35 | ||
36 | ath9k_htc_ps_wakeup(priv); | ||
37 | |||
36 | WMI_CMD(WMI_INT_STATS_CMDID); | 38 | WMI_CMD(WMI_INT_STATS_CMDID); |
37 | if (ret) | 39 | if (ret) { |
40 | ath9k_htc_ps_restore(priv); | ||
38 | return -EINVAL; | 41 | return -EINVAL; |
42 | } | ||
43 | |||
44 | ath9k_htc_ps_restore(priv); | ||
39 | 45 | ||
40 | len += snprintf(buf + len, sizeof(buf) - len, | 46 | len += snprintf(buf + len, sizeof(buf) - len, |
41 | "%20s : %10u\n", "RX", | 47 | "%20s : %10u\n", "RX", |
@@ -85,9 +91,15 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, | |||
85 | 91 | ||
86 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | 92 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); |
87 | 93 | ||
94 | ath9k_htc_ps_wakeup(priv); | ||
95 | |||
88 | WMI_CMD(WMI_TX_STATS_CMDID); | 96 | WMI_CMD(WMI_TX_STATS_CMDID); |
89 | if (ret) | 97 | if (ret) { |
98 | ath9k_htc_ps_restore(priv); | ||
90 | return -EINVAL; | 99 | return -EINVAL; |
100 | } | ||
101 | |||
102 | ath9k_htc_ps_restore(priv); | ||
91 | 103 | ||
92 | len += snprintf(buf + len, sizeof(buf) - len, | 104 | len += snprintf(buf + len, sizeof(buf) - len, |
93 | "%20s : %10u\n", "Xretries", | 105 | "%20s : %10u\n", "Xretries", |
@@ -149,9 +161,15 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, | |||
149 | 161 | ||
150 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | 162 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); |
151 | 163 | ||
164 | ath9k_htc_ps_wakeup(priv); | ||
165 | |||
152 | WMI_CMD(WMI_RX_STATS_CMDID); | 166 | WMI_CMD(WMI_RX_STATS_CMDID); |
153 | if (ret) | 167 | if (ret) { |
168 | ath9k_htc_ps_restore(priv); | ||
154 | return -EINVAL; | 169 | return -EINVAL; |
170 | } | ||
171 | |||
172 | ath9k_htc_ps_restore(priv); | ||
155 | 173 | ||
156 | len += snprintf(buf + len, sizeof(buf) - len, | 174 | len += snprintf(buf + len, sizeof(buf) - len, |
157 | "%20s : %10u\n", "NoBuf", | 175 | "%20s : %10u\n", "NoBuf", |
@@ -474,6 +492,439 @@ static const struct file_operations fops_debug = { | |||
474 | .llseek = default_llseek, | 492 | .llseek = default_llseek, |
475 | }; | 493 | }; |
476 | 494 | ||
495 | static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, | ||
496 | size_t count, loff_t *ppos) | ||
497 | { | ||
498 | struct ath9k_htc_priv *priv = file->private_data; | ||
499 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
500 | struct base_eep_header *pBase = NULL; | ||
501 | unsigned int len = 0, size = 1500; | ||
502 | ssize_t retval = 0; | ||
503 | char *buf; | ||
504 | |||
505 | /* | ||
506 | * This can be done since all the 3 EEPROM families have the | ||
507 | * same base header upto a certain point, and we are interested in | ||
508 | * the data only upto that point. | ||
509 | */ | ||
510 | |||
511 | if (AR_SREV_9271(priv->ah)) | ||
512 | pBase = (struct base_eep_header *) | ||
513 | &priv->ah->eeprom.map4k.baseEepHeader; | ||
514 | else if (priv->ah->hw_version.usbdev == AR9280_USB) | ||
515 | pBase = (struct base_eep_header *) | ||
516 | &priv->ah->eeprom.def.baseEepHeader; | ||
517 | else if (priv->ah->hw_version.usbdev == AR9287_USB) | ||
518 | pBase = (struct base_eep_header *) | ||
519 | &priv->ah->eeprom.map9287.baseEepHeader; | ||
520 | |||
521 | if (pBase == NULL) { | ||
522 | ath_err(common, "Unknown EEPROM type\n"); | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | buf = kzalloc(size, GFP_KERNEL); | ||
527 | if (buf == NULL) | ||
528 | return -ENOMEM; | ||
529 | |||
530 | len += snprintf(buf + len, size - len, | ||
531 | "%20s : %10d\n", "Major Version", | ||
532 | pBase->version >> 12); | ||
533 | len += snprintf(buf + len, size - len, | ||
534 | "%20s : %10d\n", "Minor Version", | ||
535 | pBase->version & 0xFFF); | ||
536 | len += snprintf(buf + len, size - len, | ||
537 | "%20s : %10d\n", "Checksum", | ||
538 | pBase->checksum); | ||
539 | len += snprintf(buf + len, size - len, | ||
540 | "%20s : %10d\n", "Length", | ||
541 | pBase->length); | ||
542 | len += snprintf(buf + len, size - len, | ||
543 | "%20s : %10d\n", "RegDomain1", | ||
544 | pBase->regDmn[0]); | ||
545 | len += snprintf(buf + len, size - len, | ||
546 | "%20s : %10d\n", "RegDomain2", | ||
547 | pBase->regDmn[1]); | ||
548 | len += snprintf(buf + len, size - len, | ||
549 | "%20s : %10d\n", | ||
550 | "TX Mask", pBase->txMask); | ||
551 | len += snprintf(buf + len, size - len, | ||
552 | "%20s : %10d\n", | ||
553 | "RX Mask", pBase->rxMask); | ||
554 | len += snprintf(buf + len, size - len, | ||
555 | "%20s : %10d\n", | ||
556 | "Allow 5GHz", | ||
557 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); | ||
558 | len += snprintf(buf + len, size - len, | ||
559 | "%20s : %10d\n", | ||
560 | "Allow 2GHz", | ||
561 | !!(pBase->opCapFlags & AR5416_OPFLAGS_11G)); | ||
562 | len += snprintf(buf + len, size - len, | ||
563 | "%20s : %10d\n", | ||
564 | "Disable 2GHz HT20", | ||
565 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20)); | ||
566 | len += snprintf(buf + len, size - len, | ||
567 | "%20s : %10d\n", | ||
568 | "Disable 2GHz HT40", | ||
569 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40)); | ||
570 | len += snprintf(buf + len, size - len, | ||
571 | "%20s : %10d\n", | ||
572 | "Disable 5Ghz HT20", | ||
573 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20)); | ||
574 | len += snprintf(buf + len, size - len, | ||
575 | "%20s : %10d\n", | ||
576 | "Disable 5Ghz HT40", | ||
577 | !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40)); | ||
578 | len += snprintf(buf + len, size - len, | ||
579 | "%20s : %10d\n", | ||
580 | "Big Endian", | ||
581 | !!(pBase->eepMisc & 0x01)); | ||
582 | len += snprintf(buf + len, size - len, | ||
583 | "%20s : %10d\n", | ||
584 | "Cal Bin Major Ver", | ||
585 | (pBase->binBuildNumber >> 24) & 0xFF); | ||
586 | len += snprintf(buf + len, size - len, | ||
587 | "%20s : %10d\n", | ||
588 | "Cal Bin Minor Ver", | ||
589 | (pBase->binBuildNumber >> 16) & 0xFF); | ||
590 | len += snprintf(buf + len, size - len, | ||
591 | "%20s : %10d\n", | ||
592 | "Cal Bin Build", | ||
593 | (pBase->binBuildNumber >> 8) & 0xFF); | ||
594 | |||
595 | /* | ||
596 | * UB91 specific data. | ||
597 | */ | ||
598 | if (AR_SREV_9271(priv->ah)) { | ||
599 | struct base_eep_header_4k *pBase4k = | ||
600 | &priv->ah->eeprom.map4k.baseEepHeader; | ||
601 | |||
602 | len += snprintf(buf + len, size - len, | ||
603 | "%20s : %10d\n", | ||
604 | "TX Gain type", | ||
605 | pBase4k->txGainType); | ||
606 | } | ||
607 | |||
608 | /* | ||
609 | * UB95 specific data. | ||
610 | */ | ||
611 | if (priv->ah->hw_version.usbdev == AR9287_USB) { | ||
612 | struct base_eep_ar9287_header *pBase9287 = | ||
613 | &priv->ah->eeprom.map9287.baseEepHeader; | ||
614 | |||
615 | len += snprintf(buf + len, size - len, | ||
616 | "%20s : %10ddB\n", | ||
617 | "Power Table Offset", | ||
618 | pBase9287->pwrTableOffset); | ||
619 | |||
620 | len += snprintf(buf + len, size - len, | ||
621 | "%20s : %10d\n", | ||
622 | "OpenLoop Power Ctrl", | ||
623 | pBase9287->openLoopPwrCntl); | ||
624 | } | ||
625 | |||
626 | len += snprintf(buf + len, size - len, | ||
627 | "%20s : %02X:%02X:%02X:%02X:%02X:%02X\n", | ||
628 | "MacAddress", | ||
629 | pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2], | ||
630 | pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]); | ||
631 | if (len > size) | ||
632 | len = size; | ||
633 | |||
634 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
635 | kfree(buf); | ||
636 | |||
637 | return retval; | ||
638 | } | ||
639 | |||
640 | static const struct file_operations fops_base_eeprom = { | ||
641 | .read = read_file_base_eeprom, | ||
642 | .open = ath9k_debugfs_open, | ||
643 | .owner = THIS_MODULE, | ||
644 | .llseek = default_llseek, | ||
645 | }; | ||
646 | |||
647 | static ssize_t read_4k_modal_eeprom(struct file *file, | ||
648 | char __user *user_buf, | ||
649 | size_t count, loff_t *ppos) | ||
650 | { | ||
651 | #define PR_EEP(_s, _val) \ | ||
652 | do { \ | ||
653 | len += snprintf(buf + len, size - len, "%20s : %10d\n", \ | ||
654 | _s, (_val)); \ | ||
655 | } while (0) | ||
656 | |||
657 | struct ath9k_htc_priv *priv = file->private_data; | ||
658 | struct modal_eep_4k_header *pModal = &priv->ah->eeprom.map4k.modalHeader; | ||
659 | unsigned int len = 0, size = 2048; | ||
660 | ssize_t retval = 0; | ||
661 | char *buf; | ||
662 | |||
663 | buf = kzalloc(size, GFP_KERNEL); | ||
664 | if (buf == NULL) | ||
665 | return -ENOMEM; | ||
666 | |||
667 | PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); | ||
668 | PR_EEP("Ant. Common Control", pModal->antCtrlCommon); | ||
669 | PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]); | ||
670 | PR_EEP("Switch Settle", pModal->switchSettling); | ||
671 | PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]); | ||
672 | PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]); | ||
673 | PR_EEP("ADC Desired size", pModal->adcDesiredSize); | ||
674 | PR_EEP("PGA Desired size", pModal->pgaDesiredSize); | ||
675 | PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]); | ||
676 | PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff); | ||
677 | PR_EEP("txEndToRxOn", pModal->txEndToRxOn); | ||
678 | PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn); | ||
679 | PR_EEP("CCA Threshold)", pModal->thresh62); | ||
680 | PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]); | ||
681 | PR_EEP("xpdGain", pModal->xpdGain); | ||
682 | PR_EEP("External PD", pModal->xpd); | ||
683 | PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]); | ||
684 | PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]); | ||
685 | PR_EEP("pdGainOverlap", pModal->pdGainOverlap); | ||
686 | PR_EEP("O/D Bias Version", pModal->version); | ||
687 | PR_EEP("CCK OutputBias", pModal->ob_0); | ||
688 | PR_EEP("BPSK OutputBias", pModal->ob_1); | ||
689 | PR_EEP("QPSK OutputBias", pModal->ob_2); | ||
690 | PR_EEP("16QAM OutputBias", pModal->ob_3); | ||
691 | PR_EEP("64QAM OutputBias", pModal->ob_4); | ||
692 | PR_EEP("CCK Driver1_Bias", pModal->db1_0); | ||
693 | PR_EEP("BPSK Driver1_Bias", pModal->db1_1); | ||
694 | PR_EEP("QPSK Driver1_Bias", pModal->db1_2); | ||
695 | PR_EEP("16QAM Driver1_Bias", pModal->db1_3); | ||
696 | PR_EEP("64QAM Driver1_Bias", pModal->db1_4); | ||
697 | PR_EEP("CCK Driver2_Bias", pModal->db2_0); | ||
698 | PR_EEP("BPSK Driver2_Bias", pModal->db2_1); | ||
699 | PR_EEP("QPSK Driver2_Bias", pModal->db2_2); | ||
700 | PR_EEP("16QAM Driver2_Bias", pModal->db2_3); | ||
701 | PR_EEP("64QAM Driver2_Bias", pModal->db2_4); | ||
702 | PR_EEP("xPA Bias Level", pModal->xpaBiasLvl); | ||
703 | PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart); | ||
704 | PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn); | ||
705 | PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc); | ||
706 | PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]); | ||
707 | PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]); | ||
708 | PR_EEP("HT40 Switch Settle", pModal->swSettleHt40); | ||
709 | PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]); | ||
710 | PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]); | ||
711 | PR_EEP("Ant. Diversity ctl1", pModal->antdiv_ctl1); | ||
712 | PR_EEP("Ant. Diversity ctl2", pModal->antdiv_ctl2); | ||
713 | PR_EEP("TX Diversity", pModal->tx_diversity); | ||
714 | |||
715 | if (len > size) | ||
716 | len = size; | ||
717 | |||
718 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
719 | kfree(buf); | ||
720 | |||
721 | return retval; | ||
722 | |||
723 | #undef PR_EEP | ||
724 | } | ||
725 | |||
726 | static ssize_t read_def_modal_eeprom(struct file *file, | ||
727 | char __user *user_buf, | ||
728 | size_t count, loff_t *ppos) | ||
729 | { | ||
730 | #define PR_EEP(_s, _val) \ | ||
731 | do { \ | ||
732 | if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { \ | ||
733 | pModal = &priv->ah->eeprom.def.modalHeader[1]; \ | ||
734 | len += snprintf(buf + len, size - len, "%20s : %8d%7s", \ | ||
735 | _s, (_val), "|"); \ | ||
736 | } \ | ||
737 | if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { \ | ||
738 | pModal = &priv->ah->eeprom.def.modalHeader[0]; \ | ||
739 | len += snprintf(buf + len, size - len, "%9d\n", \ | ||
740 | (_val)); \ | ||
741 | } \ | ||
742 | } while (0) | ||
743 | |||
744 | struct ath9k_htc_priv *priv = file->private_data; | ||
745 | struct base_eep_header *pBase = &priv->ah->eeprom.def.baseEepHeader; | ||
746 | struct modal_eep_header *pModal = NULL; | ||
747 | unsigned int len = 0, size = 3500; | ||
748 | ssize_t retval = 0; | ||
749 | char *buf; | ||
750 | |||
751 | buf = kzalloc(size, GFP_KERNEL); | ||
752 | if (buf == NULL) | ||
753 | return -ENOMEM; | ||
754 | |||
755 | len += snprintf(buf + len, size - len, | ||
756 | "%31s %15s\n", "2G", "5G"); | ||
757 | len += snprintf(buf + len, size - len, | ||
758 | "%32s %16s\n", "====", "====\n"); | ||
759 | |||
760 | PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); | ||
761 | PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]); | ||
762 | PR_EEP("Chain2 Ant. Control", pModal->antCtrlChain[2]); | ||
763 | PR_EEP("Ant. Common Control", pModal->antCtrlCommon); | ||
764 | PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]); | ||
765 | PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]); | ||
766 | PR_EEP("Chain2 Ant. Gain", pModal->antennaGainCh[2]); | ||
767 | PR_EEP("Switch Settle", pModal->switchSettling); | ||
768 | PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]); | ||
769 | PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]); | ||
770 | PR_EEP("Chain2 TxRxAtten", pModal->txRxAttenCh[2]); | ||
771 | PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]); | ||
772 | PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]); | ||
773 | PR_EEP("Chain2 RxTxMargin", pModal->rxTxMarginCh[2]); | ||
774 | PR_EEP("ADC Desired size", pModal->adcDesiredSize); | ||
775 | PR_EEP("PGA Desired size", pModal->pgaDesiredSize); | ||
776 | PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]); | ||
777 | PR_EEP("Chain1 xlna Gain", pModal->xlnaGainCh[1]); | ||
778 | PR_EEP("Chain2 xlna Gain", pModal->xlnaGainCh[2]); | ||
779 | PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff); | ||
780 | PR_EEP("txEndToRxOn", pModal->txEndToRxOn); | ||
781 | PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn); | ||
782 | PR_EEP("CCA Threshold)", pModal->thresh62); | ||
783 | PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]); | ||
784 | PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]); | ||
785 | PR_EEP("Chain2 NF Threshold", pModal->noiseFloorThreshCh[2]); | ||
786 | PR_EEP("xpdGain", pModal->xpdGain); | ||
787 | PR_EEP("External PD", pModal->xpd); | ||
788 | PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]); | ||
789 | PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]); | ||
790 | PR_EEP("Chain2 I Coefficient", pModal->iqCalICh[2]); | ||
791 | PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]); | ||
792 | PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]); | ||
793 | PR_EEP("Chain2 Q Coefficient", pModal->iqCalQCh[2]); | ||
794 | PR_EEP("pdGainOverlap", pModal->pdGainOverlap); | ||
795 | PR_EEP("Chain0 OutputBias", pModal->ob); | ||
796 | PR_EEP("Chain0 DriverBias", pModal->db); | ||
797 | PR_EEP("xPA Bias Level", pModal->xpaBiasLvl); | ||
798 | PR_EEP("2chain pwr decrease", pModal->pwrDecreaseFor2Chain); | ||
799 | PR_EEP("3chain pwr decrease", pModal->pwrDecreaseFor3Chain); | ||
800 | PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart); | ||
801 | PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn); | ||
802 | PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc); | ||
803 | PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]); | ||
804 | PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]); | ||
805 | PR_EEP("Chain2 bswAtten", pModal->bswAtten[2]); | ||
806 | PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]); | ||
807 | PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]); | ||
808 | PR_EEP("Chain2 bswMargin", pModal->bswMargin[2]); | ||
809 | PR_EEP("HT40 Switch Settle", pModal->swSettleHt40); | ||
810 | PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]); | ||
811 | PR_EEP("Chain1 xatten2Db", pModal->xatten2Db[1]); | ||
812 | PR_EEP("Chain2 xatten2Db", pModal->xatten2Db[2]); | ||
813 | PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]); | ||
814 | PR_EEP("Chain1 xatten2Margin", pModal->xatten2Margin[1]); | ||
815 | PR_EEP("Chain2 xatten2Margin", pModal->xatten2Margin[2]); | ||
816 | PR_EEP("Chain1 OutputBias", pModal->ob_ch1); | ||
817 | PR_EEP("Chain1 DriverBias", pModal->db_ch1); | ||
818 | PR_EEP("LNA Control", pModal->lna_ctl); | ||
819 | PR_EEP("XPA Bias Freq0", pModal->xpaBiasLvlFreq[0]); | ||
820 | PR_EEP("XPA Bias Freq1", pModal->xpaBiasLvlFreq[1]); | ||
821 | PR_EEP("XPA Bias Freq2", pModal->xpaBiasLvlFreq[2]); | ||
822 | |||
823 | if (len > size) | ||
824 | len = size; | ||
825 | |||
826 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
827 | kfree(buf); | ||
828 | |||
829 | return retval; | ||
830 | |||
831 | #undef PR_EEP | ||
832 | } | ||
833 | |||
834 | static ssize_t read_9287_modal_eeprom(struct file *file, | ||
835 | char __user *user_buf, | ||
836 | size_t count, loff_t *ppos) | ||
837 | { | ||
838 | #define PR_EEP(_s, _val) \ | ||
839 | do { \ | ||
840 | len += snprintf(buf + len, size - len, "%20s : %10d\n", \ | ||
841 | _s, (_val)); \ | ||
842 | } while (0) | ||
843 | |||
844 | struct ath9k_htc_priv *priv = file->private_data; | ||
845 | struct modal_eep_ar9287_header *pModal = &priv->ah->eeprom.map9287.modalHeader; | ||
846 | unsigned int len = 0, size = 3000; | ||
847 | ssize_t retval = 0; | ||
848 | char *buf; | ||
849 | |||
850 | buf = kzalloc(size, GFP_KERNEL); | ||
851 | if (buf == NULL) | ||
852 | return -ENOMEM; | ||
853 | |||
854 | PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); | ||
855 | PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]); | ||
856 | PR_EEP("Ant. Common Control", pModal->antCtrlCommon); | ||
857 | PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]); | ||
858 | PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]); | ||
859 | PR_EEP("Switch Settle", pModal->switchSettling); | ||
860 | PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]); | ||
861 | PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]); | ||
862 | PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]); | ||
863 | PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]); | ||
864 | PR_EEP("ADC Desired size", pModal->adcDesiredSize); | ||
865 | PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff); | ||
866 | PR_EEP("txEndToRxOn", pModal->txEndToRxOn); | ||
867 | PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn); | ||
868 | PR_EEP("CCA Threshold)", pModal->thresh62); | ||
869 | PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]); | ||
870 | PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]); | ||
871 | PR_EEP("xpdGain", pModal->xpdGain); | ||
872 | PR_EEP("External PD", pModal->xpd); | ||
873 | PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]); | ||
874 | PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]); | ||
875 | PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]); | ||
876 | PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]); | ||
877 | PR_EEP("pdGainOverlap", pModal->pdGainOverlap); | ||
878 | PR_EEP("xPA Bias Level", pModal->xpaBiasLvl); | ||
879 | PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart); | ||
880 | PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn); | ||
881 | PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc); | ||
882 | PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]); | ||
883 | PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]); | ||
884 | PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]); | ||
885 | PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]); | ||
886 | PR_EEP("HT40 Switch Settle", pModal->swSettleHt40); | ||
887 | PR_EEP("AR92x7 Version", pModal->version); | ||
888 | PR_EEP("DriverBias1", pModal->db1); | ||
889 | PR_EEP("DriverBias2", pModal->db1); | ||
890 | PR_EEP("CCK OutputBias", pModal->ob_cck); | ||
891 | PR_EEP("PSK OutputBias", pModal->ob_psk); | ||
892 | PR_EEP("QAM OutputBias", pModal->ob_qam); | ||
893 | PR_EEP("PAL_OFF OutputBias", pModal->ob_pal_off); | ||
894 | |||
895 | if (len > size) | ||
896 | len = size; | ||
897 | |||
898 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
899 | kfree(buf); | ||
900 | |||
901 | return retval; | ||
902 | |||
903 | #undef PR_EEP | ||
904 | } | ||
905 | |||
906 | static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, | ||
907 | size_t count, loff_t *ppos) | ||
908 | { | ||
909 | struct ath9k_htc_priv *priv = file->private_data; | ||
910 | |||
911 | if (AR_SREV_9271(priv->ah)) | ||
912 | return read_4k_modal_eeprom(file, user_buf, count, ppos); | ||
913 | else if (priv->ah->hw_version.usbdev == AR9280_USB) | ||
914 | return read_def_modal_eeprom(file, user_buf, count, ppos); | ||
915 | else if (priv->ah->hw_version.usbdev == AR9287_USB) | ||
916 | return read_9287_modal_eeprom(file, user_buf, count, ppos); | ||
917 | |||
918 | return 0; | ||
919 | } | ||
920 | |||
921 | static const struct file_operations fops_modal_eeprom = { | ||
922 | .read = read_file_modal_eeprom, | ||
923 | .open = ath9k_debugfs_open, | ||
924 | .owner = THIS_MODULE, | ||
925 | .llseek = default_llseek, | ||
926 | }; | ||
927 | |||
477 | int ath9k_htc_init_debug(struct ath_hw *ah) | 928 | int ath9k_htc_init_debug(struct ath_hw *ah) |
478 | { | 929 | { |
479 | struct ath_common *common = ath9k_hw_common(ah); | 930 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -485,21 +936,25 @@ int ath9k_htc_init_debug(struct ath_hw *ah) | |||
485 | return -ENOMEM; | 936 | return -ENOMEM; |
486 | 937 | ||
487 | debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy, | 938 | debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy, |
488 | priv, &fops_tgt_int_stats); | 939 | priv, &fops_tgt_int_stats); |
489 | debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy, | 940 | debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy, |
490 | priv, &fops_tgt_tx_stats); | 941 | priv, &fops_tgt_tx_stats); |
491 | debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy, | 942 | debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy, |
492 | priv, &fops_tgt_rx_stats); | 943 | priv, &fops_tgt_rx_stats); |
493 | debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, | 944 | debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, |
494 | priv, &fops_xmit); | 945 | priv, &fops_xmit); |
495 | debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy, | 946 | debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy, |
496 | priv, &fops_recv); | 947 | priv, &fops_recv); |
497 | debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy, | 948 | debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy, |
498 | priv, &fops_slot); | 949 | priv, &fops_slot); |
499 | debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy, | 950 | debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy, |
500 | priv, &fops_queue); | 951 | priv, &fops_queue); |
501 | debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy, | 952 | debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy, |
502 | priv, &fops_debug); | 953 | priv, &fops_debug); |
954 | debugfs_create_file("base_eeprom", S_IRUSR, priv->debug.debugfs_phy, | ||
955 | priv, &fops_base_eeprom); | ||
956 | debugfs_create_file("modal_eeprom", S_IRUSR, priv->debug.debugfs_phy, | ||
957 | priv, &fops_modal_eeprom); | ||
503 | 958 | ||
504 | return 0; | 959 | return 0; |
505 | } | 960 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index dc0b33d01210..af57fe5aab98 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | |||
@@ -65,17 +65,19 @@ static void ath_btcoex_period_work(struct work_struct *work) | |||
65 | u32 timer_period; | 65 | u32 timer_period; |
66 | bool is_btscan; | 66 | bool is_btscan; |
67 | int ret; | 67 | int ret; |
68 | u8 cmd_rsp, aggr; | ||
69 | 68 | ||
70 | ath_detect_bt_priority(priv); | 69 | ath_detect_bt_priority(priv); |
71 | 70 | ||
72 | is_btscan = !!(priv->op_flags & OP_BT_SCAN); | 71 | is_btscan = !!(priv->op_flags & OP_BT_SCAN); |
73 | 72 | ||
74 | aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED; | 73 | ret = ath9k_htc_update_cap_target(priv, |
75 | 74 | !!(priv->op_flags & OP_BT_PRIORITY_DETECTED)); | |
76 | WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr); | 75 | if (ret) { |
76 | ath_err(common, "Unable to set BTCOEX parameters\n"); | ||
77 | return; | ||
78 | } | ||
77 | 79 | ||
78 | ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : | 80 | ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : |
79 | btcoex->bt_stomp_type); | 81 | btcoex->bt_stomp_type); |
80 | 82 | ||
81 | timer_period = is_btscan ? btcoex->btscan_no_stomp : | 83 | timer_period = is_btscan ? btcoex->btscan_no_stomp : |
@@ -103,9 +105,9 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) | |||
103 | "time slice work for bt and wlan\n"); | 105 | "time slice work for bt and wlan\n"); |
104 | 106 | ||
105 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | 107 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) |
106 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); | 108 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
107 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | 109 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) |
108 | ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); | 110 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); |
109 | } | 111 | } |
110 | 112 | ||
111 | void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) | 113 | void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) |
@@ -152,140 +154,41 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) | |||
152 | /* LED */ | 154 | /* LED */ |
153 | /*******/ | 155 | /*******/ |
154 | 156 | ||
155 | static void ath9k_led_blink_work(struct work_struct *work) | 157 | #ifdef CONFIG_MAC80211_LEDS |
158 | void ath9k_led_work(struct work_struct *work) | ||
156 | { | 159 | { |
157 | struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, | 160 | struct ath9k_htc_priv *priv = container_of(work, |
158 | ath9k_led_blink_work.work); | 161 | struct ath9k_htc_priv, |
162 | led_work); | ||
159 | 163 | ||
160 | if (!(priv->op_flags & OP_LED_ASSOCIATED)) | 164 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, |
161 | return; | 165 | (priv->brightness == LED_OFF)); |
162 | |||
163 | if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
164 | (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
165 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); | ||
166 | else | ||
167 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, | ||
168 | (priv->op_flags & OP_LED_ON) ? 1 : 0); | ||
169 | |||
170 | ieee80211_queue_delayed_work(priv->hw, | ||
171 | &priv->ath9k_led_blink_work, | ||
172 | (priv->op_flags & OP_LED_ON) ? | ||
173 | msecs_to_jiffies(priv->led_off_duration) : | ||
174 | msecs_to_jiffies(priv->led_on_duration)); | ||
175 | |||
176 | priv->led_on_duration = priv->led_on_cnt ? | ||
177 | max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) : | ||
178 | ATH_LED_ON_DURATION_IDLE; | ||
179 | priv->led_off_duration = priv->led_off_cnt ? | ||
180 | max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) : | ||
181 | ATH_LED_OFF_DURATION_IDLE; | ||
182 | priv->led_on_cnt = priv->led_off_cnt = 0; | ||
183 | |||
184 | if (priv->op_flags & OP_LED_ON) | ||
185 | priv->op_flags &= ~OP_LED_ON; | ||
186 | else | ||
187 | priv->op_flags |= OP_LED_ON; | ||
188 | } | ||
189 | |||
190 | static void ath9k_led_brightness_work(struct work_struct *work) | ||
191 | { | ||
192 | struct ath_led *led = container_of(work, struct ath_led, | ||
193 | brightness_work.work); | ||
194 | struct ath9k_htc_priv *priv = led->priv; | ||
195 | |||
196 | switch (led->brightness) { | ||
197 | case LED_OFF: | ||
198 | if (led->led_type == ATH_LED_ASSOC || | ||
199 | led->led_type == ATH_LED_RADIO) { | ||
200 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, | ||
201 | (led->led_type == ATH_LED_RADIO)); | ||
202 | priv->op_flags &= ~OP_LED_ASSOCIATED; | ||
203 | if (led->led_type == ATH_LED_RADIO) | ||
204 | priv->op_flags &= ~OP_LED_ON; | ||
205 | } else { | ||
206 | priv->led_off_cnt++; | ||
207 | } | ||
208 | break; | ||
209 | case LED_FULL: | ||
210 | if (led->led_type == ATH_LED_ASSOC) { | ||
211 | priv->op_flags |= OP_LED_ASSOCIATED; | ||
212 | ieee80211_queue_delayed_work(priv->hw, | ||
213 | &priv->ath9k_led_blink_work, 0); | ||
214 | } else if (led->led_type == ATH_LED_RADIO) { | ||
215 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); | ||
216 | priv->op_flags |= OP_LED_ON; | ||
217 | } else { | ||
218 | priv->led_on_cnt++; | ||
219 | } | ||
220 | break; | ||
221 | default: | ||
222 | break; | ||
223 | } | ||
224 | } | 166 | } |
225 | 167 | ||
226 | static void ath9k_led_brightness(struct led_classdev *led_cdev, | 168 | static void ath9k_led_brightness(struct led_classdev *led_cdev, |
227 | enum led_brightness brightness) | 169 | enum led_brightness brightness) |
228 | { | 170 | { |
229 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | 171 | struct ath9k_htc_priv *priv = container_of(led_cdev, |
230 | struct ath9k_htc_priv *priv = led->priv; | 172 | struct ath9k_htc_priv, |
173 | led_cdev); | ||
231 | 174 | ||
232 | led->brightness = brightness; | 175 | /* Not locked, but it's just a tiny green light..*/ |
233 | if (!(priv->op_flags & OP_LED_DEINIT)) | 176 | priv->brightness = brightness; |
234 | ieee80211_queue_delayed_work(priv->hw, | 177 | ieee80211_queue_work(priv->hw, &priv->led_work); |
235 | &led->brightness_work, 0); | ||
236 | } | ||
237 | |||
238 | void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv) | ||
239 | { | ||
240 | cancel_delayed_work_sync(&priv->radio_led.brightness_work); | ||
241 | cancel_delayed_work_sync(&priv->assoc_led.brightness_work); | ||
242 | cancel_delayed_work_sync(&priv->tx_led.brightness_work); | ||
243 | cancel_delayed_work_sync(&priv->rx_led.brightness_work); | ||
244 | } | ||
245 | |||
246 | static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led, | ||
247 | char *trigger) | ||
248 | { | ||
249 | int ret; | ||
250 | |||
251 | led->priv = priv; | ||
252 | led->led_cdev.name = led->name; | ||
253 | led->led_cdev.default_trigger = trigger; | ||
254 | led->led_cdev.brightness_set = ath9k_led_brightness; | ||
255 | |||
256 | ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev); | ||
257 | if (ret) | ||
258 | ath_err(ath9k_hw_common(priv->ah), | ||
259 | "Failed to register led:%s", led->name); | ||
260 | else | ||
261 | led->registered = 1; | ||
262 | |||
263 | INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work); | ||
264 | |||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | static void ath9k_unregister_led(struct ath_led *led) | ||
269 | { | ||
270 | if (led->registered) { | ||
271 | led_classdev_unregister(&led->led_cdev); | ||
272 | led->registered = 0; | ||
273 | } | ||
274 | } | 178 | } |
275 | 179 | ||
276 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv) | 180 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv) |
277 | { | 181 | { |
278 | priv->op_flags |= OP_LED_DEINIT; | 182 | if (!priv->led_registered) |
279 | ath9k_unregister_led(&priv->assoc_led); | 183 | return; |
280 | priv->op_flags &= ~OP_LED_ASSOCIATED; | 184 | |
281 | ath9k_unregister_led(&priv->tx_led); | 185 | ath9k_led_brightness(&priv->led_cdev, LED_OFF); |
282 | ath9k_unregister_led(&priv->rx_led); | 186 | led_classdev_unregister(&priv->led_cdev); |
283 | ath9k_unregister_led(&priv->radio_led); | 187 | cancel_work_sync(&priv->led_work); |
284 | } | 188 | } |
285 | 189 | ||
286 | void ath9k_init_leds(struct ath9k_htc_priv *priv) | 190 | void ath9k_init_leds(struct ath9k_htc_priv *priv) |
287 | { | 191 | { |
288 | char *trigger; | ||
289 | int ret; | 192 | int ret; |
290 | 193 | ||
291 | if (AR_SREV_9287(priv->ah)) | 194 | if (AR_SREV_9287(priv->ah)) |
@@ -303,48 +206,21 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv) | |||
303 | /* LED off, active low */ | 206 | /* LED off, active low */ |
304 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); | 207 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); |
305 | 208 | ||
306 | INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work); | 209 | snprintf(priv->led_name, sizeof(priv->led_name), |
307 | 210 | "ath9k_htc-%s", wiphy_name(priv->hw->wiphy)); | |
308 | trigger = ieee80211_get_radio_led_name(priv->hw); | 211 | priv->led_cdev.name = priv->led_name; |
309 | snprintf(priv->radio_led.name, sizeof(priv->radio_led.name), | 212 | priv->led_cdev.brightness_set = ath9k_led_brightness; |
310 | "ath9k-%s::radio", wiphy_name(priv->hw->wiphy)); | ||
311 | ret = ath9k_register_led(priv, &priv->radio_led, trigger); | ||
312 | priv->radio_led.led_type = ATH_LED_RADIO; | ||
313 | if (ret) | ||
314 | goto fail; | ||
315 | |||
316 | trigger = ieee80211_get_assoc_led_name(priv->hw); | ||
317 | snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name), | ||
318 | "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy)); | ||
319 | ret = ath9k_register_led(priv, &priv->assoc_led, trigger); | ||
320 | priv->assoc_led.led_type = ATH_LED_ASSOC; | ||
321 | if (ret) | ||
322 | goto fail; | ||
323 | |||
324 | trigger = ieee80211_get_tx_led_name(priv->hw); | ||
325 | snprintf(priv->tx_led.name, sizeof(priv->tx_led.name), | ||
326 | "ath9k-%s::tx", wiphy_name(priv->hw->wiphy)); | ||
327 | ret = ath9k_register_led(priv, &priv->tx_led, trigger); | ||
328 | priv->tx_led.led_type = ATH_LED_TX; | ||
329 | if (ret) | ||
330 | goto fail; | ||
331 | |||
332 | trigger = ieee80211_get_rx_led_name(priv->hw); | ||
333 | snprintf(priv->rx_led.name, sizeof(priv->rx_led.name), | ||
334 | "ath9k-%s::rx", wiphy_name(priv->hw->wiphy)); | ||
335 | ret = ath9k_register_led(priv, &priv->rx_led, trigger); | ||
336 | priv->rx_led.led_type = ATH_LED_RX; | ||
337 | if (ret) | ||
338 | goto fail; | ||
339 | |||
340 | priv->op_flags &= ~OP_LED_DEINIT; | ||
341 | 213 | ||
342 | return; | 214 | ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev); |
215 | if (ret < 0) | ||
216 | return; | ||
343 | 217 | ||
344 | fail: | 218 | INIT_WORK(&priv->led_work, ath9k_led_work); |
345 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | 219 | priv->led_registered = true; |
346 | ath9k_deinit_leds(priv); | 220 | |
221 | return; | ||
347 | } | 222 | } |
223 | #endif | ||
348 | 224 | ||
349 | /*******************/ | 225 | /*******************/ |
350 | /* Rfkill */ | 226 | /* Rfkill */ |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 06e043bffaf4..bfdc8a887183 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -117,6 +117,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { | |||
117 | RATE(540, 0x0c, 0), | 117 | RATE(540, 0x0c, 0), |
118 | }; | 118 | }; |
119 | 119 | ||
120 | #ifdef CONFIG_MAC80211_LEDS | ||
121 | static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { | ||
122 | { .throughput = 0 * 1024, .blink_time = 334 }, | ||
123 | { .throughput = 1 * 1024, .blink_time = 260 }, | ||
124 | { .throughput = 5 * 1024, .blink_time = 220 }, | ||
125 | { .throughput = 10 * 1024, .blink_time = 190 }, | ||
126 | { .throughput = 20 * 1024, .blink_time = 170 }, | ||
127 | { .throughput = 50 * 1024, .blink_time = 150 }, | ||
128 | { .throughput = 70 * 1024, .blink_time = 130 }, | ||
129 | { .throughput = 100 * 1024, .blink_time = 110 }, | ||
130 | { .throughput = 200 * 1024, .blink_time = 80 }, | ||
131 | { .throughput = 300 * 1024, .blink_time = 50 }, | ||
132 | }; | ||
133 | #endif | ||
134 | |||
120 | static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) | 135 | static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) |
121 | { | 136 | { |
122 | int time_left; | 137 | int time_left; |
@@ -243,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid, | |||
243 | */ | 258 | */ |
244 | 259 | ||
245 | if (IS_AR7010_DEVICE(drv_info)) | 260 | if (IS_AR7010_DEVICE(drv_info)) |
246 | priv->htc->credits = 45; | 261 | priv->htc->credits = 48; |
247 | else | 262 | else |
248 | priv->htc->credits = 33; | 263 | priv->htc->credits = 33; |
249 | 264 | ||
@@ -753,6 +768,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
753 | hw->queues = 4; | 768 | hw->queues = 4; |
754 | hw->channel_change_time = 5000; | 769 | hw->channel_change_time = 5000; |
755 | hw->max_listen_interval = 10; | 770 | hw->max_listen_interval = 10; |
771 | |||
772 | if (AR_SREV_9271(priv->ah)) | ||
773 | hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271; | ||
774 | else | ||
775 | hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010; | ||
776 | |||
756 | hw->vif_data_size = sizeof(struct ath9k_htc_vif); | 777 | hw->vif_data_size = sizeof(struct ath9k_htc_vif); |
757 | hw->sta_data_size = sizeof(struct ath9k_htc_sta); | 778 | hw->sta_data_size = sizeof(struct ath9k_htc_sta); |
758 | 779 | ||
@@ -802,6 +823,17 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) | |||
802 | priv->fw_version_major, | 823 | priv->fw_version_major, |
803 | priv->fw_version_minor); | 824 | priv->fw_version_minor); |
804 | 825 | ||
826 | /* | ||
827 | * Check if the available FW matches the driver's | ||
828 | * required version. | ||
829 | */ | ||
830 | if (priv->fw_version_major != MAJOR_VERSION_REQ || | ||
831 | priv->fw_version_minor != MINOR_VERSION_REQ) { | ||
832 | dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", | ||
833 | MAJOR_VERSION_REQ, MINOR_VERSION_REQ); | ||
834 | return -EINVAL; | ||
835 | } | ||
836 | |||
805 | return 0; | 837 | return 0; |
806 | } | 838 | } |
807 | 839 | ||
@@ -846,6 +878,13 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
846 | if (error != 0) | 878 | if (error != 0) |
847 | goto err_rx; | 879 | goto err_rx; |
848 | 880 | ||
881 | #ifdef CONFIG_MAC80211_LEDS | ||
882 | /* must be initialized before ieee80211_register_hw */ | ||
883 | priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw, | ||
884 | IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_htc_tpt_blink, | ||
885 | ARRAY_SIZE(ath9k_htc_tpt_blink)); | ||
886 | #endif | ||
887 | |||
849 | /* Register with mac80211 */ | 888 | /* Register with mac80211 */ |
850 | error = ieee80211_register_hw(hw); | 889 | error = ieee80211_register_hw(hw); |
851 | if (error) | 890 | if (error) |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 4de38643cb53..5aa104fe7eeb 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -332,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) | |||
332 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); | 332 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); |
333 | hvif.index = priv->mon_vif_idx; | 333 | hvif.index = priv->mon_vif_idx; |
334 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); | 334 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); |
335 | if (ret) { | ||
336 | ath_err(common, "Unable to remove monitor interface at idx: %d\n", | ||
337 | priv->mon_vif_idx); | ||
338 | } | ||
339 | |||
335 | priv->nvifs--; | 340 | priv->nvifs--; |
336 | priv->vif_slot &= ~(1 << priv->mon_vif_idx); | 341 | priv->vif_slot &= ~(1 << priv->mon_vif_idx); |
337 | } | 342 | } |
@@ -462,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
462 | struct ath9k_htc_sta *ista; | 467 | struct ath9k_htc_sta *ista; |
463 | int ret, sta_idx; | 468 | int ret, sta_idx; |
464 | u8 cmd_rsp; | 469 | u8 cmd_rsp; |
470 | u16 maxampdu; | ||
465 | 471 | ||
466 | if (priv->nstations >= ATH9K_HTC_MAX_STA) | 472 | if (priv->nstations >= ATH9K_HTC_MAX_STA) |
467 | return -ENOBUFS; | 473 | return -ENOBUFS; |
@@ -485,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
485 | 491 | ||
486 | tsta.sta_index = sta_idx; | 492 | tsta.sta_index = sta_idx; |
487 | tsta.vif_index = avp->index; | 493 | tsta.vif_index = avp->index; |
488 | tsta.maxampdu = cpu_to_be16(0xffff); | 494 | |
495 | if (!sta) { | ||
496 | tsta.maxampdu = cpu_to_be16(0xffff); | ||
497 | } else { | ||
498 | maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + | ||
499 | sta->ht_cap.ampdu_factor); | ||
500 | tsta.maxampdu = cpu_to_be16(maxampdu); | ||
501 | } | ||
502 | |||
489 | if (sta && sta->ht_cap.ht_supported) | 503 | if (sta && sta->ht_cap.ht_supported) |
490 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); | 504 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); |
491 | 505 | ||
@@ -558,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, | |||
558 | return 0; | 572 | return 0; |
559 | } | 573 | } |
560 | 574 | ||
561 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) | 575 | int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv, |
576 | u8 enable_coex) | ||
562 | { | 577 | { |
563 | struct ath9k_htc_cap_target tcap; | 578 | struct ath9k_htc_cap_target tcap; |
564 | int ret; | 579 | int ret; |
@@ -566,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) | |||
566 | 581 | ||
567 | memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); | 582 | memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); |
568 | 583 | ||
569 | /* FIXME: Values are hardcoded */ | 584 | tcap.ampdu_limit = cpu_to_be32(0xffff); |
570 | tcap.flags = 0x240c40; | 585 | tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes; |
571 | tcap.flags_ext = 0x80601000; | 586 | tcap.enable_coex = enable_coex; |
572 | tcap.ampdu_limit = 0xffff0000; | ||
573 | tcap.ampdu_subframes = 20; | ||
574 | tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask; | ||
575 | tcap.protmode = 1; | ||
576 | tcap.tx_chainmask = priv->ah->caps.tx_chainmask; | 587 | tcap.tx_chainmask = priv->ah->caps.tx_chainmask; |
577 | 588 | ||
578 | WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); | 589 | WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); |
@@ -931,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
931 | 942 | ||
932 | ath9k_host_rx_init(priv); | 943 | ath9k_host_rx_init(priv); |
933 | 944 | ||
934 | ret = ath9k_htc_update_cap_target(priv); | 945 | ret = ath9k_htc_update_cap_target(priv, 0); |
935 | if (ret) | 946 | if (ret) |
936 | ath_dbg(common, ATH_DBG_CONFIG, | 947 | ath_dbg(common, ATH_DBG_CONFIG, |
937 | "Failed to update capability in target\n"); | 948 | "Failed to update capability in target\n"); |
@@ -964,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
964 | struct ath9k_htc_priv *priv = hw->priv; | 975 | struct ath9k_htc_priv *priv = hw->priv; |
965 | struct ath_hw *ah = priv->ah; | 976 | struct ath_hw *ah = priv->ah; |
966 | struct ath_common *common = ath9k_hw_common(ah); | 977 | struct ath_common *common = ath9k_hw_common(ah); |
967 | int ret = 0; | 978 | int ret __attribute__ ((unused)); |
968 | u8 cmd_rsp; | 979 | u8 cmd_rsp; |
969 | 980 | ||
970 | mutex_lock(&priv->mutex); | 981 | mutex_lock(&priv->mutex); |
@@ -992,9 +1003,11 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
992 | /* Cancel all the running timers/work .. */ | 1003 | /* Cancel all the running timers/work .. */ |
993 | cancel_work_sync(&priv->fatal_work); | 1004 | cancel_work_sync(&priv->fatal_work); |
994 | cancel_work_sync(&priv->ps_work); | 1005 | cancel_work_sync(&priv->ps_work); |
995 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | 1006 | |
1007 | #ifdef CONFIG_MAC80211_LEDS | ||
1008 | cancel_work_sync(&priv->led_work); | ||
1009 | #endif | ||
996 | ath9k_htc_stop_ani(priv); | 1010 | ath9k_htc_stop_ani(priv); |
997 | ath9k_led_stop_brightness(priv); | ||
998 | 1011 | ||
999 | mutex_lock(&priv->mutex); | 1012 | mutex_lock(&priv->mutex); |
1000 | 1013 | ||
@@ -1135,6 +1148,10 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
1135 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); | 1148 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); |
1136 | hvif.index = avp->index; | 1149 | hvif.index = avp->index; |
1137 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); | 1150 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); |
1151 | if (ret) { | ||
1152 | ath_err(common, "Unable to remove interface at idx: %d\n", | ||
1153 | avp->index); | ||
1154 | } | ||
1138 | priv->nvifs--; | 1155 | priv->nvifs--; |
1139 | priv->vif_slot &= ~(1 << avp->index); | 1156 | priv->vif_slot &= ~(1 << avp->index); |
1140 | 1157 | ||
@@ -1567,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
1567 | int ret = 0; | 1584 | int ret = 0; |
1568 | 1585 | ||
1569 | mutex_lock(&priv->mutex); | 1586 | mutex_lock(&priv->mutex); |
1587 | ath9k_htc_ps_wakeup(priv); | ||
1570 | 1588 | ||
1571 | switch (action) { | 1589 | switch (action) { |
1572 | case IEEE80211_AMPDU_RX_START: | 1590 | case IEEE80211_AMPDU_RX_START: |
@@ -1592,6 +1610,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
1592 | ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); | 1610 | ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); |
1593 | } | 1611 | } |
1594 | 1612 | ||
1613 | ath9k_htc_ps_restore(priv); | ||
1595 | mutex_unlock(&priv->mutex); | 1614 | mutex_unlock(&priv->mutex); |
1596 | 1615 | ||
1597 | return ret; | 1616 | return ret; |
@@ -1642,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, | |||
1642 | mutex_unlock(&priv->mutex); | 1661 | mutex_unlock(&priv->mutex); |
1643 | } | 1662 | } |
1644 | 1663 | ||
1664 | /* | ||
1665 | * Currently, this is used only for selecting the minimum rate | ||
1666 | * for management frames, rate selection for data frames remain | ||
1667 | * unaffected. | ||
1668 | */ | ||
1669 | static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw, | ||
1670 | struct ieee80211_vif *vif, | ||
1671 | const struct cfg80211_bitrate_mask *mask) | ||
1672 | { | ||
1673 | struct ath9k_htc_priv *priv = hw->priv; | ||
1674 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1675 | struct ath9k_htc_target_rate_mask tmask; | ||
1676 | struct ath9k_htc_vif *avp = (void *)vif->drv_priv; | ||
1677 | int ret = 0; | ||
1678 | u8 cmd_rsp; | ||
1679 | |||
1680 | memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask)); | ||
1681 | |||
1682 | tmask.vif_index = avp->index; | ||
1683 | tmask.band = IEEE80211_BAND_2GHZ; | ||
1684 | tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy); | ||
1685 | |||
1686 | WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask); | ||
1687 | if (ret) { | ||
1688 | ath_err(common, | ||
1689 | "Unable to set 2G rate mask for " | ||
1690 | "interface at idx: %d\n", avp->index); | ||
1691 | goto out; | ||
1692 | } | ||
1693 | |||
1694 | tmask.band = IEEE80211_BAND_5GHZ; | ||
1695 | tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy); | ||
1696 | |||
1697 | WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask); | ||
1698 | if (ret) { | ||
1699 | ath_err(common, | ||
1700 | "Unable to set 5G rate mask for " | ||
1701 | "interface at idx: %d\n", avp->index); | ||
1702 | goto out; | ||
1703 | } | ||
1704 | |||
1705 | ath_dbg(common, ATH_DBG_CONFIG, | ||
1706 | "Set bitrate masks: 0x%x, 0x%x\n", | ||
1707 | mask->control[IEEE80211_BAND_2GHZ].legacy, | ||
1708 | mask->control[IEEE80211_BAND_5GHZ].legacy); | ||
1709 | out: | ||
1710 | return ret; | ||
1711 | } | ||
1712 | |||
1645 | struct ieee80211_ops ath9k_htc_ops = { | 1713 | struct ieee80211_ops ath9k_htc_ops = { |
1646 | .tx = ath9k_htc_tx, | 1714 | .tx = ath9k_htc_tx, |
1647 | .start = ath9k_htc_start, | 1715 | .start = ath9k_htc_start, |
@@ -1664,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = { | |||
1664 | .set_rts_threshold = ath9k_htc_set_rts_threshold, | 1732 | .set_rts_threshold = ath9k_htc_set_rts_threshold, |
1665 | .rfkill_poll = ath9k_htc_rfkill_poll_state, | 1733 | .rfkill_poll = ath9k_htc_rfkill_poll_state, |
1666 | .set_coverage_class = ath9k_htc_set_coverage_class, | 1734 | .set_coverage_class = ath9k_htc_set_coverage_class, |
1735 | .set_bitrate_mask = ath9k_htc_set_bitrate_mask, | ||
1667 | }; | 1736 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 723a3a9c5cd9..a898dac22337 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -446,7 +446,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, | |||
446 | struct ieee80211_tx_info *tx_info; | 446 | struct ieee80211_tx_info *tx_info; |
447 | struct ieee80211_tx_rate *rate; | 447 | struct ieee80211_tx_rate *rate; |
448 | struct ieee80211_conf *cur_conf = &priv->hw->conf; | 448 | struct ieee80211_conf *cur_conf = &priv->hw->conf; |
449 | struct ieee80211_supported_band *sband; | ||
450 | bool txok; | 449 | bool txok; |
451 | int slot; | 450 | int slot; |
452 | 451 | ||
@@ -461,7 +460,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, | |||
461 | tx_info = IEEE80211_SKB_CB(skb); | 460 | tx_info = IEEE80211_SKB_CB(skb); |
462 | vif = tx_info->control.vif; | 461 | vif = tx_info->control.vif; |
463 | rate = &tx_info->status.rates[0]; | 462 | rate = &tx_info->status.rates[0]; |
464 | sband = priv->hw->wiphy->bands[cur_conf->channel->band]; | ||
465 | 463 | ||
466 | memset(&tx_info->status, 0, sizeof(tx_info->status)); | 464 | memset(&tx_info->status, 0, sizeof(tx_info->status)); |
467 | 465 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index cb9174ade53e..91a5305db95a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h | |||
@@ -83,21 +83,10 @@ struct htc_ep_callbacks { | |||
83 | void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id); | 83 | void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id); |
84 | }; | 84 | }; |
85 | 85 | ||
86 | #define HTC_TX_QUEUE_SIZE 256 | ||
87 | |||
88 | struct htc_txq { | ||
89 | struct sk_buff *buf[HTC_TX_QUEUE_SIZE]; | ||
90 | u32 txqdepth; | ||
91 | u16 txbuf_cnt; | ||
92 | u16 txq_head; | ||
93 | u16 txq_tail; | ||
94 | }; | ||
95 | |||
96 | struct htc_endpoint { | 86 | struct htc_endpoint { |
97 | u16 service_id; | 87 | u16 service_id; |
98 | 88 | ||
99 | struct htc_ep_callbacks ep_callbacks; | 89 | struct htc_ep_callbacks ep_callbacks; |
100 | struct htc_txq htc_txq; | ||
101 | u32 max_txqdepth; | 90 | u32 max_txqdepth; |
102 | int max_msglen; | 91 | int max_msglen; |
103 | 92 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 045abd557840..58f3d4210338 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -247,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) | |||
247 | { | 247 | { |
248 | u32 val; | 248 | u32 val; |
249 | 249 | ||
250 | switch (ah->hw_version.devid) { | ||
251 | case AR5416_AR9100_DEVID: | ||
252 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||
253 | break; | ||
254 | case AR9300_DEVID_AR9340: | ||
255 | ah->hw_version.macVersion = AR_SREV_VERSION_9340; | ||
256 | val = REG_READ(ah, AR_SREV); | ||
257 | ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); | ||
258 | return; | ||
259 | } | ||
260 | |||
250 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; | 261 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; |
251 | 262 | ||
252 | if (val == 0xFF) { | 263 | if (val == 0xFF) { |
@@ -462,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
462 | return ecode; | 473 | return ecode; |
463 | } | 474 | } |
464 | 475 | ||
465 | if (!AR_SREV_9100(ah)) { | 476 | if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) { |
466 | ath9k_hw_ani_setup(ah); | 477 | ath9k_hw_ani_setup(ah); |
467 | ath9k_hw_ani_init(ah); | 478 | ath9k_hw_ani_init(ah); |
468 | } | 479 | } |
@@ -484,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
484 | struct ath_common *common = ath9k_hw_common(ah); | 495 | struct ath_common *common = ath9k_hw_common(ah); |
485 | int r = 0; | 496 | int r = 0; |
486 | 497 | ||
487 | if (ah->hw_version.devid == AR5416_AR9100_DEVID) | ||
488 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||
489 | |||
490 | ath9k_hw_read_revisions(ah); | 498 | ath9k_hw_read_revisions(ah); |
491 | 499 | ||
492 | /* | 500 | /* |
@@ -544,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
544 | case AR_SREV_VERSION_9271: | 552 | case AR_SREV_VERSION_9271: |
545 | case AR_SREV_VERSION_9300: | 553 | case AR_SREV_VERSION_9300: |
546 | case AR_SREV_VERSION_9485: | 554 | case AR_SREV_VERSION_9485: |
555 | case AR_SREV_VERSION_9340: | ||
547 | break; | 556 | break; |
548 | default: | 557 | default: |
549 | ath_err(common, | 558 | ath_err(common, |
@@ -552,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
552 | return -EOPNOTSUPP; | 561 | return -EOPNOTSUPP; |
553 | } | 562 | } |
554 | 563 | ||
555 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah)) | 564 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah)) |
556 | ah->is_pciexpress = false; | 565 | ah->is_pciexpress = false; |
557 | 566 | ||
558 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); | 567 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); |
@@ -621,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
621 | case AR2427_DEVID_PCIE: | 630 | case AR2427_DEVID_PCIE: |
622 | case AR9300_DEVID_PCIE: | 631 | case AR9300_DEVID_PCIE: |
623 | case AR9300_DEVID_AR9485_PCIE: | 632 | case AR9300_DEVID_AR9485_PCIE: |
633 | case AR9300_DEVID_AR9340: | ||
624 | break; | 634 | break; |
625 | default: | 635 | default: |
626 | if (common->bus_ops->ath_bus_type == ATH_USB) | 636 | if (common->bus_ops->ath_bus_type == ATH_USB) |
@@ -663,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) | |||
663 | REGWRITE_BUFFER_FLUSH(ah); | 673 | REGWRITE_BUFFER_FLUSH(ah); |
664 | } | 674 | } |
665 | 675 | ||
666 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | 676 | u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) |
667 | { | 677 | { |
668 | REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); | 678 | REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); |
669 | udelay(100); | 679 | udelay(100); |
@@ -676,7 +686,6 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | |||
676 | } | 686 | } |
677 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); | 687 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); |
678 | 688 | ||
679 | #define DPLL3_PHASE_SHIFT_VAL 0x1 | ||
680 | static void ath9k_hw_init_pll(struct ath_hw *ah, | 689 | static void ath9k_hw_init_pll(struct ath_hw *ah, |
681 | struct ath9k_channel *chan) | 690 | struct ath9k_channel *chan) |
682 | { | 691 | { |
@@ -713,16 +722,48 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
713 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 722 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
714 | AR_CH0_BB_DPLL2_PLL_PWD, 0x0); | 723 | AR_CH0_BB_DPLL2_PLL_PWD, 0x0); |
715 | udelay(1000); | 724 | udelay(1000); |
725 | } else if (AR_SREV_9340(ah)) { | ||
726 | u32 regval, pll2_divint, pll2_divfrac, refdiv; | ||
716 | 727 | ||
717 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | 728 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); |
718 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | 729 | udelay(1000); |
730 | |||
731 | REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16); | ||
732 | udelay(100); | ||
733 | |||
734 | if (ah->is_clk_25mhz) { | ||
735 | pll2_divint = 0x54; | ||
736 | pll2_divfrac = 0x1eb85; | ||
737 | refdiv = 3; | ||
738 | } else { | ||
739 | pll2_divint = 88; | ||
740 | pll2_divfrac = 0; | ||
741 | refdiv = 5; | ||
742 | } | ||
743 | |||
744 | regval = REG_READ(ah, AR_PHY_PLL_MODE); | ||
745 | regval |= (0x1 << 16); | ||
746 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | ||
747 | udelay(100); | ||
748 | |||
749 | REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) | | ||
750 | (pll2_divint << 18) | pll2_divfrac); | ||
751 | udelay(100); | ||
752 | |||
753 | regval = REG_READ(ah, AR_PHY_PLL_MODE); | ||
754 | regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) | | ||
755 | (0x4 << 26) | (0x18 << 19); | ||
756 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | ||
757 | REG_WRITE(ah, AR_PHY_PLL_MODE, | ||
758 | REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff); | ||
759 | udelay(1000); | ||
719 | } | 760 | } |
720 | 761 | ||
721 | pll = ath9k_hw_compute_pll_control(ah, chan); | 762 | pll = ath9k_hw_compute_pll_control(ah, chan); |
722 | 763 | ||
723 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 764 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
724 | 765 | ||
725 | if (AR_SREV_9485(ah)) | 766 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) |
726 | udelay(1000); | 767 | udelay(1000); |
727 | 768 | ||
728 | /* Switch the core clock for ar9271 to 117Mhz */ | 769 | /* Switch the core clock for ar9271 to 117Mhz */ |
@@ -734,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
734 | udelay(RTC_PLL_SETTLE_DELAY); | 775 | udelay(RTC_PLL_SETTLE_DELAY); |
735 | 776 | ||
736 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); | 777 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); |
778 | |||
779 | if (AR_SREV_9340(ah)) { | ||
780 | if (ah->is_clk_25mhz) { | ||
781 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1); | ||
782 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7); | ||
783 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae); | ||
784 | } else { | ||
785 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1); | ||
786 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400); | ||
787 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e800); | ||
788 | } | ||
789 | udelay(100); | ||
790 | } | ||
737 | } | 791 | } |
738 | 792 | ||
739 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | 793 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, |
740 | enum nl80211_iftype opmode) | 794 | enum nl80211_iftype opmode) |
741 | { | 795 | { |
796 | u32 sync_default = AR_INTR_SYNC_DEFAULT; | ||
742 | u32 imr_reg = AR_IMR_TXERR | | 797 | u32 imr_reg = AR_IMR_TXERR | |
743 | AR_IMR_TXURN | | 798 | AR_IMR_TXURN | |
744 | AR_IMR_RXERR | | 799 | AR_IMR_RXERR | |
745 | AR_IMR_RXORN | | 800 | AR_IMR_RXORN | |
746 | AR_IMR_BCNMISC; | 801 | AR_IMR_BCNMISC; |
747 | 802 | ||
803 | if (AR_SREV_9340(ah)) | ||
804 | sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; | ||
805 | |||
748 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 806 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
749 | imr_reg |= AR_IMR_RXOK_HP; | 807 | imr_reg |= AR_IMR_RXOK_HP; |
750 | if (ah->config.rx_intr_mitigation) | 808 | if (ah->config.rx_intr_mitigation) |
@@ -775,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
775 | 833 | ||
776 | if (!AR_SREV_9100(ah)) { | 834 | if (!AR_SREV_9100(ah)) { |
777 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); | 835 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); |
778 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT); | 836 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); |
779 | REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); | 837 | REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); |
780 | } | 838 | } |
781 | 839 | ||
@@ -1487,7 +1545,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1487 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 1545 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); |
1488 | } | 1546 | } |
1489 | #ifdef __BIG_ENDIAN | 1547 | #ifdef __BIG_ENDIAN |
1490 | else | 1548 | else if (AR_SREV_9340(ah)) |
1549 | REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); | ||
1550 | else | ||
1491 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 1551 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); |
1492 | #endif | 1552 | #endif |
1493 | } | 1553 | } |
@@ -1793,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1793 | struct ath_common *common = ath9k_hw_common(ah); | 1853 | struct ath_common *common = ath9k_hw_common(ah); |
1794 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 1854 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
1795 | 1855 | ||
1796 | u16 capField = 0, eeval; | 1856 | u16 eeval; |
1797 | u8 ant_div_ctl1, tx_chainmask, rx_chainmask; | 1857 | u8 ant_div_ctl1, tx_chainmask, rx_chainmask; |
1798 | 1858 | ||
1799 | eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); | 1859 | eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); |
@@ -1804,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1804 | eeval |= AR9285_RDEXT_DEFAULT; | 1864 | eeval |= AR9285_RDEXT_DEFAULT; |
1805 | regulatory->current_rd_ext = eeval; | 1865 | regulatory->current_rd_ext = eeval; |
1806 | 1866 | ||
1807 | capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP); | ||
1808 | |||
1809 | if (ah->opmode != NL80211_IFTYPE_AP && | 1867 | if (ah->opmode != NL80211_IFTYPE_AP && |
1810 | ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { | 1868 | ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { |
1811 | if (regulatory->current_rd == 0x64 || | 1869 | if (regulatory->current_rd == 0x64 || |
@@ -1898,15 +1956,23 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1898 | else | 1956 | else |
1899 | pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; | 1957 | pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; |
1900 | 1958 | ||
1901 | if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) { | 1959 | if (common->btcoex_enabled) { |
1902 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; | 1960 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
1903 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; | ||
1904 | |||
1905 | if (AR_SREV_9285(ah)) { | ||
1906 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; | 1961 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; |
1907 | btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO; | 1962 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; |
1908 | } else { | 1963 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; |
1909 | btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; | 1964 | btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300; |
1965 | } else if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
1966 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280; | ||
1967 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280; | ||
1968 | |||
1969 | if (AR_SREV_9285(ah)) { | ||
1970 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; | ||
1971 | btcoex_hw->btpriority_gpio = | ||
1972 | ATH_BTPRIORITY_GPIO_9285; | ||
1973 | } else { | ||
1974 | btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; | ||
1975 | } | ||
1910 | } | 1976 | } |
1911 | } else { | 1977 | } else { |
1912 | btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; | 1978 | btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; |
@@ -2359,11 +2425,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc); | |||
2359 | 2425 | ||
2360 | void ath9k_hw_gen_timer_start(struct ath_hw *ah, | 2426 | void ath9k_hw_gen_timer_start(struct ath_hw *ah, |
2361 | struct ath_gen_timer *timer, | 2427 | struct ath_gen_timer *timer, |
2362 | u32 timer_next, | 2428 | u32 trig_timeout, |
2363 | u32 timer_period) | 2429 | u32 timer_period) |
2364 | { | 2430 | { |
2365 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | 2431 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; |
2366 | u32 tsf; | 2432 | u32 tsf, timer_next; |
2367 | 2433 | ||
2368 | BUG_ON(!timer_period); | 2434 | BUG_ON(!timer_period); |
2369 | 2435 | ||
@@ -2371,18 +2437,13 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, | |||
2371 | 2437 | ||
2372 | tsf = ath9k_hw_gettsf32(ah); | 2438 | tsf = ath9k_hw_gettsf32(ah); |
2373 | 2439 | ||
2440 | timer_next = tsf + trig_timeout; | ||
2441 | |||
2374 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, | 2442 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, |
2375 | "current tsf %x period %x timer_next %x\n", | 2443 | "current tsf %x period %x timer_next %x\n", |
2376 | tsf, timer_period, timer_next); | 2444 | tsf, timer_period, timer_next); |
2377 | 2445 | ||
2378 | /* | 2446 | /* |
2379 | * Pull timer_next forward if the current TSF already passed it | ||
2380 | * because of software latency | ||
2381 | */ | ||
2382 | if (timer_next < tsf) | ||
2383 | timer_next = tsf + timer_period; | ||
2384 | |||
2385 | /* | ||
2386 | * Program generic timer registers | 2447 | * Program generic timer registers |
2387 | */ | 2448 | */ |
2388 | REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr, | 2449 | REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 1018d6cbd530..34ed1bd0e855 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -43,6 +43,7 @@ | |||
43 | #define AR9287_DEVID_PCI 0x002d | 43 | #define AR9287_DEVID_PCI 0x002d |
44 | #define AR9287_DEVID_PCIE 0x002e | 44 | #define AR9287_DEVID_PCIE 0x002e |
45 | #define AR9300_DEVID_PCIE 0x0030 | 45 | #define AR9300_DEVID_PCIE 0x0030 |
46 | #define AR9300_DEVID_AR9340 0x0031 | ||
46 | #define AR9300_DEVID_AR9485_PCIE 0x0032 | 47 | #define AR9300_DEVID_AR9485_PCIE 0x0032 |
47 | 48 | ||
48 | #define AR5416_AR9100_DEVID 0x000b | 49 | #define AR5416_AR9100_DEVID 0x000b |
@@ -55,6 +56,9 @@ | |||
55 | #define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa | 56 | #define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa |
56 | #define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab | 57 | #define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab |
57 | 58 | ||
59 | #define AR9300_NUM_BT_WEIGHTS 4 | ||
60 | #define AR9300_NUM_WLAN_WEIGHTS 4 | ||
61 | |||
58 | #define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1) | 62 | #define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1) |
59 | 63 | ||
60 | #define ATH_DEFAULT_NOISE_FLOOR -95 | 64 | #define ATH_DEFAULT_NOISE_FLOOR -95 |
@@ -121,7 +125,7 @@ | |||
121 | #define AR_GPIO_BIT(_gpio) (1 << (_gpio)) | 125 | #define AR_GPIO_BIT(_gpio) (1 << (_gpio)) |
122 | 126 | ||
123 | #define BASE_ACTIVATE_DELAY 100 | 127 | #define BASE_ACTIVATE_DELAY 100 |
124 | #define RTC_PLL_SETTLE_DELAY 100 | 128 | #define RTC_PLL_SETTLE_DELAY (AR_SREV_9340(ah) ? 1000 : 100) |
125 | #define COEF_SCALE_S 24 | 129 | #define COEF_SCALE_S 24 |
126 | #define HT40_CHANNEL_CENTER_SHIFT 10 | 130 | #define HT40_CHANNEL_CENTER_SHIFT 10 |
127 | 131 | ||
@@ -771,6 +775,8 @@ struct ath_hw { | |||
771 | 775 | ||
772 | /* Bluetooth coexistance */ | 776 | /* Bluetooth coexistance */ |
773 | struct ath_btcoex_hw btcoex_hw; | 777 | struct ath_btcoex_hw btcoex_hw; |
778 | u32 bt_coex_bt_weight[AR9300_NUM_BT_WEIGHTS]; | ||
779 | u32 bt_coex_wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; | ||
774 | 780 | ||
775 | u32 intr_txqs; | 781 | u32 intr_txqs; |
776 | u8 txchainmask; | 782 | u8 txchainmask; |
@@ -799,6 +805,7 @@ struct ath_hw { | |||
799 | struct ar5416IniArray iniPcieSerdes; | 805 | struct ar5416IniArray iniPcieSerdes; |
800 | struct ar5416IniArray iniPcieSerdesLowPower; | 806 | struct ar5416IniArray iniPcieSerdesLowPower; |
801 | struct ar5416IniArray iniModesAdditional; | 807 | struct ar5416IniArray iniModesAdditional; |
808 | struct ar5416IniArray iniModesAdditional_40M; | ||
802 | struct ar5416IniArray iniModesRxGain; | 809 | struct ar5416IniArray iniModesRxGain; |
803 | struct ar5416IniArray iniModesTxGain; | 810 | struct ar5416IniArray iniModesTxGain; |
804 | struct ar5416IniArray iniModes_9271_1_0_only; | 811 | struct ar5416IniArray iniModes_9271_1_0_only; |
@@ -845,6 +852,8 @@ struct ath_hw { | |||
845 | 852 | ||
846 | /* Enterprise mode cap */ | 853 | /* Enterprise mode cap */ |
847 | u32 ent_mode; | 854 | u32 ent_mode; |
855 | |||
856 | bool is_clk_25mhz; | ||
848 | }; | 857 | }; |
849 | 858 | ||
850 | struct ath_bus_ops { | 859 | struct ath_bus_ops { |
@@ -928,7 +937,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | |||
928 | void ath9k_hw_reset_tsf(struct ath_hw *ah); | 937 | void ath9k_hw_reset_tsf(struct ath_hw *ah); |
929 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | 938 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); |
930 | void ath9k_hw_init_global_settings(struct ath_hw *ah); | 939 | void ath9k_hw_init_global_settings(struct ath_hw *ah); |
931 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); | 940 | u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); |
932 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); | 941 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); |
933 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | 942 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); |
934 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | 943 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 1ac8318d82a3..b172d1509515 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -574,6 +574,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
574 | sc->sc_ah->gpio_mask = pdata->gpio_mask; | 574 | sc->sc_ah->gpio_mask = pdata->gpio_mask; |
575 | sc->sc_ah->gpio_val = pdata->gpio_val; | 575 | sc->sc_ah->gpio_val = pdata->gpio_val; |
576 | sc->sc_ah->led_pin = pdata->led_pin; | 576 | sc->sc_ah->led_pin = pdata->led_pin; |
577 | ah->is_clk_25mhz = pdata->is_clk_25mhz; | ||
577 | } | 578 | } |
578 | 579 | ||
579 | common = ath9k_hw_common(ah); | 580 | common = ath9k_hw_common(ah); |
@@ -800,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
800 | 801 | ||
801 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | 802 | INIT_WORK(&sc->hw_check_work, ath_hw_check); |
802 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | 803 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); |
804 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
803 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 805 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
804 | 806 | ||
805 | ath_init_leds(sc); | 807 | ath_init_leds(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 1968c67e3fab..9cf7a7d0e118 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -812,10 +812,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts); | |||
812 | void ath9k_hw_enable_interrupts(struct ath_hw *ah) | 812 | void ath9k_hw_enable_interrupts(struct ath_hw *ah) |
813 | { | 813 | { |
814 | struct ath_common *common = ath9k_hw_common(ah); | 814 | struct ath_common *common = ath9k_hw_common(ah); |
815 | u32 sync_default = AR_INTR_SYNC_DEFAULT; | ||
815 | 816 | ||
816 | if (!(ah->imask & ATH9K_INT_GLOBAL)) | 817 | if (!(ah->imask & ATH9K_INT_GLOBAL)) |
817 | return; | 818 | return; |
818 | 819 | ||
820 | if (AR_SREV_9340(ah)) | ||
821 | sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; | ||
822 | |||
819 | ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n"); | 823 | ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n"); |
820 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); | 824 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); |
821 | if (!AR_SREV_9100(ah)) { | 825 | if (!AR_SREV_9100(ah)) { |
@@ -824,10 +828,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) | |||
824 | REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); | 828 | REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); |
825 | 829 | ||
826 | 830 | ||
827 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, | 831 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); |
828 | AR_INTR_SYNC_DEFAULT); | 832 | REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default); |
829 | REG_WRITE(ah, AR_INTR_SYNC_MASK, | ||
830 | AR_INTR_SYNC_DEFAULT); | ||
831 | } | 833 | } |
832 | ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", | 834 | ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", |
833 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); | 835 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); |
@@ -883,6 +885,9 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
883 | mask |= AR_IMR_GENTMR; | 885 | mask |= AR_IMR_GENTMR; |
884 | } | 886 | } |
885 | 887 | ||
888 | if (ints & ATH9K_INT_GENTIMER) | ||
889 | mask |= AR_IMR_GENTMR; | ||
890 | |||
886 | if (ints & (ATH9K_INT_BMISC)) { | 891 | if (ints & (ATH9K_INT_BMISC)) { |
887 | mask |= AR_IMR_BCNMISC; | 892 | mask |= AR_IMR_BCNMISC; |
888 | if (ints & ATH9K_INT_TIM) | 893 | if (ints & ATH9K_INT_TIM) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a8d9009a76d5..c3dbf2661a3f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -624,6 +624,43 @@ out: | |||
624 | ath9k_ps_restore(sc); | 624 | ath9k_ps_restore(sc); |
625 | } | 625 | } |
626 | 626 | ||
627 | static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | ||
628 | { | ||
629 | static int count; | ||
630 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
631 | |||
632 | if (pll_sqsum >= 0x40000) { | ||
633 | count++; | ||
634 | if (count == 3) { | ||
635 | /* Rx is hung for more than 500ms. Reset it */ | ||
636 | ath_dbg(common, ATH_DBG_RESET, | ||
637 | "Possible RX hang, resetting"); | ||
638 | ath_reset(sc, true); | ||
639 | count = 0; | ||
640 | } | ||
641 | } else | ||
642 | count = 0; | ||
643 | } | ||
644 | |||
645 | void ath_hw_pll_work(struct work_struct *work) | ||
646 | { | ||
647 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
648 | hw_pll_work.work); | ||
649 | u32 pll_sqsum; | ||
650 | |||
651 | if (AR_SREV_9485(sc->sc_ah)) { | ||
652 | |||
653 | ath9k_ps_wakeup(sc); | ||
654 | pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); | ||
655 | ath9k_ps_restore(sc); | ||
656 | |||
657 | ath_hw_pll_rx_hang_check(sc, pll_sqsum); | ||
658 | |||
659 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | |||
627 | void ath9k_tasklet(unsigned long data) | 664 | void ath9k_tasklet(unsigned long data) |
628 | { | 665 | { |
629 | struct ath_softc *sc = (struct ath_softc *)data; | 666 | struct ath_softc *sc = (struct ath_softc *)data; |
@@ -1932,6 +1969,12 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1932 | "Bss Info ASSOC %d, bssid: %pM\n", | 1969 | "Bss Info ASSOC %d, bssid: %pM\n", |
1933 | bss_conf->aid, common->curbssid); | 1970 | bss_conf->aid, common->curbssid); |
1934 | ath_beacon_config(sc, vif); | 1971 | ath_beacon_config(sc, vif); |
1972 | /* | ||
1973 | * Request a re-configuration of Beacon related timers | ||
1974 | * on the receipt of the first Beacon frame (i.e., | ||
1975 | * after time sync with the AP). | ||
1976 | */ | ||
1977 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
1935 | /* Reset rssi stats */ | 1978 | /* Reset rssi stats */ |
1936 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 1979 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
1937 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1980 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
@@ -2219,9 +2262,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2219 | int timeout = 200; /* ms */ | 2262 | int timeout = 200; /* ms */ |
2220 | int i, j; | 2263 | int i, j; |
2221 | 2264 | ||
2222 | ath9k_ps_wakeup(sc); | ||
2223 | mutex_lock(&sc->mutex); | 2265 | mutex_lock(&sc->mutex); |
2224 | |||
2225 | cancel_delayed_work_sync(&sc->tx_complete_work); | 2266 | cancel_delayed_work_sync(&sc->tx_complete_work); |
2226 | 2267 | ||
2227 | if (drop) | 2268 | if (drop) |
@@ -2244,15 +2285,15 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2244 | goto out; | 2285 | goto out; |
2245 | } | 2286 | } |
2246 | 2287 | ||
2288 | ath9k_ps_wakeup(sc); | ||
2247 | if (!ath_drain_all_txq(sc, false)) | 2289 | if (!ath_drain_all_txq(sc, false)) |
2248 | ath_reset(sc, false); | 2290 | ath_reset(sc, false); |
2249 | 2291 | ath9k_ps_restore(sc); | |
2250 | ieee80211_wake_queues(hw); | 2292 | ieee80211_wake_queues(hw); |
2251 | 2293 | ||
2252 | out: | 2294 | out: |
2253 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); | 2295 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); |
2254 | mutex_unlock(&sc->mutex); | 2296 | mutex_unlock(&sc->mutex); |
2255 | ath9k_ps_restore(sc); | ||
2256 | } | 2297 | } |
2257 | 2298 | ||
2258 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) | 2299 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) |
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 8e5fe9d7f174..9441bf8ca2fd 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -45,4 +45,7 @@ | |||
45 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 | 45 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 |
46 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 | 46 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 |
47 | 47 | ||
48 | #define AR_PHY_PLL_CONTROL 0x16180 | ||
49 | #define AR_PHY_PLL_MODE 0x16184 | ||
50 | |||
48 | #endif | 51 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 18094094b298..4ccbf2ddb553 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -854,14 +854,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
854 | ath_rc_rate_set_rtscts(sc, rate_table, tx_info); | 854 | ath_rc_rate_set_rtscts(sc, rate_table, tx_info); |
855 | } | 855 | } |
856 | 856 | ||
857 | static bool ath_rc_update_per(struct ath_softc *sc, | 857 | static void ath_rc_update_per(struct ath_softc *sc, |
858 | const struct ath_rate_table *rate_table, | 858 | const struct ath_rate_table *rate_table, |
859 | struct ath_rate_priv *ath_rc_priv, | 859 | struct ath_rate_priv *ath_rc_priv, |
860 | struct ieee80211_tx_info *tx_info, | 860 | struct ieee80211_tx_info *tx_info, |
861 | int tx_rate, int xretries, int retries, | 861 | int tx_rate, int xretries, int retries, |
862 | u32 now_msec) | 862 | u32 now_msec) |
863 | { | 863 | { |
864 | bool state_change = false; | ||
865 | int count, n_bad_frames; | 864 | int count, n_bad_frames; |
866 | u8 last_per; | 865 | u8 last_per; |
867 | static const u32 nretry_to_per_lookup[10] = { | 866 | static const u32 nretry_to_per_lookup[10] = { |
@@ -992,8 +991,6 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
992 | 991 | ||
993 | } | 992 | } |
994 | } | 993 | } |
995 | |||
996 | return state_change; | ||
997 | } | 994 | } |
998 | 995 | ||
999 | static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | 996 | static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, |
@@ -1017,7 +1014,6 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
1017 | u32 now_msec = jiffies_to_msecs(jiffies); | 1014 | u32 now_msec = jiffies_to_msecs(jiffies); |
1018 | int rate; | 1015 | int rate; |
1019 | u8 last_per; | 1016 | u8 last_per; |
1020 | bool state_change = false; | ||
1021 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | 1017 | const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; |
1022 | int size = ath_rc_priv->rate_table_size; | 1018 | int size = ath_rc_priv->rate_table_size; |
1023 | 1019 | ||
@@ -1027,9 +1023,9 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
1027 | last_per = ath_rc_priv->per[tx_rate]; | 1023 | last_per = ath_rc_priv->per[tx_rate]; |
1028 | 1024 | ||
1029 | /* Update PER first */ | 1025 | /* Update PER first */ |
1030 | state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, | 1026 | ath_rc_update_per(sc, rate_table, ath_rc_priv, |
1031 | tx_info, tx_rate, xretries, | 1027 | tx_info, tx_rate, xretries, |
1032 | retries, now_msec); | 1028 | retries, now_msec); |
1033 | 1029 | ||
1034 | /* | 1030 | /* |
1035 | * If this rate looks bad (high PER) then stop using it for | 1031 | * If this rate looks bad (high PER) then stop using it for |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index f69dcdf0e2e6..c5b7cbe59bfa 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -1339,7 +1339,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1339 | struct ath_hw_antcomb_conf div_ant_conf; | 1339 | struct ath_hw_antcomb_conf div_ant_conf; |
1340 | struct ath_ant_comb *antcomb = &sc->ant_comb; | 1340 | struct ath_ant_comb *antcomb = &sc->ant_comb; |
1341 | int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; | 1341 | int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; |
1342 | int curr_main_set, curr_bias; | 1342 | int curr_main_set; |
1343 | int main_rssi = rs->rs_rssi_ctl0; | 1343 | int main_rssi = rs->rs_rssi_ctl0; |
1344 | int alt_rssi = rs->rs_rssi_ctl1; | 1344 | int alt_rssi = rs->rs_rssi_ctl1; |
1345 | int rx_ant_conf, main_ant_conf; | 1345 | int rx_ant_conf, main_ant_conf; |
@@ -1393,7 +1393,6 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1393 | ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); | 1393 | ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); |
1394 | curr_alt_set = div_ant_conf.alt_lna_conf; | 1394 | curr_alt_set = div_ant_conf.alt_lna_conf; |
1395 | curr_main_set = div_ant_conf.main_lna_conf; | 1395 | curr_main_set = div_ant_conf.main_lna_conf; |
1396 | curr_bias = div_ant_conf.fast_div_bias; | ||
1397 | 1396 | ||
1398 | antcomb->count++; | 1397 | antcomb->count++; |
1399 | 1398 | ||
@@ -1743,7 +1742,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1743 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | | 1742 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | |
1744 | PS_WAIT_FOR_CAB | | 1743 | PS_WAIT_FOR_CAB | |
1745 | PS_WAIT_FOR_PSPOLL_DATA)) || | 1744 | PS_WAIT_FOR_PSPOLL_DATA)) || |
1746 | unlikely(ath9k_check_auto_sleep(sc))) | 1745 | ath9k_check_auto_sleep(sc)) |
1747 | ath_rx_ps(sc, skb); | 1746 | ath_rx_ps(sc, skb); |
1748 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 1747 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
1749 | 1748 | ||
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 6acbf0e2240b..456f3ec20fef 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -693,7 +693,7 @@ | |||
693 | #define AR_RC_APB 0x00000002 | 693 | #define AR_RC_APB 0x00000002 |
694 | #define AR_RC_HOSTIF 0x00000100 | 694 | #define AR_RC_HOSTIF 0x00000100 |
695 | 695 | ||
696 | #define AR_WA 0x4004 | 696 | #define AR_WA (AR_SREV_9340(ah) ? 0x40c4 : 0x4004) |
697 | #define AR_WA_BIT6 (1 << 6) | 697 | #define AR_WA_BIT6 (1 << 6) |
698 | #define AR_WA_BIT7 (1 << 7) | 698 | #define AR_WA_BIT7 (1 << 7) |
699 | #define AR_WA_BIT23 (1 << 23) | 699 | #define AR_WA_BIT23 (1 << 23) |
@@ -712,7 +712,7 @@ | |||
712 | #define AR_PM_STATE 0x4008 | 712 | #define AR_PM_STATE 0x4008 |
713 | #define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000 | 713 | #define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000 |
714 | 714 | ||
715 | #define AR_HOST_TIMEOUT 0x4018 | 715 | #define AR_HOST_TIMEOUT (AR_SREV_9340(ah) ? 0x4008 : 0x4018) |
716 | #define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF | 716 | #define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF |
717 | #define AR_HOST_TIMEOUT_APB_CNTR_S 0 | 717 | #define AR_HOST_TIMEOUT_APB_CNTR_S 0 |
718 | #define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000 | 718 | #define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000 |
@@ -742,7 +742,8 @@ | |||
742 | #define EEPROM_PROTECT_WP_1024_2047 0x8000 | 742 | #define EEPROM_PROTECT_WP_1024_2047 0x8000 |
743 | 743 | ||
744 | #define AR_SREV \ | 744 | #define AR_SREV \ |
745 | ((AR_SREV_9100(ah)) ? 0x0600 : 0x4020) | 745 | ((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \ |
746 | ? 0x400c : 0x4020)) | ||
746 | 747 | ||
747 | #define AR_SREV_ID \ | 748 | #define AR_SREV_ID \ |
748 | ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF) | 749 | ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF) |
@@ -790,6 +791,7 @@ | |||
790 | #define AR_SREV_VERSION_9485 0x240 | 791 | #define AR_SREV_VERSION_9485 0x240 |
791 | #define AR_SREV_REVISION_9485_10 0 | 792 | #define AR_SREV_REVISION_9485_10 0 |
792 | #define AR_SREV_REVISION_9485_11 1 | 793 | #define AR_SREV_REVISION_9485_11 1 |
794 | #define AR_SREV_VERSION_9340 0x300 | ||
793 | 795 | ||
794 | #define AR_SREV_5416(_ah) \ | 796 | #define AR_SREV_5416(_ah) \ |
795 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ | 797 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ |
@@ -868,6 +870,11 @@ | |||
868 | #define AR_SREV_9485_11(_ah) \ | 870 | #define AR_SREV_9485_11(_ah) \ |
869 | (AR_SREV_9485(_ah) && \ | 871 | (AR_SREV_9485(_ah) && \ |
870 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) | 872 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) |
873 | #define AR_SREV_9485_OR_LATER(_ah) \ | ||
874 | (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485)) | ||
875 | |||
876 | #define AR_SREV_9340(_ah) \ | ||
877 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340)) | ||
871 | 878 | ||
872 | #define AR_SREV_9285E_20(_ah) \ | 879 | #define AR_SREV_9285E_20(_ah) \ |
873 | (AR_SREV_9285_12_OR_LATER(_ah) && \ | 880 | (AR_SREV_9285_12_OR_LATER(_ah) && \ |
@@ -910,11 +917,11 @@ enum ath_usb_dev { | |||
910 | #define AR_INTR_SPURIOUS 0xFFFFFFFF | 917 | #define AR_INTR_SPURIOUS 0xFFFFFFFF |
911 | 918 | ||
912 | 919 | ||
913 | #define AR_INTR_SYNC_CAUSE_CLR 0x4028 | 920 | #define AR_INTR_SYNC_CAUSE (AR_SREV_9340(ah) ? 0x4010 : 0x4028) |
921 | #define AR_INTR_SYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4010 : 0x4028) | ||
914 | 922 | ||
915 | #define AR_INTR_SYNC_CAUSE 0x4028 | ||
916 | 923 | ||
917 | #define AR_INTR_SYNC_ENABLE 0x402c | 924 | #define AR_INTR_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4014 : 0x402c) |
918 | #define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000 | 925 | #define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000 |
919 | #define AR_INTR_SYNC_ENABLE_GPIO_S 18 | 926 | #define AR_INTR_SYNC_ENABLE_GPIO_S 18 |
920 | 927 | ||
@@ -954,24 +961,24 @@ enum { | |||
954 | 961 | ||
955 | }; | 962 | }; |
956 | 963 | ||
957 | #define AR_INTR_ASYNC_MASK 0x4030 | 964 | #define AR_INTR_ASYNC_MASK (AR_SREV_9340(ah) ? 0x4018 : 0x4030) |
958 | #define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000 | 965 | #define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000 |
959 | #define AR_INTR_ASYNC_MASK_GPIO_S 18 | 966 | #define AR_INTR_ASYNC_MASK_GPIO_S 18 |
960 | 967 | ||
961 | #define AR_INTR_SYNC_MASK 0x4034 | 968 | #define AR_INTR_SYNC_MASK (AR_SREV_9340(ah) ? 0x401c : 0x4034) |
962 | #define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000 | 969 | #define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000 |
963 | #define AR_INTR_SYNC_MASK_GPIO_S 18 | 970 | #define AR_INTR_SYNC_MASK_GPIO_S 18 |
964 | 971 | ||
965 | #define AR_INTR_ASYNC_CAUSE_CLR 0x4038 | 972 | #define AR_INTR_ASYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4020 : 0x4038) |
966 | #define AR_INTR_ASYNC_CAUSE 0x4038 | 973 | #define AR_INTR_ASYNC_CAUSE (AR_SREV_9340(ah) ? 0x4020 : 0x4038) |
967 | 974 | ||
968 | #define AR_INTR_ASYNC_ENABLE 0x403c | 975 | #define AR_INTR_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4024 : 0x403c) |
969 | #define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000 | 976 | #define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000 |
970 | #define AR_INTR_ASYNC_ENABLE_GPIO_S 18 | 977 | #define AR_INTR_ASYNC_ENABLE_GPIO_S 18 |
971 | 978 | ||
972 | #define AR_PCIE_SERDES 0x4040 | 979 | #define AR_PCIE_SERDES 0x4040 |
973 | #define AR_PCIE_SERDES2 0x4044 | 980 | #define AR_PCIE_SERDES2 0x4044 |
974 | #define AR_PCIE_PM_CTRL 0x4014 | 981 | #define AR_PCIE_PM_CTRL (AR_SREV_9340(ah) ? 0x4004 : 0x4014) |
975 | #define AR_PCIE_PM_CTRL_ENA 0x00080000 | 982 | #define AR_PCIE_PM_CTRL_ENA 0x00080000 |
976 | 983 | ||
977 | #define AR_NUM_GPIO 14 | 984 | #define AR_NUM_GPIO 14 |
@@ -982,7 +989,7 @@ enum { | |||
982 | #define AR9300_NUM_GPIO 17 | 989 | #define AR9300_NUM_GPIO 17 |
983 | #define AR7010_NUM_GPIO 16 | 990 | #define AR7010_NUM_GPIO 16 |
984 | 991 | ||
985 | #define AR_GPIO_IN_OUT 0x4048 | 992 | #define AR_GPIO_IN_OUT (AR_SREV_9340(ah) ? 0x4028 : 0x4048) |
986 | #define AR_GPIO_IN_VAL 0x0FFFC000 | 993 | #define AR_GPIO_IN_VAL 0x0FFFC000 |
987 | #define AR_GPIO_IN_VAL_S 14 | 994 | #define AR_GPIO_IN_VAL_S 14 |
988 | #define AR928X_GPIO_IN_VAL 0x000FFC00 | 995 | #define AR928X_GPIO_IN_VAL 0x000FFC00 |
@@ -996,11 +1003,12 @@ enum { | |||
996 | #define AR7010_GPIO_IN_VAL 0x0000FFFF | 1003 | #define AR7010_GPIO_IN_VAL 0x0000FFFF |
997 | #define AR7010_GPIO_IN_VAL_S 0 | 1004 | #define AR7010_GPIO_IN_VAL_S 0 |
998 | 1005 | ||
999 | #define AR_GPIO_IN 0x404c | 1006 | #define AR_GPIO_IN (AR_SREV_9340(ah) ? 0x402c : 0x404c) |
1000 | #define AR9300_GPIO_IN_VAL 0x0001FFFF | 1007 | #define AR9300_GPIO_IN_VAL 0x0001FFFF |
1001 | #define AR9300_GPIO_IN_VAL_S 0 | 1008 | #define AR9300_GPIO_IN_VAL_S 0 |
1002 | 1009 | ||
1003 | #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) | 1010 | #define AR_GPIO_OE_OUT (AR_SREV_9340(ah) ? 0x4030 : \ |
1011 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)) | ||
1004 | #define AR_GPIO_OE_OUT_DRV 0x3 | 1012 | #define AR_GPIO_OE_OUT_DRV 0x3 |
1005 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 | 1013 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 |
1006 | #define AR_GPIO_OE_OUT_DRV_LOW 0x1 | 1014 | #define AR_GPIO_OE_OUT_DRV_LOW 0x1 |
@@ -1022,11 +1030,13 @@ enum { | |||
1022 | #define AR7010_GPIO_INT_MASK 0x52024 | 1030 | #define AR7010_GPIO_INT_MASK 0x52024 |
1023 | #define AR7010_GPIO_FUNCTION 0x52028 | 1031 | #define AR7010_GPIO_FUNCTION 0x52028 |
1024 | 1032 | ||
1025 | #define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050) | 1033 | #define AR_GPIO_INTR_POL (AR_SREV_9340(ah) ? 0x4038 : \ |
1034 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)) | ||
1026 | #define AR_GPIO_INTR_POL_VAL 0x0001FFFF | 1035 | #define AR_GPIO_INTR_POL_VAL 0x0001FFFF |
1027 | #define AR_GPIO_INTR_POL_VAL_S 0 | 1036 | #define AR_GPIO_INTR_POL_VAL_S 0 |
1028 | 1037 | ||
1029 | #define AR_GPIO_INPUT_EN_VAL (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054) | 1038 | #define AR_GPIO_INPUT_EN_VAL (AR_SREV_9340(ah) ? 0x403c : \ |
1039 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)) | ||
1030 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 | 1040 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 |
1031 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 | 1041 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 |
1032 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 | 1042 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 |
@@ -1044,13 +1054,15 @@ enum { | |||
1044 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 | 1054 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 |
1045 | #define AR_GPIO_JTAG_DISABLE 0x00020000 | 1055 | #define AR_GPIO_JTAG_DISABLE 0x00020000 |
1046 | 1056 | ||
1047 | #define AR_GPIO_INPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058) | 1057 | #define AR_GPIO_INPUT_MUX1 (AR_SREV_9340(ah) ? 0x4040 : \ |
1058 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)) | ||
1048 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000 | 1059 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000 |
1049 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 | 1060 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 |
1050 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00 | 1061 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00 |
1051 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8 | 1062 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8 |
1052 | 1063 | ||
1053 | #define AR_GPIO_INPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c) | 1064 | #define AR_GPIO_INPUT_MUX2 (AR_SREV_9340(ah) ? 0x4044 : \ |
1065 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)) | ||
1054 | #define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f | 1066 | #define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f |
1055 | #define AR_GPIO_INPUT_MUX2_CLK25_S 0 | 1067 | #define AR_GPIO_INPUT_MUX2_CLK25_S 0 |
1056 | #define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0 | 1068 | #define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0 |
@@ -1058,13 +1070,18 @@ enum { | |||
1058 | #define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00 | 1070 | #define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00 |
1059 | #define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 | 1071 | #define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 |
1060 | 1072 | ||
1061 | #define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060) | 1073 | #define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9340(ah) ? 0x4048 : \ |
1062 | #define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064) | 1074 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)) |
1063 | #define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068) | 1075 | #define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9340(ah) ? 0x404c : \ |
1076 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)) | ||
1077 | #define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9340(ah) ? 0x4050 : \ | ||
1078 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)) | ||
1064 | 1079 | ||
1065 | #define AR_INPUT_STATE (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c) | 1080 | #define AR_INPUT_STATE (AR_SREV_9340(ah) ? 0x4054 : \ |
1081 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)) | ||
1066 | 1082 | ||
1067 | #define AR_EEPROM_STATUS_DATA (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c) | 1083 | #define AR_EEPROM_STATUS_DATA (AR_SREV_9340(ah) ? 0x40c8 : \ |
1084 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)) | ||
1068 | #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff | 1085 | #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff |
1069 | #define AR_EEPROM_STATUS_DATA_VAL_S 0 | 1086 | #define AR_EEPROM_STATUS_DATA_VAL_S 0 |
1070 | #define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 | 1087 | #define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 |
@@ -1072,17 +1089,19 @@ enum { | |||
1072 | #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 | 1089 | #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 |
1073 | #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 | 1090 | #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 |
1074 | 1091 | ||
1075 | #define AR_OBS (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080) | 1092 | #define AR_OBS (AR_SREV_9340(ah) ? 0x405c : \ |
1093 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)) | ||
1076 | 1094 | ||
1077 | #define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088) | 1095 | #define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088) |
1078 | 1096 | ||
1079 | #define AR_PCIE_MSI (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094) | 1097 | #define AR_PCIE_MSI (AR_SREV_9340(ah) ? 0x40d8 : \ |
1098 | (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)) | ||
1080 | #define AR_PCIE_MSI_ENABLE 0x00000001 | 1099 | #define AR_PCIE_MSI_ENABLE 0x00000001 |
1081 | 1100 | ||
1082 | #define AR_INTR_PRIO_SYNC_ENABLE 0x40c4 | 1101 | #define AR_INTR_PRIO_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4088 : 0x40c4) |
1083 | #define AR_INTR_PRIO_ASYNC_MASK 0x40c8 | 1102 | #define AR_INTR_PRIO_ASYNC_MASK (AR_SREV_9340(ah) ? 0x408c : 0x40c8) |
1084 | #define AR_INTR_PRIO_SYNC_MASK 0x40cc | 1103 | #define AR_INTR_PRIO_SYNC_MASK (AR_SREV_9340(ah) ? 0x4090 : 0x40cc) |
1085 | #define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 | 1104 | #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4) |
1086 | #define AR_ENT_OTP 0x40d8 | 1105 | #define AR_ENT_OTP 0x40d8 |
1087 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 | 1106 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 |
1088 | #define AR_ENT_OTP_MPSD 0x00800000 | 1107 | #define AR_ENT_OTP_MPSD 0x00800000 |
@@ -1163,6 +1182,7 @@ enum { | |||
1163 | #define AR_RTC_PLL_REFDIV_5 0x000000c0 | 1182 | #define AR_RTC_PLL_REFDIV_5 0x000000c0 |
1164 | #define AR_RTC_PLL_CLKSEL 0x00000300 | 1183 | #define AR_RTC_PLL_CLKSEL 0x00000300 |
1165 | #define AR_RTC_PLL_CLKSEL_S 8 | 1184 | #define AR_RTC_PLL_CLKSEL_S 8 |
1185 | #define AR_RTC_PLL_BYPASS 0x00010000 | ||
1166 | 1186 | ||
1167 | #define PLL3 0x16188 | 1187 | #define PLL3 0x16188 |
1168 | #define PLL3_DO_MEAS_MASK 0x40000000 | 1188 | #define PLL3_DO_MEAS_MASK 0x40000000 |
@@ -1209,7 +1229,8 @@ enum { | |||
1209 | 1229 | ||
1210 | /* RTC_DERIVED_* - only for AR9100 */ | 1230 | /* RTC_DERIVED_* - only for AR9100 */ |
1211 | 1231 | ||
1212 | #define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038) | 1232 | #define AR_RTC_DERIVED_CLK \ |
1233 | (AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038) | ||
1213 | #define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe | 1234 | #define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe |
1214 | #define AR_RTC_DERIVED_CLK_PERIOD_S 1 | 1235 | #define AR_RTC_DERIVED_CLK_PERIOD_S 1 |
1215 | 1236 | ||
@@ -1688,6 +1709,22 @@ enum { | |||
1688 | #define AR_BTCOEX_WL_WGHT 0xffff0000 | 1709 | #define AR_BTCOEX_WL_WGHT 0xffff0000 |
1689 | #define AR_BTCOEX_WL_WGHT_S 16 | 1710 | #define AR_BTCOEX_WL_WGHT_S 16 |
1690 | 1711 | ||
1712 | #define AR_BT_COEX_WL_WEIGHTS0 0x8174 | ||
1713 | #define AR_BT_COEX_WL_WEIGHTS1 0x81c4 | ||
1714 | |||
1715 | #define AR_BT_COEX_BT_WEIGHTS0 0x83ac | ||
1716 | #define AR_BT_COEX_BT_WEIGHTS1 0x83b0 | ||
1717 | #define AR_BT_COEX_BT_WEIGHTS2 0x83b4 | ||
1718 | #define AR_BT_COEX_BT_WEIGHTS3 0x83b8 | ||
1719 | |||
1720 | #define AR9300_BT_WGHT 0xcccc4444 | ||
1721 | #define AR9300_STOMP_ALL_WLAN_WGHT0 0xfffffff0 | ||
1722 | #define AR9300_STOMP_ALL_WLAN_WGHT1 0xfffffff0 | ||
1723 | #define AR9300_STOMP_LOW_WLAN_WGHT0 0x88888880 | ||
1724 | #define AR9300_STOMP_LOW_WLAN_WGHT1 0x88888880 | ||
1725 | #define AR9300_STOMP_NONE_WLAN_WGHT0 0x00000000 | ||
1726 | #define AR9300_STOMP_NONE_WLAN_WGHT1 0x00000000 | ||
1727 | |||
1691 | #define AR_BT_COEX_MODE2 0x817c | 1728 | #define AR_BT_COEX_MODE2 0x817c |
1692 | #define AR_BT_BCN_MISS_THRESH 0x000000ff | 1729 | #define AR_BT_BCN_MISS_THRESH 0x000000ff |
1693 | #define AR_BT_BCN_MISS_THRESH_S 0 | 1730 | #define AR_BT_BCN_MISS_THRESH_S 0 |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 8f095ad0a3db..f9b1eb4853c4 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -79,8 +79,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
79 | return "WMI_TX_STATS_CMDID"; | 79 | return "WMI_TX_STATS_CMDID"; |
80 | case WMI_RX_STATS_CMDID: | 80 | case WMI_RX_STATS_CMDID: |
81 | return "WMI_RX_STATS_CMDID"; | 81 | return "WMI_RX_STATS_CMDID"; |
82 | case WMI_AGGR_LIMIT_CMD: | 82 | case WMI_BITRATE_MASK_CMDID: |
83 | return "WMI_AGGR_LIMIT_CMD"; | 83 | return "WMI_BITRATE_MASK_CMDID"; |
84 | } | 84 | } |
85 | 85 | ||
86 | return "Bogus"; | 86 | return "Bogus"; |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 02ecb9f06db0..6095eeb6e025 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h | |||
@@ -111,7 +111,7 @@ enum wmi_cmd_id { | |||
111 | WMI_INT_STATS_CMDID, | 111 | WMI_INT_STATS_CMDID, |
112 | WMI_TX_STATS_CMDID, | 112 | WMI_TX_STATS_CMDID, |
113 | WMI_RX_STATS_CMDID, | 113 | WMI_RX_STATS_CMDID, |
114 | WMI_AGGR_LIMIT_CMD = 0x0026, | 114 | WMI_BITRATE_MASK_CMDID, |
115 | }; | 115 | }; |
116 | 116 | ||
117 | enum wmi_event_id { | 117 | enum wmi_event_id { |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index e9e99f730ca8..7b91b2aa6240 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2180,28 +2180,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2180 | } | 2180 | } |
2181 | } | 2181 | } |
2182 | 2182 | ||
2183 | static void ath_hw_pll_work(struct work_struct *work) | ||
2184 | { | ||
2185 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
2186 | hw_pll_work.work); | ||
2187 | static int count; | ||
2188 | |||
2189 | if (AR_SREV_9485(sc->sc_ah)) { | ||
2190 | if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) { | ||
2191 | count++; | ||
2192 | |||
2193 | if (count == 3) { | ||
2194 | /* Rx is hung for more than 500ms. Reset it */ | ||
2195 | ath_reset(sc, true); | ||
2196 | count = 0; | ||
2197 | } | ||
2198 | } else | ||
2199 | count = 0; | ||
2200 | |||
2201 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||
2202 | } | ||
2203 | } | ||
2204 | |||
2205 | static void ath_tx_complete_poll_work(struct work_struct *work) | 2183 | static void ath_tx_complete_poll_work(struct work_struct *work) |
2206 | { | 2184 | { |
2207 | struct ath_softc *sc = container_of(work, struct ath_softc, | 2185 | struct ath_softc *sc = container_of(work, struct ath_softc, |
@@ -2396,7 +2374,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2396 | } | 2374 | } |
2397 | 2375 | ||
2398 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); | 2376 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); |
2399 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
2400 | 2377 | ||
2401 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 2378 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
2402 | error = ath_tx_edma_init(sc); | 2379 | error = ath_tx_edma_init(sc); |
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 3d4ed5863732..bb578690935e 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h | |||
@@ -448,6 +448,8 @@ struct carl9170_ba_stats { | |||
448 | 448 | ||
449 | struct carl9170_sta_info { | 449 | struct carl9170_sta_info { |
450 | bool ht_sta; | 450 | bool ht_sta; |
451 | bool sleeping; | ||
452 | atomic_t pending_frames; | ||
451 | unsigned int ampdu_max_len; | 453 | unsigned int ampdu_max_len; |
452 | struct carl9170_sta_tid *agg[CARL9170_NUM_TID]; | 454 | struct carl9170_sta_tid *agg[CARL9170_NUM_TID]; |
453 | struct carl9170_ba_stats stats[CARL9170_NUM_TID]; | 455 | struct carl9170_ba_stats stats[CARL9170_NUM_TID]; |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 89fe60accf85..1638468be5a3 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1193,6 +1193,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, | |||
1193 | struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; | 1193 | struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; |
1194 | unsigned int i; | 1194 | unsigned int i; |
1195 | 1195 | ||
1196 | atomic_set(&sta_info->pending_frames, 0); | ||
1197 | |||
1196 | if (sta->ht_cap.ht_supported) { | 1198 | if (sta->ht_cap.ht_supported) { |
1197 | if (sta->ht_cap.ampdu_density > 6) { | 1199 | if (sta->ht_cap.ampdu_density > 6) { |
1198 | /* | 1200 | /* |
@@ -1467,99 +1469,17 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, | |||
1467 | enum sta_notify_cmd cmd, | 1469 | enum sta_notify_cmd cmd, |
1468 | struct ieee80211_sta *sta) | 1470 | struct ieee80211_sta *sta) |
1469 | { | 1471 | { |
1470 | struct ar9170 *ar = hw->priv; | ||
1471 | struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; | 1472 | struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; |
1472 | struct sk_buff *skb, *tmp; | ||
1473 | struct sk_buff_head free; | ||
1474 | int i; | ||
1475 | 1473 | ||
1476 | switch (cmd) { | 1474 | switch (cmd) { |
1477 | case STA_NOTIFY_SLEEP: | 1475 | case STA_NOTIFY_SLEEP: |
1478 | /* | 1476 | sta_info->sleeping = true; |
1479 | * Since the peer is no longer listening, we have to return | 1477 | if (atomic_read(&sta_info->pending_frames)) |
1480 | * as many SKBs as possible back to the mac80211 stack. | 1478 | ieee80211_sta_block_awake(hw, sta, true); |
1481 | * It will deal with the retry procedure, once the peer | ||
1482 | * has become available again. | ||
1483 | * | ||
1484 | * NB: Ideally, the driver should return the all frames in | ||
1485 | * the correct, ascending order. However, I think that this | ||
1486 | * functionality should be implemented in the stack and not | ||
1487 | * here... | ||
1488 | */ | ||
1489 | |||
1490 | __skb_queue_head_init(&free); | ||
1491 | |||
1492 | if (sta->ht_cap.ht_supported) { | ||
1493 | rcu_read_lock(); | ||
1494 | for (i = 0; i < CARL9170_NUM_TID; i++) { | ||
1495 | struct carl9170_sta_tid *tid_info; | ||
1496 | |||
1497 | tid_info = rcu_dereference(sta_info->agg[i]); | ||
1498 | |||
1499 | if (!tid_info) | ||
1500 | continue; | ||
1501 | |||
1502 | spin_lock_bh(&ar->tx_ampdu_list_lock); | ||
1503 | if (tid_info->state > | ||
1504 | CARL9170_TID_STATE_SUSPEND) | ||
1505 | tid_info->state = | ||
1506 | CARL9170_TID_STATE_SUSPEND; | ||
1507 | spin_unlock_bh(&ar->tx_ampdu_list_lock); | ||
1508 | |||
1509 | spin_lock_bh(&tid_info->lock); | ||
1510 | while ((skb = __skb_dequeue(&tid_info->queue))) | ||
1511 | __skb_queue_tail(&free, skb); | ||
1512 | spin_unlock_bh(&tid_info->lock); | ||
1513 | } | ||
1514 | rcu_read_unlock(); | ||
1515 | } | ||
1516 | |||
1517 | for (i = 0; i < ar->hw->queues; i++) { | ||
1518 | spin_lock_bh(&ar->tx_pending[i].lock); | ||
1519 | skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) { | ||
1520 | struct _carl9170_tx_superframe *super; | ||
1521 | struct ieee80211_hdr *hdr; | ||
1522 | struct ieee80211_tx_info *info; | ||
1523 | |||
1524 | super = (void *) skb->data; | ||
1525 | hdr = (void *) super->frame_data; | ||
1526 | |||
1527 | if (compare_ether_addr(hdr->addr1, sta->addr)) | ||
1528 | continue; | ||
1529 | |||
1530 | __skb_unlink(skb, &ar->tx_pending[i]); | ||
1531 | |||
1532 | info = IEEE80211_SKB_CB(skb); | ||
1533 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||
1534 | atomic_dec(&ar->tx_ampdu_upload); | ||
1535 | |||
1536 | carl9170_tx_status(ar, skb, false); | ||
1537 | } | ||
1538 | spin_unlock_bh(&ar->tx_pending[i].lock); | ||
1539 | } | ||
1540 | |||
1541 | while ((skb = __skb_dequeue(&free))) | ||
1542 | carl9170_tx_status(ar, skb, false); | ||
1543 | |||
1544 | break; | 1479 | break; |
1545 | 1480 | ||
1546 | case STA_NOTIFY_AWAKE: | 1481 | case STA_NOTIFY_AWAKE: |
1547 | if (!sta->ht_cap.ht_supported) | 1482 | sta_info->sleeping = false; |
1548 | return; | ||
1549 | |||
1550 | rcu_read_lock(); | ||
1551 | for (i = 0; i < CARL9170_NUM_TID; i++) { | ||
1552 | struct carl9170_sta_tid *tid_info; | ||
1553 | |||
1554 | tid_info = rcu_dereference(sta_info->agg[i]); | ||
1555 | |||
1556 | if (!tid_info) | ||
1557 | continue; | ||
1558 | |||
1559 | if ((tid_info->state == CARL9170_TID_STATE_SUSPEND)) | ||
1560 | tid_info->state = CARL9170_TID_STATE_IDLE; | ||
1561 | } | ||
1562 | rcu_read_unlock(); | ||
1563 | break; | 1483 | break; |
1564 | } | 1484 | } |
1565 | } | 1485 | } |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index cb70ed7ec5cc..bf2eff9dd582 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -104,6 +104,56 @@ static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb) | |||
104 | spin_unlock_bh(&ar->tx_stats_lock); | 104 | spin_unlock_bh(&ar->tx_stats_lock); |
105 | } | 105 | } |
106 | 106 | ||
107 | /* needs rcu_read_lock */ | ||
108 | static struct ieee80211_sta *__carl9170_get_tx_sta(struct ar9170 *ar, | ||
109 | struct sk_buff *skb) | ||
110 | { | ||
111 | struct _carl9170_tx_superframe *super = (void *) skb->data; | ||
112 | struct ieee80211_hdr *hdr = (void *) super->frame_data; | ||
113 | struct ieee80211_vif *vif; | ||
114 | unsigned int vif_id; | ||
115 | |||
116 | vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> | ||
117 | CARL9170_TX_SUPER_MISC_VIF_ID_S; | ||
118 | |||
119 | if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC)) | ||
120 | return NULL; | ||
121 | |||
122 | vif = rcu_dereference(ar->vif_priv[vif_id].vif); | ||
123 | if (unlikely(!vif)) | ||
124 | return NULL; | ||
125 | |||
126 | /* | ||
127 | * Normally we should use wrappers like ieee80211_get_DA to get | ||
128 | * the correct peer ieee80211_sta. | ||
129 | * | ||
130 | * But there is a problem with indirect traffic (broadcasts, or | ||
131 | * data which is designated for other stations) in station mode. | ||
132 | * The frame will be directed to the AP for distribution and not | ||
133 | * to the actual destination. | ||
134 | */ | ||
135 | |||
136 | return ieee80211_find_sta(vif, hdr->addr1); | ||
137 | } | ||
138 | |||
139 | static void carl9170_tx_ps_unblock(struct ar9170 *ar, struct sk_buff *skb) | ||
140 | { | ||
141 | struct ieee80211_sta *sta; | ||
142 | struct carl9170_sta_info *sta_info; | ||
143 | |||
144 | rcu_read_lock(); | ||
145 | sta = __carl9170_get_tx_sta(ar, skb); | ||
146 | if (unlikely(!sta)) | ||
147 | goto out_rcu; | ||
148 | |||
149 | sta_info = (struct carl9170_sta_info *) sta->drv_priv; | ||
150 | if (atomic_dec_return(&sta_info->pending_frames) == 0) | ||
151 | ieee80211_sta_block_awake(ar->hw, sta, false); | ||
152 | |||
153 | out_rcu: | ||
154 | rcu_read_unlock(); | ||
155 | } | ||
156 | |||
107 | static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) | 157 | static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) |
108 | { | 158 | { |
109 | struct ieee80211_tx_info *txinfo; | 159 | struct ieee80211_tx_info *txinfo; |
@@ -135,6 +185,7 @@ static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) | |||
135 | } | 185 | } |
136 | 186 | ||
137 | spin_unlock_bh(&ar->tx_stats_lock); | 187 | spin_unlock_bh(&ar->tx_stats_lock); |
188 | |||
138 | if (atomic_dec_and_test(&ar->tx_total_queued)) | 189 | if (atomic_dec_and_test(&ar->tx_total_queued)) |
139 | complete(&ar->tx_flush); | 190 | complete(&ar->tx_flush); |
140 | } | 191 | } |
@@ -329,13 +380,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, | |||
329 | { | 380 | { |
330 | struct _carl9170_tx_superframe *super = (void *) skb->data; | 381 | struct _carl9170_tx_superframe *super = (void *) skb->data; |
331 | struct ieee80211_hdr *hdr = (void *) super->frame_data; | 382 | struct ieee80211_hdr *hdr = (void *) super->frame_data; |
332 | struct ieee80211_tx_info *tx_info; | ||
333 | struct carl9170_tx_info *ar_info; | 383 | struct carl9170_tx_info *ar_info; |
334 | struct carl9170_sta_info *sta_info; | ||
335 | struct ieee80211_sta *sta; | 384 | struct ieee80211_sta *sta; |
385 | struct carl9170_sta_info *sta_info; | ||
336 | struct carl9170_sta_tid *tid_info; | 386 | struct carl9170_sta_tid *tid_info; |
337 | struct ieee80211_vif *vif; | ||
338 | unsigned int vif_id; | ||
339 | u8 tid; | 387 | u8 tid; |
340 | 388 | ||
341 | if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || | 389 | if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || |
@@ -343,30 +391,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, | |||
343 | (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) | 391 | (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) |
344 | return; | 392 | return; |
345 | 393 | ||
346 | tx_info = IEEE80211_SKB_CB(skb); | 394 | ar_info = (void *) txinfo->rate_driver_data; |
347 | ar_info = (void *) tx_info->rate_driver_data; | ||
348 | |||
349 | vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> | ||
350 | CARL9170_TX_SUPER_MISC_VIF_ID_S; | ||
351 | |||
352 | if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC)) | ||
353 | return; | ||
354 | 395 | ||
355 | rcu_read_lock(); | 396 | rcu_read_lock(); |
356 | vif = rcu_dereference(ar->vif_priv[vif_id].vif); | 397 | sta = __carl9170_get_tx_sta(ar, skb); |
357 | if (unlikely(!vif)) | ||
358 | goto out_rcu; | ||
359 | |||
360 | /* | ||
361 | * Normally we should use wrappers like ieee80211_get_DA to get | ||
362 | * the correct peer ieee80211_sta. | ||
363 | * | ||
364 | * But there is a problem with indirect traffic (broadcasts, or | ||
365 | * data which is designated for other stations) in station mode. | ||
366 | * The frame will be directed to the AP for distribution and not | ||
367 | * to the actual destination. | ||
368 | */ | ||
369 | sta = ieee80211_find_sta(vif, hdr->addr1); | ||
370 | if (unlikely(!sta)) | 398 | if (unlikely(!sta)) |
371 | goto out_rcu; | 399 | goto out_rcu; |
372 | 400 | ||
@@ -427,6 +455,7 @@ void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, | |||
427 | if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) | 455 | if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) |
428 | carl9170_tx_status_process_ampdu(ar, skb, txinfo); | 456 | carl9170_tx_status_process_ampdu(ar, skb, txinfo); |
429 | 457 | ||
458 | carl9170_tx_ps_unblock(ar, skb); | ||
430 | carl9170_tx_put_skb(skb); | 459 | carl9170_tx_put_skb(skb); |
431 | } | 460 | } |
432 | 461 | ||
@@ -540,11 +569,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar) | |||
540 | struct sk_buff *skb; | 569 | struct sk_buff *skb; |
541 | struct ieee80211_tx_info *txinfo; | 570 | struct ieee80211_tx_info *txinfo; |
542 | struct carl9170_tx_info *arinfo; | 571 | struct carl9170_tx_info *arinfo; |
543 | struct _carl9170_tx_superframe *super; | ||
544 | struct ieee80211_sta *sta; | 572 | struct ieee80211_sta *sta; |
545 | struct ieee80211_vif *vif; | ||
546 | struct ieee80211_hdr *hdr; | ||
547 | unsigned int vif_id; | ||
548 | 573 | ||
549 | rcu_read_lock(); | 574 | rcu_read_lock(); |
550 | list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { | 575 | list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { |
@@ -562,20 +587,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar) | |||
562 | msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT))) | 587 | msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT))) |
563 | goto unlock; | 588 | goto unlock; |
564 | 589 | ||
565 | super = (void *) skb->data; | 590 | sta = __carl9170_get_tx_sta(ar, skb); |
566 | hdr = (void *) super->frame_data; | ||
567 | |||
568 | vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> | ||
569 | CARL9170_TX_SUPER_MISC_VIF_ID_S; | ||
570 | |||
571 | if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC)) | ||
572 | goto unlock; | ||
573 | |||
574 | vif = rcu_dereference(ar->vif_priv[vif_id].vif); | ||
575 | if (WARN_ON(!vif)) | ||
576 | goto unlock; | ||
577 | |||
578 | sta = ieee80211_find_sta(vif, hdr->addr1); | ||
579 | if (WARN_ON(!sta)) | 591 | if (WARN_ON(!sta)) |
580 | goto unlock; | 592 | goto unlock; |
581 | 593 | ||
@@ -1199,15 +1211,6 @@ static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar, | |||
1199 | arinfo = (void *) info->rate_driver_data; | 1211 | arinfo = (void *) info->rate_driver_data; |
1200 | 1212 | ||
1201 | arinfo->timeout = jiffies; | 1213 | arinfo->timeout = jiffies; |
1202 | |||
1203 | /* | ||
1204 | * increase ref count to "2". | ||
1205 | * Ref counting is the easiest way to solve the race between | ||
1206 | * the the urb's completion routine: carl9170_tx_callback and | ||
1207 | * wlan tx status functions: carl9170_tx_status/janitor. | ||
1208 | */ | ||
1209 | carl9170_tx_get_skb(skb); | ||
1210 | |||
1211 | return skb; | 1214 | return skb; |
1212 | 1215 | ||
1213 | err_unlock: | 1216 | err_unlock: |
@@ -1228,6 +1231,36 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb) | |||
1228 | __carl9170_tx_process_status(ar, super->s.cookie, q); | 1231 | __carl9170_tx_process_status(ar, super->s.cookie, q); |
1229 | } | 1232 | } |
1230 | 1233 | ||
1234 | static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb) | ||
1235 | { | ||
1236 | struct ieee80211_sta *sta; | ||
1237 | struct carl9170_sta_info *sta_info; | ||
1238 | |||
1239 | rcu_read_lock(); | ||
1240 | sta = __carl9170_get_tx_sta(ar, skb); | ||
1241 | if (!sta) | ||
1242 | goto out_rcu; | ||
1243 | |||
1244 | sta_info = (void *) sta->drv_priv; | ||
1245 | if (unlikely(sta_info->sleeping)) { | ||
1246 | struct ieee80211_tx_info *tx_info; | ||
1247 | |||
1248 | rcu_read_unlock(); | ||
1249 | |||
1250 | tx_info = IEEE80211_SKB_CB(skb); | ||
1251 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) | ||
1252 | atomic_dec(&ar->tx_ampdu_upload); | ||
1253 | |||
1254 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
1255 | carl9170_tx_status(ar, skb, false); | ||
1256 | return true; | ||
1257 | } | ||
1258 | |||
1259 | out_rcu: | ||
1260 | rcu_read_unlock(); | ||
1261 | return false; | ||
1262 | } | ||
1263 | |||
1231 | static void carl9170_tx(struct ar9170 *ar) | 1264 | static void carl9170_tx(struct ar9170 *ar) |
1232 | { | 1265 | { |
1233 | struct sk_buff *skb; | 1266 | struct sk_buff *skb; |
@@ -1247,6 +1280,9 @@ static void carl9170_tx(struct ar9170 *ar) | |||
1247 | if (unlikely(!skb)) | 1280 | if (unlikely(!skb)) |
1248 | break; | 1281 | break; |
1249 | 1282 | ||
1283 | if (unlikely(carl9170_tx_ps_drop(ar, skb))) | ||
1284 | continue; | ||
1285 | |||
1250 | atomic_inc(&ar->tx_total_pending); | 1286 | atomic_inc(&ar->tx_total_pending); |
1251 | 1287 | ||
1252 | q = __carl9170_get_queue(ar, i); | 1288 | q = __carl9170_get_queue(ar, i); |
@@ -1256,6 +1292,16 @@ static void carl9170_tx(struct ar9170 *ar) | |||
1256 | */ | 1292 | */ |
1257 | skb_queue_tail(&ar->tx_status[q], skb); | 1293 | skb_queue_tail(&ar->tx_status[q], skb); |
1258 | 1294 | ||
1295 | /* | ||
1296 | * increase ref count to "2". | ||
1297 | * Ref counting is the easiest way to solve the | ||
1298 | * race between the urb's completion routine: | ||
1299 | * carl9170_tx_callback | ||
1300 | * and wlan tx status functions: | ||
1301 | * carl9170_tx_status/janitor. | ||
1302 | */ | ||
1303 | carl9170_tx_get_skb(skb); | ||
1304 | |||
1259 | carl9170_usb_tx(ar, skb); | 1305 | carl9170_usb_tx(ar, skb); |
1260 | schedule_garbagecollector = true; | 1306 | schedule_garbagecollector = true; |
1261 | } | 1307 | } |
@@ -1368,6 +1414,11 @@ void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1368 | * all ressouces which are associated with the frame. | 1414 | * all ressouces which are associated with the frame. |
1369 | */ | 1415 | */ |
1370 | 1416 | ||
1417 | if (sta) { | ||
1418 | struct carl9170_sta_info *stai = (void *) sta->drv_priv; | ||
1419 | atomic_inc(&stai->pending_frames); | ||
1420 | } | ||
1421 | |||
1371 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | 1422 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
1372 | run = carl9170_tx_ampdu_queue(ar, sta, skb); | 1423 | run = carl9170_tx_ampdu_queue(ar, sta, skb); |
1373 | if (run) | 1424 | if (run) |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 8a00f9a95dbb..6755063f955a 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -2281,6 +2281,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | |||
2281 | save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | 2281 | save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); |
2282 | save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); | 2282 | save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); |
2283 | save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); | 2283 | save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); |
2284 | save_regs_phy[8] = 0; | ||
2284 | } else { | 2285 | } else { |
2285 | save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | 2286 | save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); |
2286 | save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | 2287 | save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); |
@@ -2289,6 +2290,8 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | |||
2289 | save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER); | 2290 | save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER); |
2290 | save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); | 2291 | save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); |
2291 | save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2); | 2292 | save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2); |
2293 | save_regs_phy[7] = 0; | ||
2294 | save_regs_phy[8] = 0; | ||
2292 | } | 2295 | } |
2293 | 2296 | ||
2294 | b43_nphy_rssi_select(dev, 5, type); | 2297 | b43_nphy_rssi_select(dev, 5, type); |
@@ -3845,8 +3848,8 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, | |||
3845 | { | 3848 | { |
3846 | struct b43_phy *phy = &dev->phy; | 3849 | struct b43_phy *phy = &dev->phy; |
3847 | 3850 | ||
3848 | const struct b43_nphy_channeltab_entry_rev2 *tabent_r2; | 3851 | const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL; |
3849 | const struct b43_nphy_channeltab_entry_rev3 *tabent_r3; | 3852 | const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL; |
3850 | 3853 | ||
3851 | u8 tmp; | 3854 | u8 tmp; |
3852 | 3855 | ||
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c index 5a8a3cce27bc..7e5e85a017b5 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c | |||
@@ -955,9 +955,6 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
955 | if (priv->cfg->scan_rx_antennas[band]) | 955 | if (priv->cfg->scan_rx_antennas[band]) |
956 | rx_ant = priv->cfg->scan_rx_antennas[band]; | 956 | rx_ant = priv->cfg->scan_rx_antennas[band]; |
957 | 957 | ||
958 | if (priv->cfg->scan_tx_antennas[band]) | ||
959 | scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; | ||
960 | |||
961 | priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv, | 958 | priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv, |
962 | priv->scan_tx_ant[band], | 959 | priv->scan_tx_ant[band], |
963 | scan_tx_antennas); | 960 | scan_tx_antennas); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index c1511b14b239..d743373a9424 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c | |||
@@ -211,10 +211,7 @@ int iwl_legacy_init_geos(struct iwl_priv *priv) | |||
211 | if (!iwl_legacy_is_channel_valid(ch)) | 211 | if (!iwl_legacy_is_channel_valid(ch)) |
212 | continue; | 212 | continue; |
213 | 213 | ||
214 | if (iwl_legacy_is_channel_a_band(ch)) | 214 | sband = &priv->bands[ch->band]; |
215 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
216 | else | ||
217 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
218 | 215 | ||
219 | geo_ch = &sband->channels[sband->n_channels++]; | 216 | geo_ch = &sband->channels[sband->n_channels++]; |
220 | 217 | ||
@@ -2117,10 +2114,9 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2117 | IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", | 2114 | IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", |
2118 | channel->hw_value, changed); | 2115 | channel->hw_value, changed); |
2119 | 2116 | ||
2120 | if (unlikely(!priv->cfg->mod_params->disable_hw_scan && | 2117 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { |
2121 | test_bit(STATUS_SCANNING, &priv->status))) { | ||
2122 | scan_active = 1; | 2118 | scan_active = 1; |
2123 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | 2119 | IWL_DEBUG_MAC80211(priv, "scan active\n"); |
2124 | } | 2120 | } |
2125 | 2121 | ||
2126 | if (changed & (IEEE80211_CONF_CHANGE_SMPS | | 2122 | if (changed & (IEEE80211_CONF_CHANGE_SMPS | |
@@ -2433,11 +2429,13 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, | |||
2433 | 2429 | ||
2434 | IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); | 2430 | IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); |
2435 | 2431 | ||
2436 | if (!iwl_legacy_is_alive(priv)) | ||
2437 | return; | ||
2438 | |||
2439 | mutex_lock(&priv->mutex); | 2432 | mutex_lock(&priv->mutex); |
2440 | 2433 | ||
2434 | if (!iwl_legacy_is_alive(priv)) { | ||
2435 | mutex_unlock(&priv->mutex); | ||
2436 | return; | ||
2437 | } | ||
2438 | |||
2441 | if (changes & BSS_CHANGED_QOS) { | 2439 | if (changes & BSS_CHANGED_QOS) { |
2442 | unsigned long flags; | 2440 | unsigned long flags; |
2443 | 2441 | ||
@@ -2646,7 +2644,7 @@ unplugged: | |||
2646 | 2644 | ||
2647 | none: | 2645 | none: |
2648 | /* re-enable interrupts here since we don't have anything to service. */ | 2646 | /* re-enable interrupts here since we don't have anything to service. */ |
2649 | /* only Re-enable if diabled by irq */ | 2647 | /* only Re-enable if disabled by irq */ |
2650 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 2648 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
2651 | iwl_legacy_enable_interrupts(priv); | 2649 | iwl_legacy_enable_interrupts(priv); |
2652 | spin_unlock_irqrestore(&priv->lock, flags); | 2650 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index f03b463e4378..bc66c604106c 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h | |||
@@ -287,7 +287,6 @@ struct iwl_cfg { | |||
287 | struct iwl_base_params *base_params; | 287 | struct iwl_base_params *base_params; |
288 | /* params likely to change within a device family */ | 288 | /* params likely to change within a device family */ |
289 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | 289 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; |
290 | u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; | ||
291 | enum iwl_led_mode led_mode; | 290 | enum iwl_led_mode led_mode; |
292 | }; | 291 | }; |
293 | 292 | ||
diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h index 9ee849d669f3..2d87dba2cfa3 100644 --- a/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h | |||
@@ -134,7 +134,7 @@ struct iwl_queue { | |||
134 | * space more than this */ | 134 | * space more than this */ |
135 | int high_mark; /* high watermark, stop queue if free | 135 | int high_mark; /* high watermark, stop queue if free |
136 | * space less than this */ | 136 | * space less than this */ |
137 | } __packed; | 137 | }; |
138 | 138 | ||
139 | /* One for each TFD */ | 139 | /* One for each TFD */ |
140 | struct iwl_tx_info { | 140 | struct iwl_tx_info { |
@@ -290,6 +290,7 @@ enum { | |||
290 | CMD_SIZE_HUGE = (1 << 0), | 290 | CMD_SIZE_HUGE = (1 << 0), |
291 | CMD_ASYNC = (1 << 1), | 291 | CMD_ASYNC = (1 << 1), |
292 | CMD_WANT_SKB = (1 << 2), | 292 | CMD_WANT_SKB = (1 << 2), |
293 | CMD_MAPPED = (1 << 3), | ||
293 | }; | 294 | }; |
294 | 295 | ||
295 | #define DEF_CMD_PAYLOAD_SIZE 320 | 296 | #define DEF_CMD_PAYLOAD_SIZE 320 |
@@ -1076,7 +1077,6 @@ struct iwl_priv { | |||
1076 | spinlock_t hcmd_lock; /* protect hcmd */ | 1077 | spinlock_t hcmd_lock; /* protect hcmd */ |
1077 | spinlock_t reg_lock; /* protect hw register access */ | 1078 | spinlock_t reg_lock; /* protect hw register access */ |
1078 | struct mutex mutex; | 1079 | struct mutex mutex; |
1079 | struct mutex sync_cmd_mutex; /* enable serialization of sync commands */ | ||
1080 | 1080 | ||
1081 | /* basic pci-network driver stuff */ | 1081 | /* basic pci-network driver stuff */ |
1082 | struct pci_dev *pci_dev; | 1082 | struct pci_dev *pci_dev; |
diff --git a/drivers/net/wireless/iwlegacy/iwl-hcmd.c b/drivers/net/wireless/iwlegacy/iwl-hcmd.c index 9d721cbda5bb..62b4b09122cb 100644 --- a/drivers/net/wireless/iwlegacy/iwl-hcmd.c +++ b/drivers/net/wireless/iwlegacy/iwl-hcmd.c | |||
@@ -145,6 +145,8 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
145 | int cmd_idx; | 145 | int cmd_idx; |
146 | int ret; | 146 | int ret; |
147 | 147 | ||
148 | lockdep_assert_held(&priv->mutex); | ||
149 | |||
148 | BUG_ON(cmd->flags & CMD_ASYNC); | 150 | BUG_ON(cmd->flags & CMD_ASYNC); |
149 | 151 | ||
150 | /* A synchronous command can not have a callback set. */ | 152 | /* A synchronous command can not have a callback set. */ |
@@ -152,7 +154,6 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
152 | 154 | ||
153 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", | 155 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", |
154 | iwl_legacy_get_cmd_string(cmd->id)); | 156 | iwl_legacy_get_cmd_string(cmd->id)); |
155 | mutex_lock(&priv->sync_cmd_mutex); | ||
156 | 157 | ||
157 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); | 158 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); |
158 | IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", | 159 | IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", |
@@ -224,7 +225,6 @@ fail: | |||
224 | cmd->reply_page = 0; | 225 | cmd->reply_page = 0; |
225 | } | 226 | } |
226 | out: | 227 | out: |
227 | mutex_unlock(&priv->sync_cmd_mutex); | ||
228 | return ret; | 228 | return ret; |
229 | } | 229 | } |
230 | EXPORT_SYMBOL(iwl_legacy_send_cmd_sync); | 230 | EXPORT_SYMBOL(iwl_legacy_send_cmd_sync); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-helpers.h b/drivers/net/wireless/iwlegacy/iwl-helpers.h index 02132e755831..a6effdae63f9 100644 --- a/drivers/net/wireless/iwlegacy/iwl-helpers.h +++ b/drivers/net/wireless/iwlegacy/iwl-helpers.h | |||
@@ -149,6 +149,12 @@ static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv) | |||
149 | IWL_DEBUG_ISR(priv, "Disabled interrupts\n"); | 149 | IWL_DEBUG_ISR(priv, "Disabled interrupts\n"); |
150 | } | 150 | } |
151 | 151 | ||
152 | static inline void iwl_legacy_enable_rfkill_int(struct iwl_priv *priv) | ||
153 | { | ||
154 | IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); | ||
155 | iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
156 | } | ||
157 | |||
152 | static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv) | 158 | static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv) |
153 | { | 159 | { |
154 | IWL_DEBUG_ISR(priv, "Enabling interrupts\n"); | 160 | IWL_DEBUG_ISR(priv, "Enabling interrupts\n"); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-tx.c b/drivers/net/wireless/iwlegacy/iwl-tx.c index a227773cb384..4fff995c6f3e 100644 --- a/drivers/net/wireless/iwlegacy/iwl-tx.c +++ b/drivers/net/wireless/iwlegacy/iwl-tx.c | |||
@@ -146,33 +146,32 @@ void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv) | |||
146 | { | 146 | { |
147 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | 147 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; |
148 | struct iwl_queue *q = &txq->q; | 148 | struct iwl_queue *q = &txq->q; |
149 | bool huge = false; | ||
150 | int i; | 149 | int i; |
151 | 150 | ||
152 | if (q->n_bd == 0) | 151 | if (q->n_bd == 0) |
153 | return; | 152 | return; |
154 | 153 | ||
155 | while (q->read_ptr != q->write_ptr) { | 154 | while (q->read_ptr != q->write_ptr) { |
156 | /* we have no way to tell if it is a huge cmd ATM */ | ||
157 | i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0); | 155 | i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0); |
158 | 156 | ||
159 | if (txq->meta[i].flags & CMD_SIZE_HUGE) | 157 | if (txq->meta[i].flags & CMD_MAPPED) { |
160 | huge = true; | ||
161 | else | ||
162 | pci_unmap_single(priv->pci_dev, | 158 | pci_unmap_single(priv->pci_dev, |
163 | dma_unmap_addr(&txq->meta[i], mapping), | 159 | dma_unmap_addr(&txq->meta[i], mapping), |
164 | dma_unmap_len(&txq->meta[i], len), | 160 | dma_unmap_len(&txq->meta[i], len), |
165 | PCI_DMA_BIDIRECTIONAL); | 161 | PCI_DMA_BIDIRECTIONAL); |
162 | txq->meta[i].flags = 0; | ||
163 | } | ||
166 | 164 | ||
167 | q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd); | 165 | q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd); |
168 | } | 166 | } |
169 | 167 | ||
170 | if (huge) { | 168 | i = q->n_window; |
171 | i = q->n_window; | 169 | if (txq->meta[i].flags & CMD_MAPPED) { |
172 | pci_unmap_single(priv->pci_dev, | 170 | pci_unmap_single(priv->pci_dev, |
173 | dma_unmap_addr(&txq->meta[i], mapping), | 171 | dma_unmap_addr(&txq->meta[i], mapping), |
174 | dma_unmap_len(&txq->meta[i], len), | 172 | dma_unmap_len(&txq->meta[i], len), |
175 | PCI_DMA_BIDIRECTIONAL); | 173 | PCI_DMA_BIDIRECTIONAL); |
174 | txq->meta[i].flags = 0; | ||
176 | } | 175 | } |
177 | } | 176 | } |
178 | EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap); | 177 | EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap); |
@@ -467,29 +466,27 @@ int iwl_legacy_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
467 | return -EIO; | 466 | return -EIO; |
468 | } | 467 | } |
469 | 468 | ||
469 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
470 | |||
470 | if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | 471 | if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { |
471 | IWL_ERR(priv, "No space in command queue\n"); | 472 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); |
472 | IWL_ERR(priv, "Restarting adapter due to queue full\n"); | 473 | |
474 | IWL_ERR(priv, "Restarting adapter due to command queue full\n"); | ||
473 | queue_work(priv->workqueue, &priv->restart); | 475 | queue_work(priv->workqueue, &priv->restart); |
474 | return -ENOSPC; | 476 | return -ENOSPC; |
475 | } | 477 | } |
476 | 478 | ||
477 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
478 | |||
479 | /* If this is a huge cmd, mark the huge flag also on the meta.flags | ||
480 | * of the _original_ cmd. This is used for DMA mapping clean up. | ||
481 | */ | ||
482 | if (cmd->flags & CMD_SIZE_HUGE) { | ||
483 | idx = iwl_legacy_get_cmd_index(q, q->write_ptr, 0); | ||
484 | txq->meta[idx].flags = CMD_SIZE_HUGE; | ||
485 | } | ||
486 | |||
487 | idx = iwl_legacy_get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); | 479 | idx = iwl_legacy_get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); |
488 | out_cmd = txq->cmd[idx]; | 480 | out_cmd = txq->cmd[idx]; |
489 | out_meta = &txq->meta[idx]; | 481 | out_meta = &txq->meta[idx]; |
490 | 482 | ||
483 | if (WARN_ON(out_meta->flags & CMD_MAPPED)) { | ||
484 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||
485 | return -ENOSPC; | ||
486 | } | ||
487 | |||
491 | memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ | 488 | memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ |
492 | out_meta->flags = cmd->flags; | 489 | out_meta->flags = cmd->flags | CMD_MAPPED; |
493 | if (cmd->flags & CMD_WANT_SKB) | 490 | if (cmd->flags & CMD_WANT_SKB) |
494 | out_meta->source = cmd; | 491 | out_meta->source = cmd; |
495 | if (cmd->flags & CMD_ASYNC) | 492 | if (cmd->flags & CMD_ASYNC) |
@@ -610,6 +607,7 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
610 | struct iwl_device_cmd *cmd; | 607 | struct iwl_device_cmd *cmd; |
611 | struct iwl_cmd_meta *meta; | 608 | struct iwl_cmd_meta *meta; |
612 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | 609 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; |
610 | unsigned long flags; | ||
613 | 611 | ||
614 | /* If a Tx command is being handled and it isn't in the actual | 612 | /* If a Tx command is being handled and it isn't in the actual |
615 | * command queue then there a command routing bug has been introduced | 613 | * command queue then there a command routing bug has been introduced |
@@ -623,14 +621,6 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
623 | return; | 621 | return; |
624 | } | 622 | } |
625 | 623 | ||
626 | /* If this is a huge cmd, clear the huge flag on the meta.flags | ||
627 | * of the _original_ cmd. So that iwl_legacy_cmd_queue_free won't unmap | ||
628 | * the DMA buffer for the scan (huge) command. | ||
629 | */ | ||
630 | if (huge) { | ||
631 | cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, 0); | ||
632 | txq->meta[cmd_index].flags = 0; | ||
633 | } | ||
634 | cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, huge); | 624 | cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, huge); |
635 | cmd = txq->cmd[cmd_index]; | 625 | cmd = txq->cmd[cmd_index]; |
636 | meta = &txq->meta[cmd_index]; | 626 | meta = &txq->meta[cmd_index]; |
@@ -647,6 +637,8 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
647 | } else if (meta->callback) | 637 | } else if (meta->callback) |
648 | meta->callback(priv, cmd, pkt); | 638 | meta->callback(priv, cmd, pkt); |
649 | 639 | ||
640 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
641 | |||
650 | iwl_legacy_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); | 642 | iwl_legacy_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); |
651 | 643 | ||
652 | if (!(meta->flags & CMD_ASYNC)) { | 644 | if (!(meta->flags & CMD_ASYNC)) { |
@@ -655,6 +647,10 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
655 | iwl_legacy_get_cmd_string(cmd->hdr.cmd)); | 647 | iwl_legacy_get_cmd_string(cmd->hdr.cmd)); |
656 | wake_up_interruptible(&priv->wait_command_queue); | 648 | wake_up_interruptible(&priv->wait_command_queue); |
657 | } | 649 | } |
650 | |||
651 | /* Mark as unmapped */ | ||
658 | meta->flags = 0; | 652 | meta->flags = 0; |
653 | |||
654 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||
659 | } | 655 | } |
660 | EXPORT_SYMBOL(iwl_legacy_tx_cmd_complete); | 656 | EXPORT_SYMBOL(iwl_legacy_tx_cmd_complete); |
diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c index cc7ebcee60e5..0ee6be6a9c5d 100644 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c | |||
@@ -2748,11 +2748,12 @@ static void iwl3945_bg_init_alive_start(struct work_struct *data) | |||
2748 | struct iwl_priv *priv = | 2748 | struct iwl_priv *priv = |
2749 | container_of(data, struct iwl_priv, init_alive_start.work); | 2749 | container_of(data, struct iwl_priv, init_alive_start.work); |
2750 | 2750 | ||
2751 | mutex_lock(&priv->mutex); | ||
2751 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2752 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2752 | return; | 2753 | goto out; |
2753 | 2754 | ||
2754 | mutex_lock(&priv->mutex); | ||
2755 | iwl3945_init_alive_start(priv); | 2755 | iwl3945_init_alive_start(priv); |
2756 | out: | ||
2756 | mutex_unlock(&priv->mutex); | 2757 | mutex_unlock(&priv->mutex); |
2757 | } | 2758 | } |
2758 | 2759 | ||
@@ -2761,11 +2762,12 @@ static void iwl3945_bg_alive_start(struct work_struct *data) | |||
2761 | struct iwl_priv *priv = | 2762 | struct iwl_priv *priv = |
2762 | container_of(data, struct iwl_priv, alive_start.work); | 2763 | container_of(data, struct iwl_priv, alive_start.work); |
2763 | 2764 | ||
2765 | mutex_lock(&priv->mutex); | ||
2764 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2766 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2765 | return; | 2767 | goto out; |
2766 | 2768 | ||
2767 | mutex_lock(&priv->mutex); | ||
2768 | iwl3945_alive_start(priv); | 2769 | iwl3945_alive_start(priv); |
2770 | out: | ||
2769 | mutex_unlock(&priv->mutex); | 2771 | mutex_unlock(&priv->mutex); |
2770 | } | 2772 | } |
2771 | 2773 | ||
@@ -2995,10 +2997,12 @@ static void iwl3945_bg_restart(struct work_struct *data) | |||
2995 | } else { | 2997 | } else { |
2996 | iwl3945_down(priv); | 2998 | iwl3945_down(priv); |
2997 | 2999 | ||
2998 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 3000 | mutex_lock(&priv->mutex); |
3001 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
3002 | mutex_unlock(&priv->mutex); | ||
2999 | return; | 3003 | return; |
3004 | } | ||
3000 | 3005 | ||
3001 | mutex_lock(&priv->mutex); | ||
3002 | __iwl3945_up(priv); | 3006 | __iwl3945_up(priv); |
3003 | mutex_unlock(&priv->mutex); | 3007 | mutex_unlock(&priv->mutex); |
3004 | } | 3008 | } |
@@ -3009,11 +3013,12 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) | |||
3009 | struct iwl_priv *priv = | 3013 | struct iwl_priv *priv = |
3010 | container_of(data, struct iwl_priv, rx_replenish); | 3014 | container_of(data, struct iwl_priv, rx_replenish); |
3011 | 3015 | ||
3016 | mutex_lock(&priv->mutex); | ||
3012 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 3017 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
3013 | return; | 3018 | goto out; |
3014 | 3019 | ||
3015 | mutex_lock(&priv->mutex); | ||
3016 | iwl3945_rx_replenish(priv); | 3020 | iwl3945_rx_replenish(priv); |
3021 | out: | ||
3017 | mutex_unlock(&priv->mutex); | 3022 | mutex_unlock(&priv->mutex); |
3018 | } | 3023 | } |
3019 | 3024 | ||
@@ -3810,7 +3815,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
3810 | INIT_LIST_HEAD(&priv->free_frames); | 3815 | INIT_LIST_HEAD(&priv->free_frames); |
3811 | 3816 | ||
3812 | mutex_init(&priv->mutex); | 3817 | mutex_init(&priv->mutex); |
3813 | mutex_init(&priv->sync_cmd_mutex); | ||
3814 | 3818 | ||
3815 | priv->ieee_channels = NULL; | 3819 | priv->ieee_channels = NULL; |
3816 | priv->ieee_rates = NULL; | 3820 | priv->ieee_rates = NULL; |
diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index f8870543d68f..f781b7e225b4 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c | |||
@@ -1069,9 +1069,12 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | /* Re-enable all interrupts */ | 1071 | /* Re-enable all interrupts */ |
1072 | /* only Re-enable if diabled by irq */ | 1072 | /* only Re-enable if disabled by irq */ |
1073 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1073 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
1074 | iwl_legacy_enable_interrupts(priv); | 1074 | iwl_legacy_enable_interrupts(priv); |
1075 | /* Re-enable RF_KILL if it occurred */ | ||
1076 | else if (handled & CSR_INT_BIT_RF_KILL) | ||
1077 | iwl_legacy_enable_rfkill_int(priv); | ||
1075 | 1078 | ||
1076 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG | 1079 | #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG |
1077 | if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) { | 1080 | if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) { |
@@ -2139,7 +2142,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv); | |||
2139 | static void __iwl4965_down(struct iwl_priv *priv) | 2142 | static void __iwl4965_down(struct iwl_priv *priv) |
2140 | { | 2143 | { |
2141 | unsigned long flags; | 2144 | unsigned long flags; |
2142 | int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); | 2145 | int exit_pending; |
2143 | 2146 | ||
2144 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); | 2147 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); |
2145 | 2148 | ||
@@ -2401,11 +2404,12 @@ static void iwl4965_bg_init_alive_start(struct work_struct *data) | |||
2401 | struct iwl_priv *priv = | 2404 | struct iwl_priv *priv = |
2402 | container_of(data, struct iwl_priv, init_alive_start.work); | 2405 | container_of(data, struct iwl_priv, init_alive_start.work); |
2403 | 2406 | ||
2407 | mutex_lock(&priv->mutex); | ||
2404 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2408 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2405 | return; | 2409 | goto out; |
2406 | 2410 | ||
2407 | mutex_lock(&priv->mutex); | ||
2408 | priv->cfg->ops->lib->init_alive_start(priv); | 2411 | priv->cfg->ops->lib->init_alive_start(priv); |
2412 | out: | ||
2409 | mutex_unlock(&priv->mutex); | 2413 | mutex_unlock(&priv->mutex); |
2410 | } | 2414 | } |
2411 | 2415 | ||
@@ -2414,11 +2418,12 @@ static void iwl4965_bg_alive_start(struct work_struct *data) | |||
2414 | struct iwl_priv *priv = | 2418 | struct iwl_priv *priv = |
2415 | container_of(data, struct iwl_priv, alive_start.work); | 2419 | container_of(data, struct iwl_priv, alive_start.work); |
2416 | 2420 | ||
2421 | mutex_lock(&priv->mutex); | ||
2417 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2422 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2418 | return; | 2423 | goto out; |
2419 | 2424 | ||
2420 | mutex_lock(&priv->mutex); | ||
2421 | iwl4965_alive_start(priv); | 2425 | iwl4965_alive_start(priv); |
2426 | out: | ||
2422 | mutex_unlock(&priv->mutex); | 2427 | mutex_unlock(&priv->mutex); |
2423 | } | 2428 | } |
2424 | 2429 | ||
@@ -2468,10 +2473,12 @@ static void iwl4965_bg_restart(struct work_struct *data) | |||
2468 | } else { | 2473 | } else { |
2469 | iwl4965_down(priv); | 2474 | iwl4965_down(priv); |
2470 | 2475 | ||
2471 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2476 | mutex_lock(&priv->mutex); |
2477 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
2478 | mutex_unlock(&priv->mutex); | ||
2472 | return; | 2479 | return; |
2480 | } | ||
2473 | 2481 | ||
2474 | mutex_lock(&priv->mutex); | ||
2475 | __iwl4965_up(priv); | 2482 | __iwl4965_up(priv); |
2476 | mutex_unlock(&priv->mutex); | 2483 | mutex_unlock(&priv->mutex); |
2477 | } | 2484 | } |
@@ -2624,9 +2631,10 @@ void iwl4965_mac_stop(struct ieee80211_hw *hw) | |||
2624 | 2631 | ||
2625 | flush_workqueue(priv->workqueue); | 2632 | flush_workqueue(priv->workqueue); |
2626 | 2633 | ||
2627 | /* enable interrupts again in order to receive rfkill changes */ | 2634 | /* User space software may expect getting rfkill changes |
2635 | * even if interface is down */ | ||
2628 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | 2636 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
2629 | iwl_legacy_enable_interrupts(priv); | 2637 | iwl_legacy_enable_rfkill_int(priv); |
2630 | 2638 | ||
2631 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2639 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2632 | } | 2640 | } |
@@ -2847,21 +2855,22 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
2847 | 2855 | ||
2848 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 2856 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
2849 | 2857 | ||
2858 | mutex_lock(&priv->mutex); | ||
2859 | |||
2850 | if (iwl_legacy_is_rfkill(priv)) | 2860 | if (iwl_legacy_is_rfkill(priv)) |
2851 | goto out_exit; | 2861 | goto out; |
2852 | 2862 | ||
2853 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || | 2863 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
2854 | test_bit(STATUS_SCANNING, &priv->status)) | 2864 | test_bit(STATUS_SCANNING, &priv->status)) |
2855 | goto out_exit; | 2865 | goto out; |
2856 | 2866 | ||
2857 | if (!iwl_legacy_is_associated_ctx(ctx)) | 2867 | if (!iwl_legacy_is_associated_ctx(ctx)) |
2858 | goto out_exit; | 2868 | goto out; |
2859 | 2869 | ||
2860 | /* channel switch in progress */ | 2870 | /* channel switch in progress */ |
2861 | if (priv->switch_rxon.switch_in_progress == true) | 2871 | if (priv->switch_rxon.switch_in_progress == true) |
2862 | goto out_exit; | 2872 | goto out; |
2863 | 2873 | ||
2864 | mutex_lock(&priv->mutex); | ||
2865 | if (priv->cfg->ops->lib->set_channel_switch) { | 2874 | if (priv->cfg->ops->lib->set_channel_switch) { |
2866 | 2875 | ||
2867 | ch = channel->hw_value; | 2876 | ch = channel->hw_value; |
@@ -2917,7 +2926,6 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
2917 | } | 2926 | } |
2918 | out: | 2927 | out: |
2919 | mutex_unlock(&priv->mutex); | 2928 | mutex_unlock(&priv->mutex); |
2920 | out_exit: | ||
2921 | if (!priv->switch_rxon.switch_in_progress) | 2929 | if (!priv->switch_rxon.switch_in_progress) |
2922 | ieee80211_chswitch_done(ctx->vif, false); | 2930 | ieee80211_chswitch_done(ctx->vif, false); |
2923 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2931 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
@@ -3116,7 +3124,6 @@ static int iwl4965_init_drv(struct iwl_priv *priv) | |||
3116 | INIT_LIST_HEAD(&priv->free_frames); | 3124 | INIT_LIST_HEAD(&priv->free_frames); |
3117 | 3125 | ||
3118 | mutex_init(&priv->mutex); | 3126 | mutex_init(&priv->mutex); |
3119 | mutex_init(&priv->sync_cmd_mutex); | ||
3120 | 3127 | ||
3121 | priv->ieee_channels = NULL; | 3128 | priv->ieee_channels = NULL; |
3122 | priv->ieee_rates = NULL; | 3129 | priv->ieee_rates = NULL; |
@@ -3406,14 +3413,14 @@ iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3406 | * 8. Enable interrupts and read RFKILL state | 3413 | * 8. Enable interrupts and read RFKILL state |
3407 | *********************************************/ | 3414 | *********************************************/ |
3408 | 3415 | ||
3409 | /* enable interrupts if needed: hw bug w/a */ | 3416 | /* enable rfkill interrupt: hw bug w/a */ |
3410 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); | 3417 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); |
3411 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | 3418 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { |
3412 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | 3419 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; |
3413 | pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); | 3420 | pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); |
3414 | } | 3421 | } |
3415 | 3422 | ||
3416 | iwl_legacy_enable_interrupts(priv); | 3423 | iwl_legacy_enable_rfkill_int(priv); |
3417 | 3424 | ||
3418 | /* If platform's RF_KILL switch is NOT set to KILL */ | 3425 | /* If platform's RF_KILL switch is NOT set to KILL */ |
3419 | if (iwl_read32(priv, CSR_GP_CNTRL) & | 3426 | if (iwl_read32(priv, CSR_GP_CNTRL) & |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index bb6a737de61f..89a41d320c36 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -14,7 +14,6 @@ iwlagn-objs += iwl-6000.o | |||
14 | iwlagn-objs += iwl-1000.o | 14 | iwlagn-objs += iwl-1000.o |
15 | iwlagn-objs += iwl-2000.o | 15 | iwlagn-objs += iwl-2000.o |
16 | 16 | ||
17 | iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o | ||
18 | iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 17 | iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
19 | iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | 18 | iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o |
20 | 19 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index baf80111efaf..3da8cf27dcb9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include "iwl-agn.h" | 45 | #include "iwl-agn.h" |
46 | #include "iwl-helpers.h" | 46 | #include "iwl-helpers.h" |
47 | #include "iwl-agn-hw.h" | 47 | #include "iwl-agn-hw.h" |
48 | #include "iwl-agn-debugfs.h" | ||
49 | 48 | ||
50 | /* Highest firmware API version supported */ | 49 | /* Highest firmware API version supported */ |
51 | #define IWL1000_UCODE_API_MAX 5 | 50 | #define IWL1000_UCODE_API_MAX 5 |
@@ -121,10 +120,10 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = { | |||
121 | 120 | ||
122 | static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) | 121 | static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) |
123 | { | 122 | { |
124 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | 123 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
125 | priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | 124 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
126 | priv->cfg->base_params->num_of_queues = | 125 | priv->cfg->base_params->num_of_queues = |
127 | priv->cfg->mod_params->num_of_queues; | 126 | iwlagn_mod_params.num_of_queues; |
128 | 127 | ||
129 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | 128 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; |
130 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | 129 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
@@ -197,21 +196,11 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
197 | EEPROM_REG_BAND_24_HT40_CHANNELS, | 196 | EEPROM_REG_BAND_24_HT40_CHANNELS, |
198 | EEPROM_REGULATORY_BAND_NO_HT40, | 197 | EEPROM_REGULATORY_BAND_NO_HT40, |
199 | }, | 198 | }, |
200 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||
201 | .release_semaphore = iwlcore_eeprom_release_semaphore, | ||
202 | .calib_version = iwlagn_eeprom_calib_version, | ||
203 | .query_addr = iwlagn_eeprom_query_addr, | 199 | .query_addr = iwlagn_eeprom_query_addr, |
204 | }, | 200 | }, |
205 | .temp_ops = { | 201 | .temp_ops = { |
206 | .temperature = iwlagn_temperature, | 202 | .temperature = iwlagn_temperature, |
207 | }, | 203 | }, |
208 | .debugfs_ops = { | ||
209 | .rx_stats_read = iwl_ucode_rx_stats_read, | ||
210 | .tx_stats_read = iwl_ucode_tx_stats_read, | ||
211 | .general_stats_read = iwl_ucode_general_stats_read, | ||
212 | .bt_stats_read = iwl_ucode_bt_stats_read, | ||
213 | .reply_tx_error = iwl_reply_tx_error_read, | ||
214 | }, | ||
215 | .txfifo_flush = iwlagn_txfifo_flush, | 204 | .txfifo_flush = iwlagn_txfifo_flush, |
216 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 205 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
217 | }; | 206 | }; |
@@ -249,7 +238,6 @@ static struct iwl_ht_params iwl1000_ht_params = { | |||
249 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ | 238 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ |
250 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ | 239 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
251 | .ops = &iwl1000_ops, \ | 240 | .ops = &iwl1000_ops, \ |
252 | .mod_params = &iwlagn_mod_params, \ | ||
253 | .base_params = &iwl1000_base_params, \ | 241 | .base_params = &iwl1000_base_params, \ |
254 | .led_mode = IWL_LED_BLINK | 242 | .led_mode = IWL_LED_BLINK |
255 | 243 | ||
@@ -271,7 +259,6 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
271 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ | 259 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ |
272 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ | 260 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
273 | .ops = &iwl1000_ops, \ | 261 | .ops = &iwl1000_ops, \ |
274 | .mod_params = &iwlagn_mod_params, \ | ||
275 | .base_params = &iwl1000_base_params, \ | 262 | .base_params = &iwl1000_base_params, \ |
276 | .led_mode = IWL_LED_RF_STATE, \ | 263 | .led_mode = IWL_LED_RF_STATE, \ |
277 | .rx_with_siso_diversity = true | 264 | .rx_with_siso_diversity = true |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index e76e02c28928..bca462c47e37 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -46,17 +46,16 @@ | |||
46 | #include "iwl-helpers.h" | 46 | #include "iwl-helpers.h" |
47 | #include "iwl-agn-hw.h" | 47 | #include "iwl-agn-hw.h" |
48 | #include "iwl-6000-hw.h" | 48 | #include "iwl-6000-hw.h" |
49 | #include "iwl-agn-debugfs.h" | ||
50 | 49 | ||
51 | /* Highest firmware API version supported */ | 50 | /* Highest firmware API version supported */ |
52 | #define IWL2030_UCODE_API_MAX 5 | 51 | #define IWL2030_UCODE_API_MAX 5 |
53 | #define IWL2000_UCODE_API_MAX 5 | 52 | #define IWL2000_UCODE_API_MAX 5 |
54 | #define IWL200_UCODE_API_MAX 5 | 53 | #define IWL105_UCODE_API_MAX 5 |
55 | 54 | ||
56 | /* Lowest firmware API version supported */ | 55 | /* Lowest firmware API version supported */ |
57 | #define IWL2030_UCODE_API_MIN 5 | 56 | #define IWL2030_UCODE_API_MIN 5 |
58 | #define IWL2000_UCODE_API_MIN 5 | 57 | #define IWL2000_UCODE_API_MIN 5 |
59 | #define IWL200_UCODE_API_MIN 5 | 58 | #define IWL105_UCODE_API_MIN 5 |
60 | 59 | ||
61 | #define IWL2030_FW_PRE "iwlwifi-2030-" | 60 | #define IWL2030_FW_PRE "iwlwifi-2030-" |
62 | #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" | 61 | #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" |
@@ -64,8 +63,8 @@ | |||
64 | #define IWL2000_FW_PRE "iwlwifi-2000-" | 63 | #define IWL2000_FW_PRE "iwlwifi-2000-" |
65 | #define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" | 64 | #define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" |
66 | 65 | ||
67 | #define IWL200_FW_PRE "iwlwifi-200-" | 66 | #define IWL105_FW_PRE "iwlwifi-105-" |
68 | #define IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode" | 67 | #define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode" |
69 | 68 | ||
70 | static void iwl2000_set_ct_threshold(struct iwl_priv *priv) | 69 | static void iwl2000_set_ct_threshold(struct iwl_priv *priv) |
71 | { | 70 | { |
@@ -128,10 +127,10 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = { | |||
128 | 127 | ||
129 | static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) | 128 | static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) |
130 | { | 129 | { |
131 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | 130 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
132 | priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | 131 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
133 | priv->cfg->base_params->num_of_queues = | 132 | priv->cfg->base_params->num_of_queues = |
134 | priv->cfg->mod_params->num_of_queues; | 133 | iwlagn_mod_params.num_of_queues; |
135 | 134 | ||
136 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | 135 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; |
137 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | 136 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
@@ -280,22 +279,12 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
280 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 279 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
281 | EEPROM_REGULATORY_BAND_NO_HT40, | 280 | EEPROM_REGULATORY_BAND_NO_HT40, |
282 | }, | 281 | }, |
283 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||
284 | .release_semaphore = iwlcore_eeprom_release_semaphore, | ||
285 | .calib_version = iwlagn_eeprom_calib_version, | ||
286 | .query_addr = iwlagn_eeprom_query_addr, | 282 | .query_addr = iwlagn_eeprom_query_addr, |
287 | .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, | 283 | .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, |
288 | }, | 284 | }, |
289 | .temp_ops = { | 285 | .temp_ops = { |
290 | .temperature = iwlagn_temperature, | 286 | .temperature = iwlagn_temperature, |
291 | }, | 287 | }, |
292 | .debugfs_ops = { | ||
293 | .rx_stats_read = iwl_ucode_rx_stats_read, | ||
294 | .tx_stats_read = iwl_ucode_tx_stats_read, | ||
295 | .general_stats_read = iwl_ucode_general_stats_read, | ||
296 | .bt_stats_read = iwl_ucode_bt_stats_read, | ||
297 | .reply_tx_error = iwl_reply_tx_error_read, | ||
298 | }, | ||
299 | .txfifo_flush = iwlagn_txfifo_flush, | 288 | .txfifo_flush = iwlagn_txfifo_flush, |
300 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 289 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
301 | }; | 290 | }; |
@@ -312,13 +301,13 @@ static const struct iwl_ops iwl2030_ops = { | |||
312 | .utils = &iwlagn_hcmd_utils, | 301 | .utils = &iwlagn_hcmd_utils, |
313 | }; | 302 | }; |
314 | 303 | ||
315 | static const struct iwl_ops iwl200_ops = { | 304 | static const struct iwl_ops iwl105_ops = { |
316 | .lib = &iwl2000_lib, | 305 | .lib = &iwl2000_lib, |
317 | .hcmd = &iwlagn_hcmd, | 306 | .hcmd = &iwlagn_hcmd, |
318 | .utils = &iwlagn_hcmd_utils, | 307 | .utils = &iwlagn_hcmd_utils, |
319 | }; | 308 | }; |
320 | 309 | ||
321 | static const struct iwl_ops iwl230_ops = { | 310 | static const struct iwl_ops iwl135_ops = { |
322 | .lib = &iwl2000_lib, | 311 | .lib = &iwl2000_lib, |
323 | .hcmd = &iwlagn_bt_hcmd, | 312 | .hcmd = &iwlagn_bt_hcmd, |
324 | .utils = &iwlagn_hcmd_utils, | 313 | .utils = &iwlagn_hcmd_utils, |
@@ -383,7 +372,6 @@ static struct iwl_bt_params iwl2030_bt_params = { | |||
383 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 372 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
384 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 373 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
385 | .ops = &iwl2000_ops, \ | 374 | .ops = &iwl2000_ops, \ |
386 | .mod_params = &iwlagn_mod_params, \ | ||
387 | .base_params = &iwl2000_base_params, \ | 375 | .base_params = &iwl2000_base_params, \ |
388 | .need_dc_calib = true, \ | 376 | .need_dc_calib = true, \ |
389 | .need_temp_offset_calib = true, \ | 377 | .need_temp_offset_calib = true, \ |
@@ -409,7 +397,6 @@ struct iwl_cfg iwl2000_2bg_cfg = { | |||
409 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 397 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
410 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 398 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
411 | .ops = &iwl2030_ops, \ | 399 | .ops = &iwl2030_ops, \ |
412 | .mod_params = &iwlagn_mod_params, \ | ||
413 | .base_params = &iwl2030_base_params, \ | 400 | .base_params = &iwl2030_base_params, \ |
414 | .bt_params = &iwl2030_bt_params, \ | 401 | .bt_params = &iwl2030_bt_params, \ |
415 | .need_dc_calib = true, \ | 402 | .need_dc_calib = true, \ |
@@ -429,14 +416,13 @@ struct iwl_cfg iwl2030_2bg_cfg = { | |||
429 | IWL_DEVICE_2030, | 416 | IWL_DEVICE_2030, |
430 | }; | 417 | }; |
431 | 418 | ||
432 | #define IWL_DEVICE_200 \ | 419 | #define IWL_DEVICE_105 \ |
433 | .fw_name_pre = IWL200_FW_PRE, \ | 420 | .fw_name_pre = IWL105_FW_PRE, \ |
434 | .ucode_api_max = IWL200_UCODE_API_MAX, \ | 421 | .ucode_api_max = IWL105_UCODE_API_MAX, \ |
435 | .ucode_api_min = IWL200_UCODE_API_MIN, \ | 422 | .ucode_api_min = IWL105_UCODE_API_MIN, \ |
436 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 423 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
437 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 424 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
438 | .ops = &iwl200_ops, \ | 425 | .ops = &iwl105_ops, \ |
439 | .mod_params = &iwlagn_mod_params, \ | ||
440 | .base_params = &iwl2000_base_params, \ | 426 | .base_params = &iwl2000_base_params, \ |
441 | .need_dc_calib = true, \ | 427 | .need_dc_calib = true, \ |
442 | .need_temp_offset_calib = true, \ | 428 | .need_temp_offset_calib = true, \ |
@@ -444,25 +430,24 @@ struct iwl_cfg iwl2030_2bg_cfg = { | |||
444 | .adv_pm = true, \ | 430 | .adv_pm = true, \ |
445 | .rx_with_siso_diversity = true \ | 431 | .rx_with_siso_diversity = true \ |
446 | 432 | ||
447 | struct iwl_cfg iwl200_bg_cfg = { | 433 | struct iwl_cfg iwl105_bg_cfg = { |
448 | .name = "200 Series 1x1 BG", | 434 | .name = "105 Series 1x1 BG", |
449 | IWL_DEVICE_200, | 435 | IWL_DEVICE_105, |
450 | }; | 436 | }; |
451 | 437 | ||
452 | struct iwl_cfg iwl200_bgn_cfg = { | 438 | struct iwl_cfg iwl105_bgn_cfg = { |
453 | .name = "200 Series 1x1 BGN", | 439 | .name = "105 Series 1x1 BGN", |
454 | IWL_DEVICE_200, | 440 | IWL_DEVICE_105, |
455 | .ht_params = &iwl2000_ht_params, | 441 | .ht_params = &iwl2000_ht_params, |
456 | }; | 442 | }; |
457 | 443 | ||
458 | #define IWL_DEVICE_230 \ | 444 | #define IWL_DEVICE_135 \ |
459 | .fw_name_pre = IWL200_FW_PRE, \ | 445 | .fw_name_pre = IWL105_FW_PRE, \ |
460 | .ucode_api_max = IWL200_UCODE_API_MAX, \ | 446 | .ucode_api_max = IWL105_UCODE_API_MAX, \ |
461 | .ucode_api_min = IWL200_UCODE_API_MIN, \ | 447 | .ucode_api_min = IWL105_UCODE_API_MIN, \ |
462 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 448 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
463 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 449 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
464 | .ops = &iwl230_ops, \ | 450 | .ops = &iwl135_ops, \ |
465 | .mod_params = &iwlagn_mod_params, \ | ||
466 | .base_params = &iwl2030_base_params, \ | 451 | .base_params = &iwl2030_base_params, \ |
467 | .bt_params = &iwl2030_bt_params, \ | 452 | .bt_params = &iwl2030_bt_params, \ |
468 | .need_dc_calib = true, \ | 453 | .need_dc_calib = true, \ |
@@ -471,17 +456,17 @@ struct iwl_cfg iwl200_bgn_cfg = { | |||
471 | .adv_pm = true, \ | 456 | .adv_pm = true, \ |
472 | .rx_with_siso_diversity = true \ | 457 | .rx_with_siso_diversity = true \ |
473 | 458 | ||
474 | struct iwl_cfg iwl230_bg_cfg = { | 459 | struct iwl_cfg iwl135_bg_cfg = { |
475 | .name = "200 Series 1x1 BG/BT", | 460 | .name = "105 Series 1x1 BG/BT", |
476 | IWL_DEVICE_230, | 461 | IWL_DEVICE_135, |
477 | }; | 462 | }; |
478 | 463 | ||
479 | struct iwl_cfg iwl230_bgn_cfg = { | 464 | struct iwl_cfg iwl135_bgn_cfg = { |
480 | .name = "200 Series 1x1 BGN/BT", | 465 | .name = "105 Series 1x1 BGN/BT", |
481 | IWL_DEVICE_230, | 466 | IWL_DEVICE_135, |
482 | .ht_params = &iwl2000_ht_params, | 467 | .ht_params = &iwl2000_ht_params, |
483 | }; | 468 | }; |
484 | 469 | ||
485 | MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); | 470 | MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); |
486 | MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); | 471 | MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); |
487 | MODULE_FIRMWARE(IWL200_MODULE_FIRMWARE(IWL200_UCODE_API_MAX)); | 472 | MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 655afc19f68f..561f2cd65dd4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include "iwl-agn.h" | 47 | #include "iwl-agn.h" |
48 | #include "iwl-agn-hw.h" | 48 | #include "iwl-agn-hw.h" |
49 | #include "iwl-5000-hw.h" | 49 | #include "iwl-5000-hw.h" |
50 | #include "iwl-agn-debugfs.h" | ||
51 | 50 | ||
52 | /* Highest firmware API version supported */ | 51 | /* Highest firmware API version supported */ |
53 | #define IWL5000_UCODE_API_MAX 5 | 52 | #define IWL5000_UCODE_API_MAX 5 |
@@ -165,10 +164,10 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
165 | 164 | ||
166 | static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | 165 | static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) |
167 | { | 166 | { |
168 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | 167 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
169 | priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | 168 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
170 | priv->cfg->base_params->num_of_queues = | 169 | priv->cfg->base_params->num_of_queues = |
171 | priv->cfg->mod_params->num_of_queues; | 170 | iwlagn_mod_params.num_of_queues; |
172 | 171 | ||
173 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | 172 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; |
174 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | 173 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
@@ -210,10 +209,10 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
210 | 209 | ||
211 | static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) | 210 | static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) |
212 | { | 211 | { |
213 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | 212 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
214 | priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | 213 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
215 | priv->cfg->base_params->num_of_queues = | 214 | priv->cfg->base_params->num_of_queues = |
216 | priv->cfg->mod_params->num_of_queues; | 215 | iwlagn_mod_params.num_of_queues; |
217 | 216 | ||
218 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | 217 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; |
219 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | 218 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
@@ -366,21 +365,11 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
366 | EEPROM_REG_BAND_24_HT40_CHANNELS, | 365 | EEPROM_REG_BAND_24_HT40_CHANNELS, |
367 | EEPROM_REG_BAND_52_HT40_CHANNELS | 366 | EEPROM_REG_BAND_52_HT40_CHANNELS |
368 | }, | 367 | }, |
369 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||
370 | .release_semaphore = iwlcore_eeprom_release_semaphore, | ||
371 | .calib_version = iwlagn_eeprom_calib_version, | ||
372 | .query_addr = iwlagn_eeprom_query_addr, | 368 | .query_addr = iwlagn_eeprom_query_addr, |
373 | }, | 369 | }, |
374 | .temp_ops = { | 370 | .temp_ops = { |
375 | .temperature = iwlagn_temperature, | 371 | .temperature = iwlagn_temperature, |
376 | }, | 372 | }, |
377 | .debugfs_ops = { | ||
378 | .rx_stats_read = iwl_ucode_rx_stats_read, | ||
379 | .tx_stats_read = iwl_ucode_tx_stats_read, | ||
380 | .general_stats_read = iwl_ucode_general_stats_read, | ||
381 | .bt_stats_read = iwl_ucode_bt_stats_read, | ||
382 | .reply_tx_error = iwl_reply_tx_error_read, | ||
383 | }, | ||
384 | .txfifo_flush = iwlagn_txfifo_flush, | 373 | .txfifo_flush = iwlagn_txfifo_flush, |
385 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 374 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
386 | }; | 375 | }; |
@@ -413,21 +402,11 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
413 | EEPROM_REG_BAND_24_HT40_CHANNELS, | 402 | EEPROM_REG_BAND_24_HT40_CHANNELS, |
414 | EEPROM_REG_BAND_52_HT40_CHANNELS | 403 | EEPROM_REG_BAND_52_HT40_CHANNELS |
415 | }, | 404 | }, |
416 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||
417 | .release_semaphore = iwlcore_eeprom_release_semaphore, | ||
418 | .calib_version = iwlagn_eeprom_calib_version, | ||
419 | .query_addr = iwlagn_eeprom_query_addr, | 405 | .query_addr = iwlagn_eeprom_query_addr, |
420 | }, | 406 | }, |
421 | .temp_ops = { | 407 | .temp_ops = { |
422 | .temperature = iwl5150_temperature, | 408 | .temperature = iwl5150_temperature, |
423 | }, | 409 | }, |
424 | .debugfs_ops = { | ||
425 | .rx_stats_read = iwl_ucode_rx_stats_read, | ||
426 | .tx_stats_read = iwl_ucode_tx_stats_read, | ||
427 | .general_stats_read = iwl_ucode_general_stats_read, | ||
428 | .bt_stats_read = iwl_ucode_bt_stats_read, | ||
429 | .reply_tx_error = iwl_reply_tx_error_read, | ||
430 | }, | ||
431 | .txfifo_flush = iwlagn_txfifo_flush, | 410 | .txfifo_flush = iwlagn_txfifo_flush, |
432 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 411 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
433 | }; | 412 | }; |
@@ -468,7 +447,6 @@ static struct iwl_ht_params iwl5000_ht_params = { | |||
468 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ | 447 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ |
469 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ | 448 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ |
470 | .ops = &iwl5000_ops, \ | 449 | .ops = &iwl5000_ops, \ |
471 | .mod_params = &iwlagn_mod_params, \ | ||
472 | .base_params = &iwl5000_base_params, \ | 450 | .base_params = &iwl5000_base_params, \ |
473 | .led_mode = IWL_LED_BLINK | 451 | .led_mode = IWL_LED_BLINK |
474 | 452 | ||
@@ -512,7 +490,6 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
512 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, | 490 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, |
513 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, | 491 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, |
514 | .ops = &iwl5000_ops, | 492 | .ops = &iwl5000_ops, |
515 | .mod_params = &iwlagn_mod_params, | ||
516 | .base_params = &iwl5000_base_params, | 493 | .base_params = &iwl5000_base_params, |
517 | .ht_params = &iwl5000_ht_params, | 494 | .ht_params = &iwl5000_ht_params, |
518 | .led_mode = IWL_LED_BLINK, | 495 | .led_mode = IWL_LED_BLINK, |
@@ -526,7 +503,6 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
526 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ | 503 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ |
527 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ | 504 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ |
528 | .ops = &iwl5150_ops, \ | 505 | .ops = &iwl5150_ops, \ |
529 | .mod_params = &iwlagn_mod_params, \ | ||
530 | .base_params = &iwl5000_base_params, \ | 506 | .base_params = &iwl5000_base_params, \ |
531 | .need_dc_calib = true, \ | 507 | .need_dc_calib = true, \ |
532 | .led_mode = IWL_LED_BLINK, \ | 508 | .led_mode = IWL_LED_BLINK, \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 905eb57f7cab..6045457cc722 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include "iwl-helpers.h" | 46 | #include "iwl-helpers.h" |
47 | #include "iwl-agn-hw.h" | 47 | #include "iwl-agn-hw.h" |
48 | #include "iwl-6000-hw.h" | 48 | #include "iwl-6000-hw.h" |
49 | #include "iwl-agn-debugfs.h" | ||
50 | 49 | ||
51 | /* Highest firmware API version supported */ | 50 | /* Highest firmware API version supported */ |
52 | #define IWL6000_UCODE_API_MAX 4 | 51 | #define IWL6000_UCODE_API_MAX 4 |
@@ -80,7 +79,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | |||
80 | static void iwl6050_additional_nic_config(struct iwl_priv *priv) | 79 | static void iwl6050_additional_nic_config(struct iwl_priv *priv) |
81 | { | 80 | { |
82 | /* Indicate calibration version to uCode. */ | 81 | /* Indicate calibration version to uCode. */ |
83 | if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) | 82 | if (iwlagn_eeprom_calib_version(priv) >= 6) |
84 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, | 83 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, |
85 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | 84 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); |
86 | } | 85 | } |
@@ -88,7 +87,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv) | |||
88 | static void iwl6150_additional_nic_config(struct iwl_priv *priv) | 87 | static void iwl6150_additional_nic_config(struct iwl_priv *priv) |
89 | { | 88 | { |
90 | /* Indicate calibration version to uCode. */ | 89 | /* Indicate calibration version to uCode. */ |
91 | if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) | 90 | if (iwlagn_eeprom_calib_version(priv) >= 6) |
92 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, | 91 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, |
93 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | 92 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); |
94 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, | 93 | iwl_set_bit(priv, CSR_GP_DRIVER_REG, |
@@ -154,10 +153,10 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | |||
154 | 153 | ||
155 | static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) | 154 | static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) |
156 | { | 155 | { |
157 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | 156 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
158 | priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | 157 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
159 | priv->cfg->base_params->num_of_queues = | 158 | priv->cfg->base_params->num_of_queues = |
160 | priv->cfg->mod_params->num_of_queues; | 159 | iwlagn_mod_params.num_of_queues; |
161 | 160 | ||
162 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | 161 | priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; |
163 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | 162 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
@@ -305,22 +304,12 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
305 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 304 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
306 | EEPROM_REG_BAND_52_HT40_CHANNELS | 305 | EEPROM_REG_BAND_52_HT40_CHANNELS |
307 | }, | 306 | }, |
308 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||
309 | .release_semaphore = iwlcore_eeprom_release_semaphore, | ||
310 | .calib_version = iwlagn_eeprom_calib_version, | ||
311 | .query_addr = iwlagn_eeprom_query_addr, | 307 | .query_addr = iwlagn_eeprom_query_addr, |
312 | .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, | 308 | .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, |
313 | }, | 309 | }, |
314 | .temp_ops = { | 310 | .temp_ops = { |
315 | .temperature = iwlagn_temperature, | 311 | .temperature = iwlagn_temperature, |
316 | }, | 312 | }, |
317 | .debugfs_ops = { | ||
318 | .rx_stats_read = iwl_ucode_rx_stats_read, | ||
319 | .tx_stats_read = iwl_ucode_tx_stats_read, | ||
320 | .general_stats_read = iwl_ucode_general_stats_read, | ||
321 | .bt_stats_read = iwl_ucode_bt_stats_read, | ||
322 | .reply_tx_error = iwl_reply_tx_error_read, | ||
323 | }, | ||
324 | .txfifo_flush = iwlagn_txfifo_flush, | 313 | .txfifo_flush = iwlagn_txfifo_flush, |
325 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 314 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
326 | }; | 315 | }; |
@@ -354,22 +343,12 @@ static struct iwl_lib_ops iwl6030_lib = { | |||
354 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 343 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
355 | EEPROM_REG_BAND_52_HT40_CHANNELS | 344 | EEPROM_REG_BAND_52_HT40_CHANNELS |
356 | }, | 345 | }, |
357 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||
358 | .release_semaphore = iwlcore_eeprom_release_semaphore, | ||
359 | .calib_version = iwlagn_eeprom_calib_version, | ||
360 | .query_addr = iwlagn_eeprom_query_addr, | 346 | .query_addr = iwlagn_eeprom_query_addr, |
361 | .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, | 347 | .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, |
362 | }, | 348 | }, |
363 | .temp_ops = { | 349 | .temp_ops = { |
364 | .temperature = iwlagn_temperature, | 350 | .temperature = iwlagn_temperature, |
365 | }, | 351 | }, |
366 | .debugfs_ops = { | ||
367 | .rx_stats_read = iwl_ucode_rx_stats_read, | ||
368 | .tx_stats_read = iwl_ucode_tx_stats_read, | ||
369 | .general_stats_read = iwl_ucode_general_stats_read, | ||
370 | .bt_stats_read = iwl_ucode_bt_stats_read, | ||
371 | .reply_tx_error = iwl_reply_tx_error_read, | ||
372 | }, | ||
373 | .txfifo_flush = iwlagn_txfifo_flush, | 352 | .txfifo_flush = iwlagn_txfifo_flush, |
374 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, | 353 | .dev_txfifo_flush = iwlagn_dev_txfifo_flush, |
375 | }; | 354 | }; |
@@ -482,7 +461,6 @@ static struct iwl_bt_params iwl6000_bt_params = { | |||
482 | .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ | 461 | .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ |
483 | .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ | 462 | .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ |
484 | .ops = &iwl6000_ops, \ | 463 | .ops = &iwl6000_ops, \ |
485 | .mod_params = &iwlagn_mod_params, \ | ||
486 | .base_params = &iwl6000_g2_base_params, \ | 464 | .base_params = &iwl6000_g2_base_params, \ |
487 | .need_dc_calib = true, \ | 465 | .need_dc_calib = true, \ |
488 | .need_temp_offset_calib = true, \ | 466 | .need_temp_offset_calib = true, \ |
@@ -511,7 +489,6 @@ struct iwl_cfg iwl6005_2bg_cfg = { | |||
511 | .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ | 489 | .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ |
512 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ | 490 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ |
513 | .ops = &iwl6030_ops, \ | 491 | .ops = &iwl6030_ops, \ |
514 | .mod_params = &iwlagn_mod_params, \ | ||
515 | .base_params = &iwl6000_g2_base_params, \ | 492 | .base_params = &iwl6000_g2_base_params, \ |
516 | .bt_params = &iwl6000_bt_params, \ | 493 | .bt_params = &iwl6000_bt_params, \ |
517 | .need_dc_calib = true, \ | 494 | .need_dc_calib = true, \ |
@@ -593,7 +570,6 @@ struct iwl_cfg iwl130_bg_cfg = { | |||
593 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ | 570 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ |
594 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ | 571 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ |
595 | .ops = &iwl6000_ops, \ | 572 | .ops = &iwl6000_ops, \ |
596 | .mod_params = &iwlagn_mod_params, \ | ||
597 | .base_params = &iwl6000_base_params, \ | 573 | .base_params = &iwl6000_base_params, \ |
598 | .pa_type = IWL_PA_INTERNAL, \ | 574 | .pa_type = IWL_PA_INTERNAL, \ |
599 | .led_mode = IWL_LED_BLINK | 575 | .led_mode = IWL_LED_BLINK |
@@ -623,7 +599,6 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
623 | .ops = &iwl6050_ops, \ | 599 | .ops = &iwl6050_ops, \ |
624 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ | 600 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ |
625 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ | 601 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ |
626 | .mod_params = &iwlagn_mod_params, \ | ||
627 | .base_params = &iwl6050_base_params, \ | 602 | .base_params = &iwl6050_base_params, \ |
628 | .need_dc_calib = true, \ | 603 | .need_dc_calib = true, \ |
629 | .led_mode = IWL_LED_BLINK, \ | 604 | .led_mode = IWL_LED_BLINK, \ |
@@ -648,7 +623,6 @@ struct iwl_cfg iwl6150_bgn_cfg = { | |||
648 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, | 623 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, |
649 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, | 624 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, |
650 | .ops = &iwl6150_ops, | 625 | .ops = &iwl6150_ops, |
651 | .mod_params = &iwlagn_mod_params, | ||
652 | .base_params = &iwl6050_base_params, | 626 | .base_params = &iwl6050_base_params, |
653 | .ht_params = &iwl6000_ht_params, | 627 | .ht_params = &iwl6000_ht_params, |
654 | .need_dc_calib = true, | 628 | .need_dc_calib = true, |
@@ -664,7 +638,6 @@ struct iwl_cfg iwl6000_3agn_cfg = { | |||
664 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 638 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
665 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, | 639 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, |
666 | .ops = &iwl6000_ops, | 640 | .ops = &iwl6000_ops, |
667 | .mod_params = &iwlagn_mod_params, | ||
668 | .base_params = &iwl6000_base_params, | 641 | .base_params = &iwl6000_base_params, |
669 | .ht_params = &iwl6000_ht_params, | 642 | .ht_params = &iwl6000_ht_params, |
670 | .need_dc_calib = true, | 643 | .need_dc_calib = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c deleted file mode 100644 index 71a5f31cd7cc..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ /dev/null | |||
@@ -1,1025 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * GPL LICENSE SUMMARY | ||
4 | * | ||
5 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
19 | * USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution | ||
22 | * in the file called LICENSE.GPL. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | *****************************************************************************/ | ||
28 | #include "iwl-agn.h" | ||
29 | #include "iwl-agn-debugfs.h" | ||
30 | |||
31 | static const char *fmt_value = " %-30s %10u\n"; | ||
32 | static const char *fmt_hex = " %-30s 0x%02X\n"; | ||
33 | static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; | ||
34 | static const char *fmt_header = | ||
35 | "%-32s current cumulative delta max\n"; | ||
36 | |||
37 | static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) | ||
38 | { | ||
39 | int p = 0; | ||
40 | u32 flag; | ||
41 | |||
42 | flag = le32_to_cpu(priv->statistics.flag); | ||
43 | |||
44 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); | ||
45 | if (flag & UCODE_STATISTICS_CLEAR_MSK) | ||
46 | p += scnprintf(buf + p, bufsz - p, | ||
47 | "\tStatistics have been cleared\n"); | ||
48 | p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", | ||
49 | (flag & UCODE_STATISTICS_FREQUENCY_MSK) | ||
50 | ? "2.4 GHz" : "5.2 GHz"); | ||
51 | p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", | ||
52 | (flag & UCODE_STATISTICS_NARROW_BAND_MSK) | ||
53 | ? "enabled" : "disabled"); | ||
54 | |||
55 | return p; | ||
56 | } | ||
57 | |||
58 | ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | ||
59 | size_t count, loff_t *ppos) | ||
60 | { | ||
61 | struct iwl_priv *priv = file->private_data; | ||
62 | int pos = 0; | ||
63 | char *buf; | ||
64 | int bufsz = sizeof(struct statistics_rx_phy) * 40 + | ||
65 | sizeof(struct statistics_rx_non_phy) * 40 + | ||
66 | sizeof(struct statistics_rx_ht_phy) * 40 + 400; | ||
67 | ssize_t ret; | ||
68 | struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; | ||
69 | struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; | ||
70 | struct statistics_rx_non_phy *general, *accum_general; | ||
71 | struct statistics_rx_non_phy *delta_general, *max_general; | ||
72 | struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; | ||
73 | |||
74 | if (!iwl_is_alive(priv)) | ||
75 | return -EAGAIN; | ||
76 | |||
77 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
78 | if (!buf) { | ||
79 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
80 | return -ENOMEM; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * the statistic information display here is based on | ||
85 | * the last statistics notification from uCode | ||
86 | * might not reflect the current uCode activity | ||
87 | */ | ||
88 | ofdm = &priv->statistics.rx_ofdm; | ||
89 | cck = &priv->statistics.rx_cck; | ||
90 | general = &priv->statistics.rx_non_phy; | ||
91 | ht = &priv->statistics.rx_ofdm_ht; | ||
92 | accum_ofdm = &priv->accum_stats.rx_ofdm; | ||
93 | accum_cck = &priv->accum_stats.rx_cck; | ||
94 | accum_general = &priv->accum_stats.rx_non_phy; | ||
95 | accum_ht = &priv->accum_stats.rx_ofdm_ht; | ||
96 | delta_ofdm = &priv->delta_stats.rx_ofdm; | ||
97 | delta_cck = &priv->delta_stats.rx_cck; | ||
98 | delta_general = &priv->delta_stats.rx_non_phy; | ||
99 | delta_ht = &priv->delta_stats.rx_ofdm_ht; | ||
100 | max_ofdm = &priv->max_delta_stats.rx_ofdm; | ||
101 | max_cck = &priv->max_delta_stats.rx_cck; | ||
102 | max_general = &priv->max_delta_stats.rx_non_phy; | ||
103 | max_ht = &priv->max_delta_stats.rx_ofdm_ht; | ||
104 | |||
105 | pos += iwl_statistics_flag(priv, buf, bufsz); | ||
106 | pos += scnprintf(buf + pos, bufsz - pos, | ||
107 | fmt_header, "Statistics_Rx - OFDM:"); | ||
108 | pos += scnprintf(buf + pos, bufsz - pos, | ||
109 | fmt_table, "ina_cnt:", | ||
110 | le32_to_cpu(ofdm->ina_cnt), | ||
111 | accum_ofdm->ina_cnt, | ||
112 | delta_ofdm->ina_cnt, max_ofdm->ina_cnt); | ||
113 | pos += scnprintf(buf + pos, bufsz - pos, | ||
114 | fmt_table, "fina_cnt:", | ||
115 | le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, | ||
116 | delta_ofdm->fina_cnt, max_ofdm->fina_cnt); | ||
117 | pos += scnprintf(buf + pos, bufsz - pos, | ||
118 | fmt_table, "plcp_err:", | ||
119 | le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, | ||
120 | delta_ofdm->plcp_err, max_ofdm->plcp_err); | ||
121 | pos += scnprintf(buf + pos, bufsz - pos, | ||
122 | fmt_table, "crc32_err:", | ||
123 | le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, | ||
124 | delta_ofdm->crc32_err, max_ofdm->crc32_err); | ||
125 | pos += scnprintf(buf + pos, bufsz - pos, | ||
126 | fmt_table, "overrun_err:", | ||
127 | le32_to_cpu(ofdm->overrun_err), | ||
128 | accum_ofdm->overrun_err, delta_ofdm->overrun_err, | ||
129 | max_ofdm->overrun_err); | ||
130 | pos += scnprintf(buf + pos, bufsz - pos, | ||
131 | fmt_table, "early_overrun_err:", | ||
132 | le32_to_cpu(ofdm->early_overrun_err), | ||
133 | accum_ofdm->early_overrun_err, | ||
134 | delta_ofdm->early_overrun_err, | ||
135 | max_ofdm->early_overrun_err); | ||
136 | pos += scnprintf(buf + pos, bufsz - pos, | ||
137 | fmt_table, "crc32_good:", | ||
138 | le32_to_cpu(ofdm->crc32_good), | ||
139 | accum_ofdm->crc32_good, delta_ofdm->crc32_good, | ||
140 | max_ofdm->crc32_good); | ||
141 | pos += scnprintf(buf + pos, bufsz - pos, | ||
142 | fmt_table, "false_alarm_cnt:", | ||
143 | le32_to_cpu(ofdm->false_alarm_cnt), | ||
144 | accum_ofdm->false_alarm_cnt, | ||
145 | delta_ofdm->false_alarm_cnt, | ||
146 | max_ofdm->false_alarm_cnt); | ||
147 | pos += scnprintf(buf + pos, bufsz - pos, | ||
148 | fmt_table, "fina_sync_err_cnt:", | ||
149 | le32_to_cpu(ofdm->fina_sync_err_cnt), | ||
150 | accum_ofdm->fina_sync_err_cnt, | ||
151 | delta_ofdm->fina_sync_err_cnt, | ||
152 | max_ofdm->fina_sync_err_cnt); | ||
153 | pos += scnprintf(buf + pos, bufsz - pos, | ||
154 | fmt_table, "sfd_timeout:", | ||
155 | le32_to_cpu(ofdm->sfd_timeout), | ||
156 | accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout, | ||
157 | max_ofdm->sfd_timeout); | ||
158 | pos += scnprintf(buf + pos, bufsz - pos, | ||
159 | fmt_table, "fina_timeout:", | ||
160 | le32_to_cpu(ofdm->fina_timeout), | ||
161 | accum_ofdm->fina_timeout, delta_ofdm->fina_timeout, | ||
162 | max_ofdm->fina_timeout); | ||
163 | pos += scnprintf(buf + pos, bufsz - pos, | ||
164 | fmt_table, "unresponded_rts:", | ||
165 | le32_to_cpu(ofdm->unresponded_rts), | ||
166 | accum_ofdm->unresponded_rts, | ||
167 | delta_ofdm->unresponded_rts, | ||
168 | max_ofdm->unresponded_rts); | ||
169 | pos += scnprintf(buf + pos, bufsz - pos, | ||
170 | fmt_table, "rxe_frame_lmt_ovrun:", | ||
171 | le32_to_cpu(ofdm->rxe_frame_limit_overrun), | ||
172 | accum_ofdm->rxe_frame_limit_overrun, | ||
173 | delta_ofdm->rxe_frame_limit_overrun, | ||
174 | max_ofdm->rxe_frame_limit_overrun); | ||
175 | pos += scnprintf(buf + pos, bufsz - pos, | ||
176 | fmt_table, "sent_ack_cnt:", | ||
177 | le32_to_cpu(ofdm->sent_ack_cnt), | ||
178 | accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt, | ||
179 | max_ofdm->sent_ack_cnt); | ||
180 | pos += scnprintf(buf + pos, bufsz - pos, | ||
181 | fmt_table, "sent_cts_cnt:", | ||
182 | le32_to_cpu(ofdm->sent_cts_cnt), | ||
183 | accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt, | ||
184 | max_ofdm->sent_cts_cnt); | ||
185 | pos += scnprintf(buf + pos, bufsz - pos, | ||
186 | fmt_table, "sent_ba_rsp_cnt:", | ||
187 | le32_to_cpu(ofdm->sent_ba_rsp_cnt), | ||
188 | accum_ofdm->sent_ba_rsp_cnt, | ||
189 | delta_ofdm->sent_ba_rsp_cnt, | ||
190 | max_ofdm->sent_ba_rsp_cnt); | ||
191 | pos += scnprintf(buf + pos, bufsz - pos, | ||
192 | fmt_table, "dsp_self_kill:", | ||
193 | le32_to_cpu(ofdm->dsp_self_kill), | ||
194 | accum_ofdm->dsp_self_kill, | ||
195 | delta_ofdm->dsp_self_kill, | ||
196 | max_ofdm->dsp_self_kill); | ||
197 | pos += scnprintf(buf + pos, bufsz - pos, | ||
198 | fmt_table, "mh_format_err:", | ||
199 | le32_to_cpu(ofdm->mh_format_err), | ||
200 | accum_ofdm->mh_format_err, | ||
201 | delta_ofdm->mh_format_err, | ||
202 | max_ofdm->mh_format_err); | ||
203 | pos += scnprintf(buf + pos, bufsz - pos, | ||
204 | fmt_table, "re_acq_main_rssi_sum:", | ||
205 | le32_to_cpu(ofdm->re_acq_main_rssi_sum), | ||
206 | accum_ofdm->re_acq_main_rssi_sum, | ||
207 | delta_ofdm->re_acq_main_rssi_sum, | ||
208 | max_ofdm->re_acq_main_rssi_sum); | ||
209 | |||
210 | pos += scnprintf(buf + pos, bufsz - pos, | ||
211 | fmt_header, "Statistics_Rx - CCK:"); | ||
212 | pos += scnprintf(buf + pos, bufsz - pos, | ||
213 | fmt_table, "ina_cnt:", | ||
214 | le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, | ||
215 | delta_cck->ina_cnt, max_cck->ina_cnt); | ||
216 | pos += scnprintf(buf + pos, bufsz - pos, | ||
217 | fmt_table, "fina_cnt:", | ||
218 | le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, | ||
219 | delta_cck->fina_cnt, max_cck->fina_cnt); | ||
220 | pos += scnprintf(buf + pos, bufsz - pos, | ||
221 | fmt_table, "plcp_err:", | ||
222 | le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, | ||
223 | delta_cck->plcp_err, max_cck->plcp_err); | ||
224 | pos += scnprintf(buf + pos, bufsz - pos, | ||
225 | fmt_table, "crc32_err:", | ||
226 | le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, | ||
227 | delta_cck->crc32_err, max_cck->crc32_err); | ||
228 | pos += scnprintf(buf + pos, bufsz - pos, | ||
229 | fmt_table, "overrun_err:", | ||
230 | le32_to_cpu(cck->overrun_err), | ||
231 | accum_cck->overrun_err, delta_cck->overrun_err, | ||
232 | max_cck->overrun_err); | ||
233 | pos += scnprintf(buf + pos, bufsz - pos, | ||
234 | fmt_table, "early_overrun_err:", | ||
235 | le32_to_cpu(cck->early_overrun_err), | ||
236 | accum_cck->early_overrun_err, | ||
237 | delta_cck->early_overrun_err, | ||
238 | max_cck->early_overrun_err); | ||
239 | pos += scnprintf(buf + pos, bufsz - pos, | ||
240 | fmt_table, "crc32_good:", | ||
241 | le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, | ||
242 | delta_cck->crc32_good, max_cck->crc32_good); | ||
243 | pos += scnprintf(buf + pos, bufsz - pos, | ||
244 | fmt_table, "false_alarm_cnt:", | ||
245 | le32_to_cpu(cck->false_alarm_cnt), | ||
246 | accum_cck->false_alarm_cnt, | ||
247 | delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); | ||
248 | pos += scnprintf(buf + pos, bufsz - pos, | ||
249 | fmt_table, "fina_sync_err_cnt:", | ||
250 | le32_to_cpu(cck->fina_sync_err_cnt), | ||
251 | accum_cck->fina_sync_err_cnt, | ||
252 | delta_cck->fina_sync_err_cnt, | ||
253 | max_cck->fina_sync_err_cnt); | ||
254 | pos += scnprintf(buf + pos, bufsz - pos, | ||
255 | fmt_table, "sfd_timeout:", | ||
256 | le32_to_cpu(cck->sfd_timeout), | ||
257 | accum_cck->sfd_timeout, delta_cck->sfd_timeout, | ||
258 | max_cck->sfd_timeout); | ||
259 | pos += scnprintf(buf + pos, bufsz - pos, | ||
260 | fmt_table, "fina_timeout:", | ||
261 | le32_to_cpu(cck->fina_timeout), | ||
262 | accum_cck->fina_timeout, delta_cck->fina_timeout, | ||
263 | max_cck->fina_timeout); | ||
264 | pos += scnprintf(buf + pos, bufsz - pos, | ||
265 | fmt_table, "unresponded_rts:", | ||
266 | le32_to_cpu(cck->unresponded_rts), | ||
267 | accum_cck->unresponded_rts, delta_cck->unresponded_rts, | ||
268 | max_cck->unresponded_rts); | ||
269 | pos += scnprintf(buf + pos, bufsz - pos, | ||
270 | fmt_table, "rxe_frame_lmt_ovrun:", | ||
271 | le32_to_cpu(cck->rxe_frame_limit_overrun), | ||
272 | accum_cck->rxe_frame_limit_overrun, | ||
273 | delta_cck->rxe_frame_limit_overrun, | ||
274 | max_cck->rxe_frame_limit_overrun); | ||
275 | pos += scnprintf(buf + pos, bufsz - pos, | ||
276 | fmt_table, "sent_ack_cnt:", | ||
277 | le32_to_cpu(cck->sent_ack_cnt), | ||
278 | accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt, | ||
279 | max_cck->sent_ack_cnt); | ||
280 | pos += scnprintf(buf + pos, bufsz - pos, | ||
281 | fmt_table, "sent_cts_cnt:", | ||
282 | le32_to_cpu(cck->sent_cts_cnt), | ||
283 | accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt, | ||
284 | max_cck->sent_cts_cnt); | ||
285 | pos += scnprintf(buf + pos, bufsz - pos, | ||
286 | fmt_table, "sent_ba_rsp_cnt:", | ||
287 | le32_to_cpu(cck->sent_ba_rsp_cnt), | ||
288 | accum_cck->sent_ba_rsp_cnt, | ||
289 | delta_cck->sent_ba_rsp_cnt, | ||
290 | max_cck->sent_ba_rsp_cnt); | ||
291 | pos += scnprintf(buf + pos, bufsz - pos, | ||
292 | fmt_table, "dsp_self_kill:", | ||
293 | le32_to_cpu(cck->dsp_self_kill), | ||
294 | accum_cck->dsp_self_kill, delta_cck->dsp_self_kill, | ||
295 | max_cck->dsp_self_kill); | ||
296 | pos += scnprintf(buf + pos, bufsz - pos, | ||
297 | fmt_table, "mh_format_err:", | ||
298 | le32_to_cpu(cck->mh_format_err), | ||
299 | accum_cck->mh_format_err, delta_cck->mh_format_err, | ||
300 | max_cck->mh_format_err); | ||
301 | pos += scnprintf(buf + pos, bufsz - pos, | ||
302 | fmt_table, "re_acq_main_rssi_sum:", | ||
303 | le32_to_cpu(cck->re_acq_main_rssi_sum), | ||
304 | accum_cck->re_acq_main_rssi_sum, | ||
305 | delta_cck->re_acq_main_rssi_sum, | ||
306 | max_cck->re_acq_main_rssi_sum); | ||
307 | |||
308 | pos += scnprintf(buf + pos, bufsz - pos, | ||
309 | fmt_header, "Statistics_Rx - GENERAL:"); | ||
310 | pos += scnprintf(buf + pos, bufsz - pos, | ||
311 | fmt_table, "bogus_cts:", | ||
312 | le32_to_cpu(general->bogus_cts), | ||
313 | accum_general->bogus_cts, delta_general->bogus_cts, | ||
314 | max_general->bogus_cts); | ||
315 | pos += scnprintf(buf + pos, bufsz - pos, | ||
316 | fmt_table, "bogus_ack:", | ||
317 | le32_to_cpu(general->bogus_ack), | ||
318 | accum_general->bogus_ack, delta_general->bogus_ack, | ||
319 | max_general->bogus_ack); | ||
320 | pos += scnprintf(buf + pos, bufsz - pos, | ||
321 | fmt_table, "non_bssid_frames:", | ||
322 | le32_to_cpu(general->non_bssid_frames), | ||
323 | accum_general->non_bssid_frames, | ||
324 | delta_general->non_bssid_frames, | ||
325 | max_general->non_bssid_frames); | ||
326 | pos += scnprintf(buf + pos, bufsz - pos, | ||
327 | fmt_table, "filtered_frames:", | ||
328 | le32_to_cpu(general->filtered_frames), | ||
329 | accum_general->filtered_frames, | ||
330 | delta_general->filtered_frames, | ||
331 | max_general->filtered_frames); | ||
332 | pos += scnprintf(buf + pos, bufsz - pos, | ||
333 | fmt_table, "non_channel_beacons:", | ||
334 | le32_to_cpu(general->non_channel_beacons), | ||
335 | accum_general->non_channel_beacons, | ||
336 | delta_general->non_channel_beacons, | ||
337 | max_general->non_channel_beacons); | ||
338 | pos += scnprintf(buf + pos, bufsz - pos, | ||
339 | fmt_table, "channel_beacons:", | ||
340 | le32_to_cpu(general->channel_beacons), | ||
341 | accum_general->channel_beacons, | ||
342 | delta_general->channel_beacons, | ||
343 | max_general->channel_beacons); | ||
344 | pos += scnprintf(buf + pos, bufsz - pos, | ||
345 | fmt_table, "num_missed_bcon:", | ||
346 | le32_to_cpu(general->num_missed_bcon), | ||
347 | accum_general->num_missed_bcon, | ||
348 | delta_general->num_missed_bcon, | ||
349 | max_general->num_missed_bcon); | ||
350 | pos += scnprintf(buf + pos, bufsz - pos, | ||
351 | fmt_table, "adc_rx_saturation_time:", | ||
352 | le32_to_cpu(general->adc_rx_saturation_time), | ||
353 | accum_general->adc_rx_saturation_time, | ||
354 | delta_general->adc_rx_saturation_time, | ||
355 | max_general->adc_rx_saturation_time); | ||
356 | pos += scnprintf(buf + pos, bufsz - pos, | ||
357 | fmt_table, "ina_detect_search_tm:", | ||
358 | le32_to_cpu(general->ina_detection_search_time), | ||
359 | accum_general->ina_detection_search_time, | ||
360 | delta_general->ina_detection_search_time, | ||
361 | max_general->ina_detection_search_time); | ||
362 | pos += scnprintf(buf + pos, bufsz - pos, | ||
363 | fmt_table, "beacon_silence_rssi_a:", | ||
364 | le32_to_cpu(general->beacon_silence_rssi_a), | ||
365 | accum_general->beacon_silence_rssi_a, | ||
366 | delta_general->beacon_silence_rssi_a, | ||
367 | max_general->beacon_silence_rssi_a); | ||
368 | pos += scnprintf(buf + pos, bufsz - pos, | ||
369 | fmt_table, "beacon_silence_rssi_b:", | ||
370 | le32_to_cpu(general->beacon_silence_rssi_b), | ||
371 | accum_general->beacon_silence_rssi_b, | ||
372 | delta_general->beacon_silence_rssi_b, | ||
373 | max_general->beacon_silence_rssi_b); | ||
374 | pos += scnprintf(buf + pos, bufsz - pos, | ||
375 | fmt_table, "beacon_silence_rssi_c:", | ||
376 | le32_to_cpu(general->beacon_silence_rssi_c), | ||
377 | accum_general->beacon_silence_rssi_c, | ||
378 | delta_general->beacon_silence_rssi_c, | ||
379 | max_general->beacon_silence_rssi_c); | ||
380 | pos += scnprintf(buf + pos, bufsz - pos, | ||
381 | fmt_table, "interference_data_flag:", | ||
382 | le32_to_cpu(general->interference_data_flag), | ||
383 | accum_general->interference_data_flag, | ||
384 | delta_general->interference_data_flag, | ||
385 | max_general->interference_data_flag); | ||
386 | pos += scnprintf(buf + pos, bufsz - pos, | ||
387 | fmt_table, "channel_load:", | ||
388 | le32_to_cpu(general->channel_load), | ||
389 | accum_general->channel_load, | ||
390 | delta_general->channel_load, | ||
391 | max_general->channel_load); | ||
392 | pos += scnprintf(buf + pos, bufsz - pos, | ||
393 | fmt_table, "dsp_false_alarms:", | ||
394 | le32_to_cpu(general->dsp_false_alarms), | ||
395 | accum_general->dsp_false_alarms, | ||
396 | delta_general->dsp_false_alarms, | ||
397 | max_general->dsp_false_alarms); | ||
398 | pos += scnprintf(buf + pos, bufsz - pos, | ||
399 | fmt_table, "beacon_rssi_a:", | ||
400 | le32_to_cpu(general->beacon_rssi_a), | ||
401 | accum_general->beacon_rssi_a, | ||
402 | delta_general->beacon_rssi_a, | ||
403 | max_general->beacon_rssi_a); | ||
404 | pos += scnprintf(buf + pos, bufsz - pos, | ||
405 | fmt_table, "beacon_rssi_b:", | ||
406 | le32_to_cpu(general->beacon_rssi_b), | ||
407 | accum_general->beacon_rssi_b, | ||
408 | delta_general->beacon_rssi_b, | ||
409 | max_general->beacon_rssi_b); | ||
410 | pos += scnprintf(buf + pos, bufsz - pos, | ||
411 | fmt_table, "beacon_rssi_c:", | ||
412 | le32_to_cpu(general->beacon_rssi_c), | ||
413 | accum_general->beacon_rssi_c, | ||
414 | delta_general->beacon_rssi_c, | ||
415 | max_general->beacon_rssi_c); | ||
416 | pos += scnprintf(buf + pos, bufsz - pos, | ||
417 | fmt_table, "beacon_energy_a:", | ||
418 | le32_to_cpu(general->beacon_energy_a), | ||
419 | accum_general->beacon_energy_a, | ||
420 | delta_general->beacon_energy_a, | ||
421 | max_general->beacon_energy_a); | ||
422 | pos += scnprintf(buf + pos, bufsz - pos, | ||
423 | fmt_table, "beacon_energy_b:", | ||
424 | le32_to_cpu(general->beacon_energy_b), | ||
425 | accum_general->beacon_energy_b, | ||
426 | delta_general->beacon_energy_b, | ||
427 | max_general->beacon_energy_b); | ||
428 | pos += scnprintf(buf + pos, bufsz - pos, | ||
429 | fmt_table, "beacon_energy_c:", | ||
430 | le32_to_cpu(general->beacon_energy_c), | ||
431 | accum_general->beacon_energy_c, | ||
432 | delta_general->beacon_energy_c, | ||
433 | max_general->beacon_energy_c); | ||
434 | |||
435 | pos += scnprintf(buf + pos, bufsz - pos, | ||
436 | fmt_header, "Statistics_Rx - OFDM_HT:"); | ||
437 | pos += scnprintf(buf + pos, bufsz - pos, | ||
438 | fmt_table, "plcp_err:", | ||
439 | le32_to_cpu(ht->plcp_err), accum_ht->plcp_err, | ||
440 | delta_ht->plcp_err, max_ht->plcp_err); | ||
441 | pos += scnprintf(buf + pos, bufsz - pos, | ||
442 | fmt_table, "overrun_err:", | ||
443 | le32_to_cpu(ht->overrun_err), accum_ht->overrun_err, | ||
444 | delta_ht->overrun_err, max_ht->overrun_err); | ||
445 | pos += scnprintf(buf + pos, bufsz - pos, | ||
446 | fmt_table, "early_overrun_err:", | ||
447 | le32_to_cpu(ht->early_overrun_err), | ||
448 | accum_ht->early_overrun_err, | ||
449 | delta_ht->early_overrun_err, | ||
450 | max_ht->early_overrun_err); | ||
451 | pos += scnprintf(buf + pos, bufsz - pos, | ||
452 | fmt_table, "crc32_good:", | ||
453 | le32_to_cpu(ht->crc32_good), accum_ht->crc32_good, | ||
454 | delta_ht->crc32_good, max_ht->crc32_good); | ||
455 | pos += scnprintf(buf + pos, bufsz - pos, | ||
456 | fmt_table, "crc32_err:", | ||
457 | le32_to_cpu(ht->crc32_err), accum_ht->crc32_err, | ||
458 | delta_ht->crc32_err, max_ht->crc32_err); | ||
459 | pos += scnprintf(buf + pos, bufsz - pos, | ||
460 | fmt_table, "mh_format_err:", | ||
461 | le32_to_cpu(ht->mh_format_err), | ||
462 | accum_ht->mh_format_err, | ||
463 | delta_ht->mh_format_err, max_ht->mh_format_err); | ||
464 | pos += scnprintf(buf + pos, bufsz - pos, | ||
465 | fmt_table, "agg_crc32_good:", | ||
466 | le32_to_cpu(ht->agg_crc32_good), | ||
467 | accum_ht->agg_crc32_good, | ||
468 | delta_ht->agg_crc32_good, max_ht->agg_crc32_good); | ||
469 | pos += scnprintf(buf + pos, bufsz - pos, | ||
470 | fmt_table, "agg_mpdu_cnt:", | ||
471 | le32_to_cpu(ht->agg_mpdu_cnt), | ||
472 | accum_ht->agg_mpdu_cnt, | ||
473 | delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt); | ||
474 | pos += scnprintf(buf + pos, bufsz - pos, | ||
475 | fmt_table, "agg_cnt:", | ||
476 | le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt, | ||
477 | delta_ht->agg_cnt, max_ht->agg_cnt); | ||
478 | pos += scnprintf(buf + pos, bufsz - pos, | ||
479 | fmt_table, "unsupport_mcs:", | ||
480 | le32_to_cpu(ht->unsupport_mcs), | ||
481 | accum_ht->unsupport_mcs, | ||
482 | delta_ht->unsupport_mcs, max_ht->unsupport_mcs); | ||
483 | |||
484 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
485 | kfree(buf); | ||
486 | return ret; | ||
487 | } | ||
488 | |||
489 | ssize_t iwl_ucode_tx_stats_read(struct file *file, | ||
490 | char __user *user_buf, | ||
491 | size_t count, loff_t *ppos) | ||
492 | { | ||
493 | struct iwl_priv *priv = file->private_data; | ||
494 | int pos = 0; | ||
495 | char *buf; | ||
496 | int bufsz = (sizeof(struct statistics_tx) * 48) + 250; | ||
497 | ssize_t ret; | ||
498 | struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; | ||
499 | |||
500 | if (!iwl_is_alive(priv)) | ||
501 | return -EAGAIN; | ||
502 | |||
503 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
504 | if (!buf) { | ||
505 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
506 | return -ENOMEM; | ||
507 | } | ||
508 | |||
509 | /* the statistic information display here is based on | ||
510 | * the last statistics notification from uCode | ||
511 | * might not reflect the current uCode activity | ||
512 | */ | ||
513 | tx = &priv->statistics.tx; | ||
514 | accum_tx = &priv->accum_stats.tx; | ||
515 | delta_tx = &priv->delta_stats.tx; | ||
516 | max_tx = &priv->max_delta_stats.tx; | ||
517 | |||
518 | pos += iwl_statistics_flag(priv, buf, bufsz); | ||
519 | pos += scnprintf(buf + pos, bufsz - pos, | ||
520 | fmt_header, "Statistics_Tx:"); | ||
521 | pos += scnprintf(buf + pos, bufsz - pos, | ||
522 | fmt_table, "preamble:", | ||
523 | le32_to_cpu(tx->preamble_cnt), | ||
524 | accum_tx->preamble_cnt, | ||
525 | delta_tx->preamble_cnt, max_tx->preamble_cnt); | ||
526 | pos += scnprintf(buf + pos, bufsz - pos, | ||
527 | fmt_table, "rx_detected_cnt:", | ||
528 | le32_to_cpu(tx->rx_detected_cnt), | ||
529 | accum_tx->rx_detected_cnt, | ||
530 | delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); | ||
531 | pos += scnprintf(buf + pos, bufsz - pos, | ||
532 | fmt_table, "bt_prio_defer_cnt:", | ||
533 | le32_to_cpu(tx->bt_prio_defer_cnt), | ||
534 | accum_tx->bt_prio_defer_cnt, | ||
535 | delta_tx->bt_prio_defer_cnt, | ||
536 | max_tx->bt_prio_defer_cnt); | ||
537 | pos += scnprintf(buf + pos, bufsz - pos, | ||
538 | fmt_table, "bt_prio_kill_cnt:", | ||
539 | le32_to_cpu(tx->bt_prio_kill_cnt), | ||
540 | accum_tx->bt_prio_kill_cnt, | ||
541 | delta_tx->bt_prio_kill_cnt, | ||
542 | max_tx->bt_prio_kill_cnt); | ||
543 | pos += scnprintf(buf + pos, bufsz - pos, | ||
544 | fmt_table, "few_bytes_cnt:", | ||
545 | le32_to_cpu(tx->few_bytes_cnt), | ||
546 | accum_tx->few_bytes_cnt, | ||
547 | delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); | ||
548 | pos += scnprintf(buf + pos, bufsz - pos, | ||
549 | fmt_table, "cts_timeout:", | ||
550 | le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, | ||
551 | delta_tx->cts_timeout, max_tx->cts_timeout); | ||
552 | pos += scnprintf(buf + pos, bufsz - pos, | ||
553 | fmt_table, "ack_timeout:", | ||
554 | le32_to_cpu(tx->ack_timeout), | ||
555 | accum_tx->ack_timeout, | ||
556 | delta_tx->ack_timeout, max_tx->ack_timeout); | ||
557 | pos += scnprintf(buf + pos, bufsz - pos, | ||
558 | fmt_table, "expected_ack_cnt:", | ||
559 | le32_to_cpu(tx->expected_ack_cnt), | ||
560 | accum_tx->expected_ack_cnt, | ||
561 | delta_tx->expected_ack_cnt, | ||
562 | max_tx->expected_ack_cnt); | ||
563 | pos += scnprintf(buf + pos, bufsz - pos, | ||
564 | fmt_table, "actual_ack_cnt:", | ||
565 | le32_to_cpu(tx->actual_ack_cnt), | ||
566 | accum_tx->actual_ack_cnt, | ||
567 | delta_tx->actual_ack_cnt, | ||
568 | max_tx->actual_ack_cnt); | ||
569 | pos += scnprintf(buf + pos, bufsz - pos, | ||
570 | fmt_table, "dump_msdu_cnt:", | ||
571 | le32_to_cpu(tx->dump_msdu_cnt), | ||
572 | accum_tx->dump_msdu_cnt, | ||
573 | delta_tx->dump_msdu_cnt, | ||
574 | max_tx->dump_msdu_cnt); | ||
575 | pos += scnprintf(buf + pos, bufsz - pos, | ||
576 | fmt_table, "abort_nxt_frame_mismatch:", | ||
577 | le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), | ||
578 | accum_tx->burst_abort_next_frame_mismatch_cnt, | ||
579 | delta_tx->burst_abort_next_frame_mismatch_cnt, | ||
580 | max_tx->burst_abort_next_frame_mismatch_cnt); | ||
581 | pos += scnprintf(buf + pos, bufsz - pos, | ||
582 | fmt_table, "abort_missing_nxt_frame:", | ||
583 | le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), | ||
584 | accum_tx->burst_abort_missing_next_frame_cnt, | ||
585 | delta_tx->burst_abort_missing_next_frame_cnt, | ||
586 | max_tx->burst_abort_missing_next_frame_cnt); | ||
587 | pos += scnprintf(buf + pos, bufsz - pos, | ||
588 | fmt_table, "cts_timeout_collision:", | ||
589 | le32_to_cpu(tx->cts_timeout_collision), | ||
590 | accum_tx->cts_timeout_collision, | ||
591 | delta_tx->cts_timeout_collision, | ||
592 | max_tx->cts_timeout_collision); | ||
593 | pos += scnprintf(buf + pos, bufsz - pos, | ||
594 | fmt_table, "ack_ba_timeout_collision:", | ||
595 | le32_to_cpu(tx->ack_or_ba_timeout_collision), | ||
596 | accum_tx->ack_or_ba_timeout_collision, | ||
597 | delta_tx->ack_or_ba_timeout_collision, | ||
598 | max_tx->ack_or_ba_timeout_collision); | ||
599 | pos += scnprintf(buf + pos, bufsz - pos, | ||
600 | fmt_table, "agg ba_timeout:", | ||
601 | le32_to_cpu(tx->agg.ba_timeout), | ||
602 | accum_tx->agg.ba_timeout, | ||
603 | delta_tx->agg.ba_timeout, | ||
604 | max_tx->agg.ba_timeout); | ||
605 | pos += scnprintf(buf + pos, bufsz - pos, | ||
606 | fmt_table, "agg ba_resched_frames:", | ||
607 | le32_to_cpu(tx->agg.ba_reschedule_frames), | ||
608 | accum_tx->agg.ba_reschedule_frames, | ||
609 | delta_tx->agg.ba_reschedule_frames, | ||
610 | max_tx->agg.ba_reschedule_frames); | ||
611 | pos += scnprintf(buf + pos, bufsz - pos, | ||
612 | fmt_table, "agg scd_query_agg_frame:", | ||
613 | le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), | ||
614 | accum_tx->agg.scd_query_agg_frame_cnt, | ||
615 | delta_tx->agg.scd_query_agg_frame_cnt, | ||
616 | max_tx->agg.scd_query_agg_frame_cnt); | ||
617 | pos += scnprintf(buf + pos, bufsz - pos, | ||
618 | fmt_table, "agg scd_query_no_agg:", | ||
619 | le32_to_cpu(tx->agg.scd_query_no_agg), | ||
620 | accum_tx->agg.scd_query_no_agg, | ||
621 | delta_tx->agg.scd_query_no_agg, | ||
622 | max_tx->agg.scd_query_no_agg); | ||
623 | pos += scnprintf(buf + pos, bufsz - pos, | ||
624 | fmt_table, "agg scd_query_agg:", | ||
625 | le32_to_cpu(tx->agg.scd_query_agg), | ||
626 | accum_tx->agg.scd_query_agg, | ||
627 | delta_tx->agg.scd_query_agg, | ||
628 | max_tx->agg.scd_query_agg); | ||
629 | pos += scnprintf(buf + pos, bufsz - pos, | ||
630 | fmt_table, "agg scd_query_mismatch:", | ||
631 | le32_to_cpu(tx->agg.scd_query_mismatch), | ||
632 | accum_tx->agg.scd_query_mismatch, | ||
633 | delta_tx->agg.scd_query_mismatch, | ||
634 | max_tx->agg.scd_query_mismatch); | ||
635 | pos += scnprintf(buf + pos, bufsz - pos, | ||
636 | fmt_table, "agg frame_not_ready:", | ||
637 | le32_to_cpu(tx->agg.frame_not_ready), | ||
638 | accum_tx->agg.frame_not_ready, | ||
639 | delta_tx->agg.frame_not_ready, | ||
640 | max_tx->agg.frame_not_ready); | ||
641 | pos += scnprintf(buf + pos, bufsz - pos, | ||
642 | fmt_table, "agg underrun:", | ||
643 | le32_to_cpu(tx->agg.underrun), | ||
644 | accum_tx->agg.underrun, | ||
645 | delta_tx->agg.underrun, max_tx->agg.underrun); | ||
646 | pos += scnprintf(buf + pos, bufsz - pos, | ||
647 | fmt_table, "agg bt_prio_kill:", | ||
648 | le32_to_cpu(tx->agg.bt_prio_kill), | ||
649 | accum_tx->agg.bt_prio_kill, | ||
650 | delta_tx->agg.bt_prio_kill, | ||
651 | max_tx->agg.bt_prio_kill); | ||
652 | pos += scnprintf(buf + pos, bufsz - pos, | ||
653 | fmt_table, "agg rx_ba_rsp_cnt:", | ||
654 | le32_to_cpu(tx->agg.rx_ba_rsp_cnt), | ||
655 | accum_tx->agg.rx_ba_rsp_cnt, | ||
656 | delta_tx->agg.rx_ba_rsp_cnt, | ||
657 | max_tx->agg.rx_ba_rsp_cnt); | ||
658 | |||
659 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { | ||
660 | pos += scnprintf(buf + pos, bufsz - pos, | ||
661 | "tx power: (1/2 dB step)\n"); | ||
662 | if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) | ||
663 | pos += scnprintf(buf + pos, bufsz - pos, | ||
664 | fmt_hex, "antenna A:", | ||
665 | tx->tx_power.ant_a); | ||
666 | if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) | ||
667 | pos += scnprintf(buf + pos, bufsz - pos, | ||
668 | fmt_hex, "antenna B:", | ||
669 | tx->tx_power.ant_b); | ||
670 | if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) | ||
671 | pos += scnprintf(buf + pos, bufsz - pos, | ||
672 | fmt_hex, "antenna C:", | ||
673 | tx->tx_power.ant_c); | ||
674 | } | ||
675 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
676 | kfree(buf); | ||
677 | return ret; | ||
678 | } | ||
679 | |||
680 | ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | ||
681 | size_t count, loff_t *ppos) | ||
682 | { | ||
683 | struct iwl_priv *priv = file->private_data; | ||
684 | int pos = 0; | ||
685 | char *buf; | ||
686 | int bufsz = sizeof(struct statistics_general) * 10 + 300; | ||
687 | ssize_t ret; | ||
688 | struct statistics_general_common *general, *accum_general; | ||
689 | struct statistics_general_common *delta_general, *max_general; | ||
690 | struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; | ||
691 | struct statistics_div *div, *accum_div, *delta_div, *max_div; | ||
692 | |||
693 | if (!iwl_is_alive(priv)) | ||
694 | return -EAGAIN; | ||
695 | |||
696 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
697 | if (!buf) { | ||
698 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
699 | return -ENOMEM; | ||
700 | } | ||
701 | |||
702 | /* the statistic information display here is based on | ||
703 | * the last statistics notification from uCode | ||
704 | * might not reflect the current uCode activity | ||
705 | */ | ||
706 | general = &priv->statistics.common; | ||
707 | dbg = &priv->statistics.common.dbg; | ||
708 | div = &priv->statistics.common.div; | ||
709 | accum_general = &priv->accum_stats.common; | ||
710 | accum_dbg = &priv->accum_stats.common.dbg; | ||
711 | accum_div = &priv->accum_stats.common.div; | ||
712 | delta_general = &priv->delta_stats.common; | ||
713 | max_general = &priv->max_delta_stats.common; | ||
714 | delta_dbg = &priv->delta_stats.common.dbg; | ||
715 | max_dbg = &priv->max_delta_stats.common.dbg; | ||
716 | delta_div = &priv->delta_stats.common.div; | ||
717 | max_div = &priv->max_delta_stats.common.div; | ||
718 | |||
719 | pos += iwl_statistics_flag(priv, buf, bufsz); | ||
720 | pos += scnprintf(buf + pos, bufsz - pos, | ||
721 | fmt_header, "Statistics_General:"); | ||
722 | pos += scnprintf(buf + pos, bufsz - pos, | ||
723 | fmt_value, "temperature:", | ||
724 | le32_to_cpu(general->temperature)); | ||
725 | pos += scnprintf(buf + pos, bufsz - pos, | ||
726 | fmt_value, "temperature_m:", | ||
727 | le32_to_cpu(general->temperature_m)); | ||
728 | pos += scnprintf(buf + pos, bufsz - pos, | ||
729 | fmt_value, "ttl_timestamp:", | ||
730 | le32_to_cpu(general->ttl_timestamp)); | ||
731 | pos += scnprintf(buf + pos, bufsz - pos, | ||
732 | fmt_table, "burst_check:", | ||
733 | le32_to_cpu(dbg->burst_check), | ||
734 | accum_dbg->burst_check, | ||
735 | delta_dbg->burst_check, max_dbg->burst_check); | ||
736 | pos += scnprintf(buf + pos, bufsz - pos, | ||
737 | fmt_table, "burst_count:", | ||
738 | le32_to_cpu(dbg->burst_count), | ||
739 | accum_dbg->burst_count, | ||
740 | delta_dbg->burst_count, max_dbg->burst_count); | ||
741 | pos += scnprintf(buf + pos, bufsz - pos, | ||
742 | fmt_table, "wait_for_silence_timeout_count:", | ||
743 | le32_to_cpu(dbg->wait_for_silence_timeout_cnt), | ||
744 | accum_dbg->wait_for_silence_timeout_cnt, | ||
745 | delta_dbg->wait_for_silence_timeout_cnt, | ||
746 | max_dbg->wait_for_silence_timeout_cnt); | ||
747 | pos += scnprintf(buf + pos, bufsz - pos, | ||
748 | fmt_table, "sleep_time:", | ||
749 | le32_to_cpu(general->sleep_time), | ||
750 | accum_general->sleep_time, | ||
751 | delta_general->sleep_time, max_general->sleep_time); | ||
752 | pos += scnprintf(buf + pos, bufsz - pos, | ||
753 | fmt_table, "slots_out:", | ||
754 | le32_to_cpu(general->slots_out), | ||
755 | accum_general->slots_out, | ||
756 | delta_general->slots_out, max_general->slots_out); | ||
757 | pos += scnprintf(buf + pos, bufsz - pos, | ||
758 | fmt_table, "slots_idle:", | ||
759 | le32_to_cpu(general->slots_idle), | ||
760 | accum_general->slots_idle, | ||
761 | delta_general->slots_idle, max_general->slots_idle); | ||
762 | pos += scnprintf(buf + pos, bufsz - pos, | ||
763 | fmt_table, "tx_on_a:", | ||
764 | le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, | ||
765 | delta_div->tx_on_a, max_div->tx_on_a); | ||
766 | pos += scnprintf(buf + pos, bufsz - pos, | ||
767 | fmt_table, "tx_on_b:", | ||
768 | le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, | ||
769 | delta_div->tx_on_b, max_div->tx_on_b); | ||
770 | pos += scnprintf(buf + pos, bufsz - pos, | ||
771 | fmt_table, "exec_time:", | ||
772 | le32_to_cpu(div->exec_time), accum_div->exec_time, | ||
773 | delta_div->exec_time, max_div->exec_time); | ||
774 | pos += scnprintf(buf + pos, bufsz - pos, | ||
775 | fmt_table, "probe_time:", | ||
776 | le32_to_cpu(div->probe_time), accum_div->probe_time, | ||
777 | delta_div->probe_time, max_div->probe_time); | ||
778 | pos += scnprintf(buf + pos, bufsz - pos, | ||
779 | fmt_table, "rx_enable_counter:", | ||
780 | le32_to_cpu(general->rx_enable_counter), | ||
781 | accum_general->rx_enable_counter, | ||
782 | delta_general->rx_enable_counter, | ||
783 | max_general->rx_enable_counter); | ||
784 | pos += scnprintf(buf + pos, bufsz - pos, | ||
785 | fmt_table, "num_of_sos_states:", | ||
786 | le32_to_cpu(general->num_of_sos_states), | ||
787 | accum_general->num_of_sos_states, | ||
788 | delta_general->num_of_sos_states, | ||
789 | max_general->num_of_sos_states); | ||
790 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
791 | kfree(buf); | ||
792 | return ret; | ||
793 | } | ||
794 | |||
795 | ssize_t iwl_ucode_bt_stats_read(struct file *file, | ||
796 | char __user *user_buf, | ||
797 | size_t count, loff_t *ppos) | ||
798 | { | ||
799 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
800 | int pos = 0; | ||
801 | char *buf; | ||
802 | int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200; | ||
803 | ssize_t ret; | ||
804 | struct statistics_bt_activity *bt, *accum_bt; | ||
805 | |||
806 | if (!iwl_is_alive(priv)) | ||
807 | return -EAGAIN; | ||
808 | |||
809 | if (!priv->bt_enable_flag) | ||
810 | return -EINVAL; | ||
811 | |||
812 | /* make request to uCode to retrieve statistics information */ | ||
813 | mutex_lock(&priv->mutex); | ||
814 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); | ||
815 | mutex_unlock(&priv->mutex); | ||
816 | |||
817 | if (ret) { | ||
818 | IWL_ERR(priv, | ||
819 | "Error sending statistics request: %zd\n", ret); | ||
820 | return -EAGAIN; | ||
821 | } | ||
822 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
823 | if (!buf) { | ||
824 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
825 | return -ENOMEM; | ||
826 | } | ||
827 | |||
828 | /* | ||
829 | * the statistic information display here is based on | ||
830 | * the last statistics notification from uCode | ||
831 | * might not reflect the current uCode activity | ||
832 | */ | ||
833 | bt = &priv->statistics.bt_activity; | ||
834 | accum_bt = &priv->accum_stats.bt_activity; | ||
835 | |||
836 | pos += iwl_statistics_flag(priv, buf, bufsz); | ||
837 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); | ||
838 | pos += scnprintf(buf + pos, bufsz - pos, | ||
839 | "\t\t\tcurrent\t\t\taccumulative\n"); | ||
840 | pos += scnprintf(buf + pos, bufsz - pos, | ||
841 | "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", | ||
842 | le32_to_cpu(bt->hi_priority_tx_req_cnt), | ||
843 | accum_bt->hi_priority_tx_req_cnt); | ||
844 | pos += scnprintf(buf + pos, bufsz - pos, | ||
845 | "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n", | ||
846 | le32_to_cpu(bt->hi_priority_tx_denied_cnt), | ||
847 | accum_bt->hi_priority_tx_denied_cnt); | ||
848 | pos += scnprintf(buf + pos, bufsz - pos, | ||
849 | "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", | ||
850 | le32_to_cpu(bt->lo_priority_tx_req_cnt), | ||
851 | accum_bt->lo_priority_tx_req_cnt); | ||
852 | pos += scnprintf(buf + pos, bufsz - pos, | ||
853 | "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n", | ||
854 | le32_to_cpu(bt->lo_priority_tx_denied_cnt), | ||
855 | accum_bt->lo_priority_tx_denied_cnt); | ||
856 | pos += scnprintf(buf + pos, bufsz - pos, | ||
857 | "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", | ||
858 | le32_to_cpu(bt->hi_priority_rx_req_cnt), | ||
859 | accum_bt->hi_priority_rx_req_cnt); | ||
860 | pos += scnprintf(buf + pos, bufsz - pos, | ||
861 | "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n", | ||
862 | le32_to_cpu(bt->hi_priority_rx_denied_cnt), | ||
863 | accum_bt->hi_priority_rx_denied_cnt); | ||
864 | pos += scnprintf(buf + pos, bufsz - pos, | ||
865 | "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", | ||
866 | le32_to_cpu(bt->lo_priority_rx_req_cnt), | ||
867 | accum_bt->lo_priority_rx_req_cnt); | ||
868 | pos += scnprintf(buf + pos, bufsz - pos, | ||
869 | "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", | ||
870 | le32_to_cpu(bt->lo_priority_rx_denied_cnt), | ||
871 | accum_bt->lo_priority_rx_denied_cnt); | ||
872 | |||
873 | pos += scnprintf(buf + pos, bufsz - pos, | ||
874 | "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", | ||
875 | le32_to_cpu(priv->statistics.num_bt_kills), | ||
876 | priv->statistics.accum_num_bt_kills); | ||
877 | |||
878 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
879 | kfree(buf); | ||
880 | return ret; | ||
881 | } | ||
882 | |||
883 | ssize_t iwl_reply_tx_error_read(struct file *file, | ||
884 | char __user *user_buf, | ||
885 | size_t count, loff_t *ppos) | ||
886 | { | ||
887 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
888 | int pos = 0; | ||
889 | char *buf; | ||
890 | int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) + | ||
891 | (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; | ||
892 | ssize_t ret; | ||
893 | |||
894 | if (!iwl_is_alive(priv)) | ||
895 | return -EAGAIN; | ||
896 | |||
897 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
898 | if (!buf) { | ||
899 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
900 | return -ENOMEM; | ||
901 | } | ||
902 | |||
903 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n"); | ||
904 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n", | ||
905 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY), | ||
906 | priv->_agn.reply_tx_stats.pp_delay); | ||
907 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
908 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES), | ||
909 | priv->_agn.reply_tx_stats.pp_few_bytes); | ||
910 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
911 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO), | ||
912 | priv->_agn.reply_tx_stats.pp_bt_prio); | ||
913 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
914 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD), | ||
915 | priv->_agn.reply_tx_stats.pp_quiet_period); | ||
916 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
917 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK), | ||
918 | priv->_agn.reply_tx_stats.pp_calc_ttak); | ||
919 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
920 | iwl_get_tx_fail_reason( | ||
921 | TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY), | ||
922 | priv->_agn.reply_tx_stats.int_crossed_retry); | ||
923 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
924 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT), | ||
925 | priv->_agn.reply_tx_stats.short_limit); | ||
926 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
927 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT), | ||
928 | priv->_agn.reply_tx_stats.long_limit); | ||
929 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
930 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN), | ||
931 | priv->_agn.reply_tx_stats.fifo_underrun); | ||
932 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
933 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW), | ||
934 | priv->_agn.reply_tx_stats.drain_flow); | ||
935 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
936 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH), | ||
937 | priv->_agn.reply_tx_stats.rfkill_flush); | ||
938 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
939 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE), | ||
940 | priv->_agn.reply_tx_stats.life_expire); | ||
941 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
942 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS), | ||
943 | priv->_agn.reply_tx_stats.dest_ps); | ||
944 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
945 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED), | ||
946 | priv->_agn.reply_tx_stats.host_abort); | ||
947 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
948 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY), | ||
949 | priv->_agn.reply_tx_stats.pp_delay); | ||
950 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
951 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID), | ||
952 | priv->_agn.reply_tx_stats.sta_invalid); | ||
953 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
954 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED), | ||
955 | priv->_agn.reply_tx_stats.frag_drop); | ||
956 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
957 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE), | ||
958 | priv->_agn.reply_tx_stats.tid_disable); | ||
959 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
960 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED), | ||
961 | priv->_agn.reply_tx_stats.fifo_flush); | ||
962 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
963 | iwl_get_tx_fail_reason( | ||
964 | TX_STATUS_FAIL_INSUFFICIENT_CF_POLL), | ||
965 | priv->_agn.reply_tx_stats.insuff_cf_poll); | ||
966 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
967 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX), | ||
968 | priv->_agn.reply_tx_stats.fail_hw_drop); | ||
969 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
970 | iwl_get_tx_fail_reason( | ||
971 | TX_STATUS_FAIL_NO_BEACON_ON_RADAR), | ||
972 | priv->_agn.reply_tx_stats.sta_color_mismatch); | ||
973 | pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", | ||
974 | priv->_agn.reply_tx_stats.unknown); | ||
975 | |||
976 | pos += scnprintf(buf + pos, bufsz - pos, | ||
977 | "\nStatistics_Agg_TX_Error:\n"); | ||
978 | |||
979 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
980 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK), | ||
981 | priv->_agn.reply_agg_tx_stats.underrun); | ||
982 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
983 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK), | ||
984 | priv->_agn.reply_agg_tx_stats.bt_prio); | ||
985 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
986 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK), | ||
987 | priv->_agn.reply_agg_tx_stats.few_bytes); | ||
988 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
989 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK), | ||
990 | priv->_agn.reply_agg_tx_stats.abort); | ||
991 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
992 | iwl_get_agg_tx_fail_reason( | ||
993 | AGG_TX_STATE_LAST_SENT_TTL_MSK), | ||
994 | priv->_agn.reply_agg_tx_stats.last_sent_ttl); | ||
995 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
996 | iwl_get_agg_tx_fail_reason( | ||
997 | AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK), | ||
998 | priv->_agn.reply_agg_tx_stats.last_sent_try); | ||
999 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
1000 | iwl_get_agg_tx_fail_reason( | ||
1001 | AGG_TX_STATE_LAST_SENT_BT_KILL_MSK), | ||
1002 | priv->_agn.reply_agg_tx_stats.last_sent_bt_kill); | ||
1003 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1004 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK), | ||
1005 | priv->_agn.reply_agg_tx_stats.scd_query); | ||
1006 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
1007 | iwl_get_agg_tx_fail_reason( | ||
1008 | AGG_TX_STATE_TEST_BAD_CRC32_MSK), | ||
1009 | priv->_agn.reply_agg_tx_stats.bad_crc32); | ||
1010 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1011 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK), | ||
1012 | priv->_agn.reply_agg_tx_stats.response); | ||
1013 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1014 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK), | ||
1015 | priv->_agn.reply_agg_tx_stats.dump_tx); | ||
1016 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1017 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK), | ||
1018 | priv->_agn.reply_agg_tx_stats.delay_tx); | ||
1019 | pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", | ||
1020 | priv->_agn.reply_agg_tx_stats.unknown); | ||
1021 | |||
1022 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
1023 | kfree(buf); | ||
1024 | return ret; | ||
1025 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h deleted file mode 100644 index 9a3f329e508f..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * GPL LICENSE SUMMARY | ||
4 | * | ||
5 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
19 | * USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution | ||
22 | * in the file called LICENSE.GPL. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #include "iwl-dev.h" | ||
30 | #include "iwl-core.h" | ||
31 | #include "iwl-debug.h" | ||
32 | |||
33 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
34 | ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | ||
35 | size_t count, loff_t *ppos); | ||
36 | ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf, | ||
37 | size_t count, loff_t *ppos); | ||
38 | ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | ||
39 | size_t count, loff_t *ppos); | ||
40 | ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, | ||
41 | size_t count, loff_t *ppos); | ||
42 | ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf, | ||
43 | size_t count, loff_t *ppos); | ||
44 | #else | ||
45 | static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | ||
46 | size_t count, loff_t *ppos) | ||
47 | { | ||
48 | return 0; | ||
49 | } | ||
50 | static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf, | ||
51 | size_t count, loff_t *ppos) | ||
52 | { | ||
53 | return 0; | ||
54 | } | ||
55 | static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | ||
56 | size_t count, loff_t *ppos) | ||
57 | { | ||
58 | return 0; | ||
59 | } | ||
60 | static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, | ||
61 | size_t count, loff_t *ppos) | ||
62 | { | ||
63 | return 0; | ||
64 | } | ||
65 | static ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf, | ||
66 | size_t count, loff_t *ppos) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 3bcaa10f9929..2ef9448b1c20 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | |||
@@ -81,52 +81,13 @@ | |||
81 | * | 81 | * |
82 | ******************************************************************************/ | 82 | ******************************************************************************/ |
83 | 83 | ||
84 | /* | ||
85 | * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||
86 | * when accessing the EEPROM; each access is a series of pulses to/from the | ||
87 | * EEPROM chip, not a single event, so even reads could conflict if they | ||
88 | * weren't arbitrated by the semaphore. | ||
89 | */ | ||
90 | int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv) | ||
91 | { | ||
92 | u16 count; | ||
93 | int ret; | ||
94 | |||
95 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||
96 | /* Request semaphore */ | ||
97 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
98 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
99 | |||
100 | /* See if we got it */ | ||
101 | ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
102 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
103 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
104 | EEPROM_SEM_TIMEOUT); | ||
105 | if (ret >= 0) { | ||
106 | IWL_DEBUG_EEPROM(priv, | ||
107 | "Acquired semaphore after %d tries.\n", | ||
108 | count+1); | ||
109 | return ret; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv) | ||
117 | { | ||
118 | iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
119 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
120 | |||
121 | } | ||
122 | |||
123 | int iwl_eeprom_check_version(struct iwl_priv *priv) | 84 | int iwl_eeprom_check_version(struct iwl_priv *priv) |
124 | { | 85 | { |
125 | u16 eeprom_ver; | 86 | u16 eeprom_ver; |
126 | u16 calib_ver; | 87 | u16 calib_ver; |
127 | 88 | ||
128 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | 89 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); |
129 | calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv); | 90 | calib_ver = iwlagn_eeprom_calib_version(priv); |
130 | 91 | ||
131 | if (eeprom_ver < priv->cfg->eeprom_ver || | 92 | if (eeprom_ver < priv->cfg->eeprom_ver || |
132 | calib_ver < priv->cfg->eeprom_calib_ver) | 93 | calib_ver < priv->cfg->eeprom_calib_ver) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 861cc93957a9..49dd03f9feda 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | |||
@@ -37,54 +37,6 @@ | |||
37 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
38 | #include "iwl-agn.h" | 38 | #include "iwl-agn.h" |
39 | 39 | ||
40 | int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | ||
41 | struct iwl_rxon_context *ctx) | ||
42 | { | ||
43 | int ret = 0; | ||
44 | struct iwl5000_rxon_assoc_cmd rxon_assoc; | ||
45 | const struct iwl_rxon_cmd *rxon1 = &ctx->staging; | ||
46 | const struct iwl_rxon_cmd *rxon2 = &ctx->active; | ||
47 | |||
48 | if ((rxon1->flags == rxon2->flags) && | ||
49 | (rxon1->filter_flags == rxon2->filter_flags) && | ||
50 | (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && | ||
51 | (rxon1->ofdm_ht_single_stream_basic_rates == | ||
52 | rxon2->ofdm_ht_single_stream_basic_rates) && | ||
53 | (rxon1->ofdm_ht_dual_stream_basic_rates == | ||
54 | rxon2->ofdm_ht_dual_stream_basic_rates) && | ||
55 | (rxon1->ofdm_ht_triple_stream_basic_rates == | ||
56 | rxon2->ofdm_ht_triple_stream_basic_rates) && | ||
57 | (rxon1->acquisition_data == rxon2->acquisition_data) && | ||
58 | (rxon1->rx_chain == rxon2->rx_chain) && | ||
59 | (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { | ||
60 | IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | rxon_assoc.flags = ctx->staging.flags; | ||
65 | rxon_assoc.filter_flags = ctx->staging.filter_flags; | ||
66 | rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; | ||
67 | rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; | ||
68 | rxon_assoc.reserved1 = 0; | ||
69 | rxon_assoc.reserved2 = 0; | ||
70 | rxon_assoc.reserved3 = 0; | ||
71 | rxon_assoc.ofdm_ht_single_stream_basic_rates = | ||
72 | ctx->staging.ofdm_ht_single_stream_basic_rates; | ||
73 | rxon_assoc.ofdm_ht_dual_stream_basic_rates = | ||
74 | ctx->staging.ofdm_ht_dual_stream_basic_rates; | ||
75 | rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; | ||
76 | rxon_assoc.ofdm_ht_triple_stream_basic_rates = | ||
77 | ctx->staging.ofdm_ht_triple_stream_basic_rates; | ||
78 | rxon_assoc.acquisition_data = ctx->staging.acquisition_data; | ||
79 | |||
80 | ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, | ||
81 | sizeof(rxon_assoc), &rxon_assoc, NULL); | ||
82 | if (ret) | ||
83 | return ret; | ||
84 | |||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) | 40 | int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) |
89 | { | 41 | { |
90 | struct iwl_tx_ant_config_cmd tx_ant_cmd = { | 42 | struct iwl_tx_ant_config_cmd tx_ant_cmd = { |
@@ -364,7 +316,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
364 | } | 316 | } |
365 | 317 | ||
366 | struct iwl_hcmd_ops iwlagn_hcmd = { | 318 | struct iwl_hcmd_ops iwlagn_hcmd = { |
367 | .rxon_assoc = iwlagn_send_rxon_assoc, | ||
368 | .commit_rxon = iwlagn_commit_rxon, | 319 | .commit_rxon = iwlagn_commit_rxon, |
369 | .set_rxon_chain = iwlagn_set_rxon_chain, | 320 | .set_rxon_chain = iwlagn_set_rxon_chain, |
370 | .set_tx_ant = iwlagn_send_tx_ant_config, | 321 | .set_tx_ant = iwlagn_send_tx_ant_config, |
@@ -373,7 +324,6 @@ struct iwl_hcmd_ops iwlagn_hcmd = { | |||
373 | }; | 324 | }; |
374 | 325 | ||
375 | struct iwl_hcmd_ops iwlagn_bt_hcmd = { | 326 | struct iwl_hcmd_ops iwlagn_bt_hcmd = { |
376 | .rxon_assoc = iwlagn_send_rxon_assoc, | ||
377 | .commit_rxon = iwlagn_commit_rxon, | 327 | .commit_rxon = iwlagn_commit_rxon, |
378 | .set_rxon_chain = iwlagn_set_rxon_chain, | 328 | .set_rxon_chain = iwlagn_set_rxon_chain, |
379 | .set_tx_ant = iwlagn_send_tx_ant_config, | 329 | .set_tx_ant = iwlagn_send_tx_ant_config, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index e741128842bb..8e79653aed9a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -483,8 +483,6 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv) | |||
483 | /* init calibration handlers */ | 483 | /* init calibration handlers */ |
484 | priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] = | 484 | priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] = |
485 | iwlagn_rx_calib_result; | 485 | iwlagn_rx_calib_result; |
486 | priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] = | ||
487 | iwlagn_rx_calib_complete; | ||
488 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; | 486 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; |
489 | 487 | ||
490 | /* set up notification wait support */ | 488 | /* set up notification wait support */ |
@@ -667,7 +665,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
667 | 665 | ||
668 | rb_timeout = RX_RB_TIMEOUT; | 666 | rb_timeout = RX_RB_TIMEOUT; |
669 | 667 | ||
670 | if (priv->cfg->mod_params->amsdu_size_8K) | 668 | if (iwlagn_mod_params.amsdu_size_8K) |
671 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | 669 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; |
672 | else | 670 | else |
673 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | 671 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; |
@@ -1296,9 +1294,17 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1296 | * mean we never reach it, but at the same time work around | 1294 | * mean we never reach it, but at the same time work around |
1297 | * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER | 1295 | * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER |
1298 | * here instead of IWL_GOOD_CRC_TH_DISABLED. | 1296 | * here instead of IWL_GOOD_CRC_TH_DISABLED. |
1297 | * | ||
1298 | * This was fixed in later versions along with some other | ||
1299 | * scan changes, and the threshold behaves as a flag in those | ||
1300 | * versions. | ||
1299 | */ | 1301 | */ |
1300 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : | 1302 | if (priv->new_scan_threshold_behaviour) |
1301 | IWL_GOOD_CRC_TH_NEVER; | 1303 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : |
1304 | IWL_GOOD_CRC_TH_DISABLED; | ||
1305 | else | ||
1306 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : | ||
1307 | IWL_GOOD_CRC_TH_NEVER; | ||
1302 | 1308 | ||
1303 | band = priv->scan_band; | 1309 | band = priv->scan_band; |
1304 | 1310 | ||
@@ -2256,34 +2262,44 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) | |||
2256 | /* notification wait support */ | 2262 | /* notification wait support */ |
2257 | void iwlagn_init_notification_wait(struct iwl_priv *priv, | 2263 | void iwlagn_init_notification_wait(struct iwl_priv *priv, |
2258 | struct iwl_notification_wait *wait_entry, | 2264 | struct iwl_notification_wait *wait_entry, |
2265 | u8 cmd, | ||
2259 | void (*fn)(struct iwl_priv *priv, | 2266 | void (*fn)(struct iwl_priv *priv, |
2260 | struct iwl_rx_packet *pkt), | 2267 | struct iwl_rx_packet *pkt, |
2261 | u8 cmd) | 2268 | void *data), |
2269 | void *fn_data) | ||
2262 | { | 2270 | { |
2263 | wait_entry->fn = fn; | 2271 | wait_entry->fn = fn; |
2272 | wait_entry->fn_data = fn_data; | ||
2264 | wait_entry->cmd = cmd; | 2273 | wait_entry->cmd = cmd; |
2265 | wait_entry->triggered = false; | 2274 | wait_entry->triggered = false; |
2275 | wait_entry->aborted = false; | ||
2266 | 2276 | ||
2267 | spin_lock_bh(&priv->_agn.notif_wait_lock); | 2277 | spin_lock_bh(&priv->_agn.notif_wait_lock); |
2268 | list_add(&wait_entry->list, &priv->_agn.notif_waits); | 2278 | list_add(&wait_entry->list, &priv->_agn.notif_waits); |
2269 | spin_unlock_bh(&priv->_agn.notif_wait_lock); | 2279 | spin_unlock_bh(&priv->_agn.notif_wait_lock); |
2270 | } | 2280 | } |
2271 | 2281 | ||
2272 | signed long iwlagn_wait_notification(struct iwl_priv *priv, | 2282 | int iwlagn_wait_notification(struct iwl_priv *priv, |
2273 | struct iwl_notification_wait *wait_entry, | 2283 | struct iwl_notification_wait *wait_entry, |
2274 | unsigned long timeout) | 2284 | unsigned long timeout) |
2275 | { | 2285 | { |
2276 | int ret; | 2286 | int ret; |
2277 | 2287 | ||
2278 | ret = wait_event_timeout(priv->_agn.notif_waitq, | 2288 | ret = wait_event_timeout(priv->_agn.notif_waitq, |
2279 | wait_entry->triggered, | 2289 | wait_entry->triggered || wait_entry->aborted, |
2280 | timeout); | 2290 | timeout); |
2281 | 2291 | ||
2282 | spin_lock_bh(&priv->_agn.notif_wait_lock); | 2292 | spin_lock_bh(&priv->_agn.notif_wait_lock); |
2283 | list_del(&wait_entry->list); | 2293 | list_del(&wait_entry->list); |
2284 | spin_unlock_bh(&priv->_agn.notif_wait_lock); | 2294 | spin_unlock_bh(&priv->_agn.notif_wait_lock); |
2285 | 2295 | ||
2286 | return ret; | 2296 | if (wait_entry->aborted) |
2297 | return -EIO; | ||
2298 | |||
2299 | /* return value is always >= 0 */ | ||
2300 | if (ret <= 0) | ||
2301 | return -ETIMEDOUT; | ||
2302 | return 0; | ||
2287 | } | 2303 | } |
2288 | 2304 | ||
2289 | void iwlagn_remove_notification(struct iwl_priv *priv, | 2305 | void iwlagn_remove_notification(struct iwl_priv *priv, |
@@ -2293,3 +2309,87 @@ void iwlagn_remove_notification(struct iwl_priv *priv, | |||
2293 | list_del(&wait_entry->list); | 2309 | list_del(&wait_entry->list); |
2294 | spin_unlock_bh(&priv->_agn.notif_wait_lock); | 2310 | spin_unlock_bh(&priv->_agn.notif_wait_lock); |
2295 | } | 2311 | } |
2312 | |||
2313 | int iwlagn_start_device(struct iwl_priv *priv) | ||
2314 | { | ||
2315 | int ret; | ||
2316 | |||
2317 | if (iwl_prepare_card_hw(priv)) { | ||
2318 | IWL_WARN(priv, "Exit HW not ready\n"); | ||
2319 | return -EIO; | ||
2320 | } | ||
2321 | |||
2322 | /* If platform's RF_KILL switch is NOT set to KILL */ | ||
2323 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | ||
2324 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
2325 | else | ||
2326 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
2327 | |||
2328 | if (iwl_is_rfkill(priv)) { | ||
2329 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); | ||
2330 | iwl_enable_interrupts(priv); | ||
2331 | return -ERFKILL; | ||
2332 | } | ||
2333 | |||
2334 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | ||
2335 | |||
2336 | ret = iwlagn_hw_nic_init(priv); | ||
2337 | if (ret) { | ||
2338 | IWL_ERR(priv, "Unable to init nic\n"); | ||
2339 | return ret; | ||
2340 | } | ||
2341 | |||
2342 | /* make sure rfkill handshake bits are cleared */ | ||
2343 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
2344 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | ||
2345 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||
2346 | |||
2347 | /* clear (again), then enable host interrupts */ | ||
2348 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | ||
2349 | iwl_enable_interrupts(priv); | ||
2350 | |||
2351 | /* really make sure rfkill handshake bits are cleared */ | ||
2352 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
2353 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
2354 | |||
2355 | return 0; | ||
2356 | } | ||
2357 | |||
2358 | void iwlagn_stop_device(struct iwl_priv *priv) | ||
2359 | { | ||
2360 | unsigned long flags; | ||
2361 | |||
2362 | /* stop and reset the on-board processor */ | ||
2363 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
2364 | |||
2365 | /* tell the device to stop sending interrupts */ | ||
2366 | spin_lock_irqsave(&priv->lock, flags); | ||
2367 | iwl_disable_interrupts(priv); | ||
2368 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2369 | iwl_synchronize_irq(priv); | ||
2370 | |||
2371 | /* device going down, Stop using ICT table */ | ||
2372 | iwl_disable_ict(priv); | ||
2373 | |||
2374 | /* | ||
2375 | * If a HW restart happens during firmware loading, | ||
2376 | * then the firmware loading might call this function | ||
2377 | * and later it might be called again due to the | ||
2378 | * restart. So don't process again if the device is | ||
2379 | * already dead. | ||
2380 | */ | ||
2381 | if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) { | ||
2382 | iwlagn_txq_ctx_stop(priv); | ||
2383 | iwlagn_rxq_stop(priv); | ||
2384 | |||
2385 | /* Power-down device's busmaster DMA clocks */ | ||
2386 | iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); | ||
2387 | udelay(5); | ||
2388 | } | ||
2389 | |||
2390 | /* Make sure (redundant) we've released our request to stay awake */ | ||
2391 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
2392 | |||
2393 | /* Stop the device, and put it in low power state */ | ||
2394 | iwl_apm_stop(priv); | ||
2395 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 90e12c17801e..02387430f7fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -58,8 +58,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
58 | u8 old_dev_type = send->dev_type; | 58 | u8 old_dev_type = send->dev_type; |
59 | int ret; | 59 | int ret; |
60 | 60 | ||
61 | iwlagn_init_notification_wait(priv, &disable_wait, NULL, | 61 | iwlagn_init_notification_wait(priv, &disable_wait, |
62 | REPLY_WIPAN_DEACTIVATION_COMPLETE); | 62 | REPLY_WIPAN_DEACTIVATION_COMPLETE, |
63 | NULL, NULL); | ||
63 | 64 | ||
64 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 65 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
65 | send->dev_type = RXON_DEV_TYPE_P2P; | 66 | send->dev_type = RXON_DEV_TYPE_P2P; |
@@ -72,13 +73,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
72 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); | 73 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); |
73 | iwlagn_remove_notification(priv, &disable_wait); | 74 | iwlagn_remove_notification(priv, &disable_wait); |
74 | } else { | 75 | } else { |
75 | signed long wait_res; | 76 | ret = iwlagn_wait_notification(priv, &disable_wait, HZ); |
76 | 77 | if (ret) | |
77 | wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ); | ||
78 | if (wait_res == 0) { | ||
79 | IWL_ERR(priv, "Timed out waiting for PAN disable\n"); | 78 | IWL_ERR(priv, "Timed out waiting for PAN disable\n"); |
80 | ret = -EIO; | ||
81 | } | ||
82 | } | 79 | } |
83 | 80 | ||
84 | return ret; | 81 | return ret; |
@@ -124,6 +121,151 @@ static int iwlagn_update_beacon(struct iwl_priv *priv, | |||
124 | return iwlagn_send_beacon_cmd(priv); | 121 | return iwlagn_send_beacon_cmd(priv); |
125 | } | 122 | } |
126 | 123 | ||
124 | static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | ||
125 | struct iwl_rxon_context *ctx) | ||
126 | { | ||
127 | int ret = 0; | ||
128 | struct iwl_rxon_assoc_cmd rxon_assoc; | ||
129 | const struct iwl_rxon_cmd *rxon1 = &ctx->staging; | ||
130 | const struct iwl_rxon_cmd *rxon2 = &ctx->active; | ||
131 | |||
132 | if ((rxon1->flags == rxon2->flags) && | ||
133 | (rxon1->filter_flags == rxon2->filter_flags) && | ||
134 | (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && | ||
135 | (rxon1->ofdm_ht_single_stream_basic_rates == | ||
136 | rxon2->ofdm_ht_single_stream_basic_rates) && | ||
137 | (rxon1->ofdm_ht_dual_stream_basic_rates == | ||
138 | rxon2->ofdm_ht_dual_stream_basic_rates) && | ||
139 | (rxon1->ofdm_ht_triple_stream_basic_rates == | ||
140 | rxon2->ofdm_ht_triple_stream_basic_rates) && | ||
141 | (rxon1->acquisition_data == rxon2->acquisition_data) && | ||
142 | (rxon1->rx_chain == rxon2->rx_chain) && | ||
143 | (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { | ||
144 | IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | rxon_assoc.flags = ctx->staging.flags; | ||
149 | rxon_assoc.filter_flags = ctx->staging.filter_flags; | ||
150 | rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; | ||
151 | rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; | ||
152 | rxon_assoc.reserved1 = 0; | ||
153 | rxon_assoc.reserved2 = 0; | ||
154 | rxon_assoc.reserved3 = 0; | ||
155 | rxon_assoc.ofdm_ht_single_stream_basic_rates = | ||
156 | ctx->staging.ofdm_ht_single_stream_basic_rates; | ||
157 | rxon_assoc.ofdm_ht_dual_stream_basic_rates = | ||
158 | ctx->staging.ofdm_ht_dual_stream_basic_rates; | ||
159 | rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; | ||
160 | rxon_assoc.ofdm_ht_triple_stream_basic_rates = | ||
161 | ctx->staging.ofdm_ht_triple_stream_basic_rates; | ||
162 | rxon_assoc.acquisition_data = ctx->staging.acquisition_data; | ||
163 | |||
164 | ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, | ||
165 | sizeof(rxon_assoc), &rxon_assoc, NULL); | ||
166 | if (ret) | ||
167 | return ret; | ||
168 | |||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | static int iwlagn_rxon_disconn(struct iwl_priv *priv, | ||
173 | struct iwl_rxon_context *ctx) | ||
174 | { | ||
175 | int ret; | ||
176 | struct iwl_rxon_cmd *active = (void *)&ctx->active; | ||
177 | |||
178 | if (ctx->ctxid == IWL_RXON_CTX_BSS) | ||
179 | ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); | ||
180 | else | ||
181 | ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); | ||
182 | if (ret) | ||
183 | return ret; | ||
184 | |||
185 | /* | ||
186 | * Un-assoc RXON clears the station table and WEP | ||
187 | * keys, so we have to restore those afterwards. | ||
188 | */ | ||
189 | iwl_clear_ucode_stations(priv, ctx); | ||
190 | iwl_restore_stations(priv, ctx); | ||
191 | ret = iwl_restore_default_wep_keys(priv, ctx); | ||
192 | if (ret) { | ||
193 | IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | memcpy(active, &ctx->staging, sizeof(*active)); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static int iwlagn_rxon_connect(struct iwl_priv *priv, | ||
202 | struct iwl_rxon_context *ctx) | ||
203 | { | ||
204 | int ret; | ||
205 | struct iwl_rxon_cmd *active = (void *)&ctx->active; | ||
206 | |||
207 | /* RXON timing must be before associated RXON */ | ||
208 | ret = iwl_send_rxon_timing(priv, ctx); | ||
209 | if (ret) { | ||
210 | IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); | ||
211 | return ret; | ||
212 | } | ||
213 | /* QoS info may be cleared by previous un-assoc RXON */ | ||
214 | iwlagn_update_qos(priv, ctx); | ||
215 | |||
216 | /* | ||
217 | * We'll run into this code path when beaconing is | ||
218 | * enabled, but then we also need to send the beacon | ||
219 | * to the device. | ||
220 | */ | ||
221 | if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) { | ||
222 | ret = iwlagn_update_beacon(priv, ctx->vif); | ||
223 | if (ret) { | ||
224 | IWL_ERR(priv, | ||
225 | "Error sending required beacon (%d)!\n", | ||
226 | ret); | ||
227 | return ret; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | priv->start_calib = 0; | ||
232 | /* | ||
233 | * Apply the new configuration. | ||
234 | * | ||
235 | * Associated RXON doesn't clear the station table in uCode, | ||
236 | * so we don't need to restore stations etc. after this. | ||
237 | */ | ||
238 | ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, | ||
239 | sizeof(struct iwl_rxon_cmd), &ctx->staging); | ||
240 | if (ret) { | ||
241 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); | ||
242 | return ret; | ||
243 | } | ||
244 | memcpy(active, &ctx->staging, sizeof(*active)); | ||
245 | |||
246 | iwl_reprogram_ap_sta(priv, ctx); | ||
247 | |||
248 | /* IBSS beacon needs to be sent after setting assoc */ | ||
249 | if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) | ||
250 | if (iwlagn_update_beacon(priv, ctx->vif)) | ||
251 | IWL_ERR(priv, "Error sending IBSS beacon\n"); | ||
252 | iwl_init_sensitivity(priv); | ||
253 | |||
254 | /* | ||
255 | * If we issue a new RXON command which required a tune then | ||
256 | * we must send a new TXPOWER command or we won't be able to | ||
257 | * Tx any frames. | ||
258 | * | ||
259 | * It's expected we set power here if channel is changing. | ||
260 | */ | ||
261 | ret = iwl_set_tx_power(priv, priv->tx_power_next, true); | ||
262 | if (ret) { | ||
263 | IWL_ERR(priv, "Error sending TX power (%d)\n", ret); | ||
264 | return ret; | ||
265 | } | ||
266 | return 0; | ||
267 | } | ||
268 | |||
127 | /** | 269 | /** |
128 | * iwlagn_commit_rxon - commit staging_rxon to hardware | 270 | * iwlagn_commit_rxon - commit staging_rxon to hardware |
129 | * | 271 | * |
@@ -131,6 +273,16 @@ static int iwlagn_update_beacon(struct iwl_priv *priv, | |||
131 | * the active_rxon structure is updated with the new data. This | 273 | * the active_rxon structure is updated with the new data. This |
132 | * function correctly transitions out of the RXON_ASSOC_MSK state if | 274 | * function correctly transitions out of the RXON_ASSOC_MSK state if |
133 | * a HW tune is required based on the RXON structure changes. | 275 | * a HW tune is required based on the RXON structure changes. |
276 | * | ||
277 | * The connect/disconnect flow should be as the following: | ||
278 | * | ||
279 | * 1. make sure send RXON command with association bit unset if not connect | ||
280 | * this should include the channel and the band for the candidate | ||
281 | * to be connected to | ||
282 | * 2. Add Station before RXON association with the AP | ||
283 | * 3. RXON_timing has to send before RXON for connection | ||
284 | * 4. full RXON command - associated bit set | ||
285 | * 5. use RXON_ASSOC command to update any flags changes | ||
134 | */ | 286 | */ |
135 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | 287 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) |
136 | { | 288 | { |
@@ -180,6 +332,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
180 | else | 332 | else |
181 | ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 333 | ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
182 | 334 | ||
335 | iwl_print_rx_config_cmd(priv, ctx); | ||
183 | ret = iwl_check_rxon_cmd(priv, ctx); | 336 | ret = iwl_check_rxon_cmd(priv, ctx); |
184 | if (ret) { | 337 | if (ret) { |
185 | IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); | 338 | IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); |
@@ -203,14 +356,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
203 | * and other flags for the current radio configuration. | 356 | * and other flags for the current radio configuration. |
204 | */ | 357 | */ |
205 | if (!iwl_full_rxon_required(priv, ctx)) { | 358 | if (!iwl_full_rxon_required(priv, ctx)) { |
206 | ret = iwl_send_rxon_assoc(priv, ctx); | 359 | ret = iwlagn_send_rxon_assoc(priv, ctx); |
207 | if (ret) { | 360 | if (ret) { |
208 | IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); | 361 | IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); |
209 | return ret; | 362 | return ret; |
210 | } | 363 | } |
211 | 364 | ||
212 | memcpy(active, &ctx->staging, sizeof(*active)); | 365 | memcpy(active, &ctx->staging, sizeof(*active)); |
213 | iwl_print_rx_config_cmd(priv, ctx); | ||
214 | return 0; | 366 | return 0; |
215 | } | 367 | } |
216 | 368 | ||
@@ -220,7 +372,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
220 | return ret; | 372 | return ret; |
221 | } | 373 | } |
222 | 374 | ||
223 | iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); | 375 | iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto); |
224 | 376 | ||
225 | IWL_DEBUG_INFO(priv, | 377 | IWL_DEBUG_INFO(priv, |
226 | "Going to commit RXON\n" | 378 | "Going to commit RXON\n" |
@@ -238,92 +390,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
238 | * set up filters in the device. | 390 | * set up filters in the device. |
239 | */ | 391 | */ |
240 | if ((old_assoc && new_assoc) || !new_assoc) { | 392 | if ((old_assoc && new_assoc) || !new_assoc) { |
241 | if (ctx->ctxid == IWL_RXON_CTX_BSS) | 393 | ret = iwlagn_rxon_disconn(priv, ctx); |
242 | ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); | ||
243 | else | ||
244 | ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); | ||
245 | if (ret) | 394 | if (ret) |
246 | return ret; | 395 | return ret; |
247 | |||
248 | memcpy(active, &ctx->staging, sizeof(*active)); | ||
249 | |||
250 | /* | ||
251 | * Un-assoc RXON clears the station table and WEP | ||
252 | * keys, so we have to restore those afterwards. | ||
253 | */ | ||
254 | iwl_clear_ucode_stations(priv, ctx); | ||
255 | iwl_restore_stations(priv, ctx); | ||
256 | ret = iwl_restore_default_wep_keys(priv, ctx); | ||
257 | if (ret) { | ||
258 | IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); | ||
259 | return ret; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | /* RXON timing must be before associated RXON */ | ||
264 | ret = iwl_send_rxon_timing(priv, ctx); | ||
265 | if (ret) { | ||
266 | IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); | ||
267 | return ret; | ||
268 | } | ||
269 | |||
270 | if (new_assoc) { | ||
271 | /* QoS info may be cleared by previous un-assoc RXON */ | ||
272 | iwlagn_update_qos(priv, ctx); | ||
273 | |||
274 | /* | ||
275 | * We'll run into this code path when beaconing is | ||
276 | * enabled, but then we also need to send the beacon | ||
277 | * to the device. | ||
278 | */ | ||
279 | if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) { | ||
280 | ret = iwlagn_update_beacon(priv, ctx->vif); | ||
281 | if (ret) { | ||
282 | IWL_ERR(priv, | ||
283 | "Error sending required beacon (%d)!\n", | ||
284 | ret); | ||
285 | return ret; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | priv->start_calib = 0; | ||
290 | /* | ||
291 | * Apply the new configuration. | ||
292 | * | ||
293 | * Associated RXON doesn't clear the station table in uCode, | ||
294 | * so we don't need to restore stations etc. after this. | ||
295 | */ | ||
296 | ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, | ||
297 | sizeof(struct iwl_rxon_cmd), &ctx->staging); | ||
298 | if (ret) { | ||
299 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); | ||
300 | return ret; | ||
301 | } | ||
302 | memcpy(active, &ctx->staging, sizeof(*active)); | ||
303 | |||
304 | iwl_reprogram_ap_sta(priv, ctx); | ||
305 | |||
306 | /* IBSS beacon needs to be sent after setting assoc */ | ||
307 | if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) | ||
308 | if (iwlagn_update_beacon(priv, ctx->vif)) | ||
309 | IWL_ERR(priv, "Error sending IBSS beacon\n"); | ||
310 | } | 396 | } |
311 | 397 | ||
312 | iwl_print_rx_config_cmd(priv, ctx); | 398 | if (new_assoc) |
313 | 399 | return iwlagn_rxon_connect(priv, ctx); | |
314 | iwl_init_sensitivity(priv); | ||
315 | |||
316 | /* | ||
317 | * If we issue a new RXON command which required a tune then we must | ||
318 | * send a new TXPOWER command or we won't be able to Tx any frames. | ||
319 | * | ||
320 | * It's expected we set power here if channel is changing. | ||
321 | */ | ||
322 | ret = iwl_set_tx_power(priv, priv->tx_power_next, true); | ||
323 | if (ret) { | ||
324 | IWL_ERR(priv, "Error sending TX power (%d)\n", ret); | ||
325 | return ret; | ||
326 | } | ||
327 | 400 | ||
328 | return 0; | 401 | return 0; |
329 | } | 402 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 5c30f6b19a7f..c3ae2e44fcc9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -161,47 +161,19 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, | |||
161 | } | 161 | } |
162 | 162 | ||
163 | static int iwlagn_load_given_ucode(struct iwl_priv *priv, | 163 | static int iwlagn_load_given_ucode(struct iwl_priv *priv, |
164 | struct fw_desc *inst_image, | 164 | struct fw_img *image) |
165 | struct fw_desc *data_image) | ||
166 | { | 165 | { |
167 | int ret = 0; | 166 | int ret = 0; |
168 | 167 | ||
169 | ret = iwlagn_load_section(priv, "INST", inst_image, | 168 | ret = iwlagn_load_section(priv, "INST", &image->code, |
170 | IWLAGN_RTC_INST_LOWER_BOUND); | 169 | IWLAGN_RTC_INST_LOWER_BOUND); |
171 | if (ret) | 170 | if (ret) |
172 | return ret; | 171 | return ret; |
173 | 172 | ||
174 | return iwlagn_load_section(priv, "DATA", data_image, | 173 | return iwlagn_load_section(priv, "DATA", &image->data, |
175 | IWLAGN_RTC_DATA_LOWER_BOUND); | 174 | IWLAGN_RTC_DATA_LOWER_BOUND); |
176 | } | 175 | } |
177 | 176 | ||
178 | int iwlagn_load_ucode(struct iwl_priv *priv) | ||
179 | { | ||
180 | int ret = 0; | ||
181 | |||
182 | /* check whether init ucode should be loaded, or rather runtime ucode */ | ||
183 | if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) { | ||
184 | IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n"); | ||
185 | ret = iwlagn_load_given_ucode(priv, | ||
186 | &priv->ucode_init, &priv->ucode_init_data); | ||
187 | if (!ret) { | ||
188 | IWL_DEBUG_INFO(priv, "Init ucode load complete.\n"); | ||
189 | priv->ucode_type = UCODE_INIT; | ||
190 | } | ||
191 | } else { | ||
192 | IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. " | ||
193 | "Loading runtime ucode...\n"); | ||
194 | ret = iwlagn_load_given_ucode(priv, | ||
195 | &priv->ucode_code, &priv->ucode_data); | ||
196 | if (!ret) { | ||
197 | IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n"); | ||
198 | priv->ucode_type = UCODE_RT; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | /* | 177 | /* |
206 | * Calibration | 178 | * Calibration |
207 | */ | 179 | */ |
@@ -297,33 +269,9 @@ void iwlagn_rx_calib_result(struct iwl_priv *priv, | |||
297 | iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len); | 269 | iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len); |
298 | } | 270 | } |
299 | 271 | ||
300 | void iwlagn_rx_calib_complete(struct iwl_priv *priv, | 272 | static int iwlagn_init_alive_start(struct iwl_priv *priv) |
301 | struct iwl_rx_mem_buffer *rxb) | ||
302 | { | 273 | { |
303 | IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n"); | 274 | int ret; |
304 | queue_work(priv->workqueue, &priv->restart); | ||
305 | } | ||
306 | |||
307 | void iwlagn_init_alive_start(struct iwl_priv *priv) | ||
308 | { | ||
309 | int ret = 0; | ||
310 | |||
311 | /* initialize uCode was loaded... verify inst image. | ||
312 | * This is a paranoid check, because we would not have gotten the | ||
313 | * "initialize" alive if code weren't properly loaded. */ | ||
314 | if (iwl_verify_ucode(priv, &priv->ucode_init)) { | ||
315 | /* Runtime instruction load was bad; | ||
316 | * take it all the way back down so we can try again */ | ||
317 | IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); | ||
318 | goto restart; | ||
319 | } | ||
320 | |||
321 | ret = iwlagn_alive_notify(priv); | ||
322 | if (ret) { | ||
323 | IWL_WARN(priv, | ||
324 | "Could not complete ALIVE transition: %d\n", ret); | ||
325 | goto restart; | ||
326 | } | ||
327 | 275 | ||
328 | if (priv->cfg->bt_params && | 276 | if (priv->cfg->bt_params && |
329 | priv->cfg->bt_params->advanced_bt_coexist) { | 277 | priv->cfg->bt_params->advanced_bt_coexist) { |
@@ -333,24 +281,25 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) | |||
333 | * no need to close the envlope since we are going | 281 | * no need to close the envlope since we are going |
334 | * to load the runtime uCode later. | 282 | * to load the runtime uCode later. |
335 | */ | 283 | */ |
336 | iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, | 284 | ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, |
337 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 285 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
286 | if (ret) | ||
287 | return ret; | ||
338 | 288 | ||
339 | } | 289 | } |
340 | iwlagn_send_calib_cfg(priv); | 290 | |
291 | ret = iwlagn_send_calib_cfg(priv); | ||
292 | if (ret) | ||
293 | return ret; | ||
341 | 294 | ||
342 | /** | 295 | /** |
343 | * temperature offset calibration is only needed for runtime ucode, | 296 | * temperature offset calibration is only needed for runtime ucode, |
344 | * so prepare the value now. | 297 | * so prepare the value now. |
345 | */ | 298 | */ |
346 | if (priv->cfg->need_temp_offset_calib) | 299 | if (priv->cfg->need_temp_offset_calib) |
347 | iwlagn_set_temperature_offset_calib(priv); | 300 | return iwlagn_set_temperature_offset_calib(priv); |
348 | |||
349 | return; | ||
350 | 301 | ||
351 | restart: | 302 | return 0; |
352 | /* real restart (first load init_ucode) */ | ||
353 | queue_work(priv->workqueue, &priv->restart); | ||
354 | } | 303 | } |
355 | 304 | ||
356 | static int iwlagn_send_wimax_coex(struct iwl_priv *priv) | 305 | static int iwlagn_send_wimax_coex(struct iwl_priv *priv) |
@@ -413,19 +362,22 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv) | |||
413 | IWL_ERR(priv, "failed to send BT prio tbl command\n"); | 362 | IWL_ERR(priv, "failed to send BT prio tbl command\n"); |
414 | } | 363 | } |
415 | 364 | ||
416 | void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) | 365 | int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) |
417 | { | 366 | { |
418 | struct iwl_bt_coex_prot_env_cmd env_cmd; | 367 | struct iwl_bt_coex_prot_env_cmd env_cmd; |
368 | int ret; | ||
419 | 369 | ||
420 | env_cmd.action = action; | 370 | env_cmd.action = action; |
421 | env_cmd.type = type; | 371 | env_cmd.type = type; |
422 | if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, | 372 | ret = iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, |
423 | sizeof(env_cmd), &env_cmd)) | 373 | sizeof(env_cmd), &env_cmd); |
374 | if (ret) | ||
424 | IWL_ERR(priv, "failed to send BT env command\n"); | 375 | IWL_ERR(priv, "failed to send BT env command\n"); |
376 | return ret; | ||
425 | } | 377 | } |
426 | 378 | ||
427 | 379 | ||
428 | int iwlagn_alive_notify(struct iwl_priv *priv) | 380 | static int iwlagn_alive_notify(struct iwl_priv *priv) |
429 | { | 381 | { |
430 | const struct queue_to_fifo_ac *queue_to_fifo; | 382 | const struct queue_to_fifo_ac *queue_to_fifo; |
431 | struct iwl_rxon_context *ctx; | 383 | struct iwl_rxon_context *ctx; |
@@ -604,15 +556,164 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, | |||
604 | * iwl_verify_ucode - determine which instruction image is in SRAM, | 556 | * iwl_verify_ucode - determine which instruction image is in SRAM, |
605 | * and verify its contents | 557 | * and verify its contents |
606 | */ | 558 | */ |
607 | int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc) | 559 | static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img) |
608 | { | 560 | { |
609 | if (!iwlcore_verify_inst_sparse(priv, fw_desc)) { | 561 | if (!iwlcore_verify_inst_sparse(priv, &img->code)) { |
610 | IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n"); | 562 | IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n"); |
611 | return 0; | 563 | return 0; |
612 | } | 564 | } |
613 | 565 | ||
614 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | 566 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); |
615 | 567 | ||
616 | iwl_print_mismatch_inst(priv, fw_desc); | 568 | iwl_print_mismatch_inst(priv, &img->code); |
617 | return -EIO; | 569 | return -EIO; |
618 | } | 570 | } |
571 | |||
572 | struct iwlagn_alive_data { | ||
573 | bool valid; | ||
574 | u8 subtype; | ||
575 | }; | ||
576 | |||
577 | static void iwlagn_alive_fn(struct iwl_priv *priv, | ||
578 | struct iwl_rx_packet *pkt, | ||
579 | void *data) | ||
580 | { | ||
581 | struct iwlagn_alive_data *alive_data = data; | ||
582 | struct iwl_alive_resp *palive; | ||
583 | |||
584 | palive = &pkt->u.alive_frame; | ||
585 | |||
586 | IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " | ||
587 | "0x%01X 0x%01X\n", | ||
588 | palive->is_valid, palive->ver_type, | ||
589 | palive->ver_subtype); | ||
590 | |||
591 | priv->device_pointers.error_event_table = | ||
592 | le32_to_cpu(palive->error_event_table_ptr); | ||
593 | priv->device_pointers.log_event_table = | ||
594 | le32_to_cpu(palive->log_event_table_ptr); | ||
595 | |||
596 | alive_data->subtype = palive->ver_subtype; | ||
597 | alive_data->valid = palive->is_valid == UCODE_VALID_OK; | ||
598 | } | ||
599 | |||
600 | #define UCODE_ALIVE_TIMEOUT HZ | ||
601 | #define UCODE_CALIB_TIMEOUT (2*HZ) | ||
602 | |||
603 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | ||
604 | struct fw_img *image, | ||
605 | int subtype, int alternate_subtype) | ||
606 | { | ||
607 | struct iwl_notification_wait alive_wait; | ||
608 | struct iwlagn_alive_data alive_data; | ||
609 | int ret; | ||
610 | enum iwlagn_ucode_subtype old_type; | ||
611 | |||
612 | ret = iwlagn_start_device(priv); | ||
613 | if (ret) | ||
614 | return ret; | ||
615 | |||
616 | iwlagn_init_notification_wait(priv, &alive_wait, REPLY_ALIVE, | ||
617 | iwlagn_alive_fn, &alive_data); | ||
618 | |||
619 | old_type = priv->ucode_type; | ||
620 | priv->ucode_type = subtype; | ||
621 | |||
622 | ret = iwlagn_load_given_ucode(priv, image); | ||
623 | if (ret) { | ||
624 | priv->ucode_type = old_type; | ||
625 | iwlagn_remove_notification(priv, &alive_wait); | ||
626 | return ret; | ||
627 | } | ||
628 | |||
629 | /* Remove all resets to allow NIC to operate */ | ||
630 | iwl_write32(priv, CSR_RESET, 0); | ||
631 | |||
632 | /* | ||
633 | * Some things may run in the background now, but we | ||
634 | * just wait for the ALIVE notification here. | ||
635 | */ | ||
636 | ret = iwlagn_wait_notification(priv, &alive_wait, UCODE_ALIVE_TIMEOUT); | ||
637 | if (ret) { | ||
638 | priv->ucode_type = old_type; | ||
639 | return ret; | ||
640 | } | ||
641 | |||
642 | if (!alive_data.valid) { | ||
643 | IWL_ERR(priv, "Loaded ucode is not valid!\n"); | ||
644 | priv->ucode_type = old_type; | ||
645 | return -EIO; | ||
646 | } | ||
647 | |||
648 | if (alive_data.subtype != subtype && | ||
649 | alive_data.subtype != alternate_subtype) { | ||
650 | IWL_ERR(priv, | ||
651 | "Loaded ucode is not expected type (got %d, expected %d)!\n", | ||
652 | alive_data.subtype, subtype); | ||
653 | priv->ucode_type = old_type; | ||
654 | return -EIO; | ||
655 | } | ||
656 | |||
657 | ret = iwl_verify_ucode(priv, image); | ||
658 | if (ret) { | ||
659 | priv->ucode_type = old_type; | ||
660 | return ret; | ||
661 | } | ||
662 | |||
663 | /* delay a bit to give rfkill time to run */ | ||
664 | msleep(5); | ||
665 | |||
666 | ret = iwlagn_alive_notify(priv); | ||
667 | if (ret) { | ||
668 | IWL_WARN(priv, | ||
669 | "Could not complete ALIVE transition: %d\n", ret); | ||
670 | priv->ucode_type = old_type; | ||
671 | return ret; | ||
672 | } | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | int iwlagn_run_init_ucode(struct iwl_priv *priv) | ||
678 | { | ||
679 | struct iwl_notification_wait calib_wait; | ||
680 | int ret; | ||
681 | |||
682 | lockdep_assert_held(&priv->mutex); | ||
683 | |||
684 | /* No init ucode required? Curious, but maybe ok */ | ||
685 | if (!priv->ucode_init.code.len) | ||
686 | return 0; | ||
687 | |||
688 | if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED) | ||
689 | return 0; | ||
690 | |||
691 | iwlagn_init_notification_wait(priv, &calib_wait, | ||
692 | CALIBRATION_COMPLETE_NOTIFICATION, | ||
693 | NULL, NULL); | ||
694 | |||
695 | /* Will also start the device */ | ||
696 | ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, | ||
697 | UCODE_SUBTYPE_INIT, -1); | ||
698 | if (ret) | ||
699 | goto error; | ||
700 | |||
701 | ret = iwlagn_init_alive_start(priv); | ||
702 | if (ret) | ||
703 | goto error; | ||
704 | |||
705 | /* | ||
706 | * Some things may run in the background now, but we | ||
707 | * just wait for the calibration complete notification. | ||
708 | */ | ||
709 | ret = iwlagn_wait_notification(priv, &calib_wait, UCODE_CALIB_TIMEOUT); | ||
710 | |||
711 | goto out; | ||
712 | |||
713 | error: | ||
714 | iwlagn_remove_notification(priv, &calib_wait); | ||
715 | out: | ||
716 | /* Whatever happened, stop the device */ | ||
717 | iwlagn_stop_device(priv); | ||
718 | return ret; | ||
719 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index cdeb09eee739..003d5243542b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -769,7 +769,7 @@ static void iwl_rx_handle(struct iwl_priv *priv) | |||
769 | if (w->cmd == pkt->hdr.cmd) { | 769 | if (w->cmd == pkt->hdr.cmd) { |
770 | w->triggered = true; | 770 | w->triggered = true; |
771 | if (w->fn) | 771 | if (w->fn) |
772 | w->fn(priv, pkt); | 772 | w->fn(priv, pkt, w->fn_data); |
773 | } | 773 | } |
774 | } | 774 | } |
775 | spin_unlock(&priv->_agn.notif_wait_lock); | 775 | spin_unlock(&priv->_agn.notif_wait_lock); |
@@ -846,14 +846,6 @@ static void iwl_rx_handle(struct iwl_priv *priv) | |||
846 | iwlagn_rx_queue_restock(priv); | 846 | iwlagn_rx_queue_restock(priv); |
847 | } | 847 | } |
848 | 848 | ||
849 | /* call this function to flush any scheduled tasklet */ | ||
850 | static inline void iwl_synchronize_irq(struct iwl_priv *priv) | ||
851 | { | ||
852 | /* wait to make sure we flush pending tasklet*/ | ||
853 | synchronize_irq(priv->pci_dev->irq); | ||
854 | tasklet_kill(&priv->irq_tasklet); | ||
855 | } | ||
856 | |||
857 | /* tasklet for iwlagn interrupt */ | 849 | /* tasklet for iwlagn interrupt */ |
858 | static void iwl_irq_tasklet(struct iwl_priv *priv) | 850 | static void iwl_irq_tasklet(struct iwl_priv *priv) |
859 | { | 851 | { |
@@ -1181,18 +1173,42 @@ static struct attribute_group iwl_attribute_group = { | |||
1181 | * | 1173 | * |
1182 | ******************************************************************************/ | 1174 | ******************************************************************************/ |
1183 | 1175 | ||
1184 | static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) | 1176 | static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) |
1185 | { | 1177 | { |
1186 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); | 1178 | if (desc->v_addr) |
1187 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); | 1179 | dma_free_coherent(&pci_dev->dev, desc->len, |
1188 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init); | 1180 | desc->v_addr, desc->p_addr); |
1189 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); | 1181 | desc->v_addr = NULL; |
1182 | desc->len = 0; | ||
1190 | } | 1183 | } |
1191 | 1184 | ||
1192 | static void iwl_nic_start(struct iwl_priv *priv) | 1185 | static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img) |
1193 | { | 1186 | { |
1194 | /* Remove all resets to allow NIC to operate */ | 1187 | iwl_free_fw_desc(pci_dev, &img->code); |
1195 | iwl_write32(priv, CSR_RESET, 0); | 1188 | iwl_free_fw_desc(pci_dev, &img->data); |
1189 | } | ||
1190 | |||
1191 | static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc, | ||
1192 | const void *data, size_t len) | ||
1193 | { | ||
1194 | if (!len) { | ||
1195 | desc->v_addr = NULL; | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1198 | |||
1199 | desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len, | ||
1200 | &desc->p_addr, GFP_KERNEL); | ||
1201 | if (!desc->v_addr) | ||
1202 | return -ENOMEM; | ||
1203 | desc->len = len; | ||
1204 | memcpy(desc->v_addr, data, len); | ||
1205 | return 0; | ||
1206 | } | ||
1207 | |||
1208 | static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) | ||
1209 | { | ||
1210 | iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt); | ||
1211 | iwl_free_fw_img(priv->pci_dev, &priv->ucode_init); | ||
1196 | } | 1212 | } |
1197 | 1213 | ||
1198 | struct iwlagn_ucode_capabilities { | 1214 | struct iwlagn_ucode_capabilities { |
@@ -1661,24 +1677,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1661 | /* Runtime instructions and 2 copies of data: | 1677 | /* Runtime instructions and 2 copies of data: |
1662 | * 1) unmodified from disk | 1678 | * 1) unmodified from disk |
1663 | * 2) backup cache for save/restore during power-downs */ | 1679 | * 2) backup cache for save/restore during power-downs */ |
1664 | priv->ucode_code.len = pieces.inst_size; | 1680 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code, |
1665 | iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); | 1681 | pieces.inst, pieces.inst_size)) |
1666 | 1682 | goto err_pci_alloc; | |
1667 | priv->ucode_data.len = pieces.data_size; | 1683 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data, |
1668 | iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); | 1684 | pieces.data, pieces.data_size)) |
1669 | |||
1670 | if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr) | ||
1671 | goto err_pci_alloc; | 1685 | goto err_pci_alloc; |
1672 | 1686 | ||
1673 | /* Initialization instructions and data */ | 1687 | /* Initialization instructions and data */ |
1674 | if (pieces.init_size && pieces.init_data_size) { | 1688 | if (pieces.init_size && pieces.init_data_size) { |
1675 | priv->ucode_init.len = pieces.init_size; | 1689 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code, |
1676 | iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); | 1690 | pieces.init, pieces.init_size)) |
1677 | 1691 | goto err_pci_alloc; | |
1678 | priv->ucode_init_data.len = pieces.init_data_size; | 1692 | if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data, |
1679 | iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); | 1693 | pieces.init_data, pieces.init_data_size)) |
1680 | |||
1681 | if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) | ||
1682 | goto err_pci_alloc; | 1694 | goto err_pci_alloc; |
1683 | } | 1695 | } |
1684 | 1696 | ||
@@ -1704,6 +1716,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1704 | priv->cfg->base_params->max_event_log_size; | 1716 | priv->cfg->base_params->max_event_log_size; |
1705 | priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; | 1717 | priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; |
1706 | 1718 | ||
1719 | priv->new_scan_threshold_behaviour = | ||
1720 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | ||
1721 | |||
1707 | if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { | 1722 | if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { |
1708 | priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); | 1723 | priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); |
1709 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | 1724 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; |
@@ -1715,39 +1730,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1715 | else | 1730 | else |
1716 | priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | 1731 | priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; |
1717 | 1732 | ||
1718 | /* Copy images into buffers for card's bus-master reads ... */ | ||
1719 | |||
1720 | /* Runtime instructions (first block of data in file) */ | ||
1721 | IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", | ||
1722 | pieces.inst_size); | ||
1723 | memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size); | ||
1724 | |||
1725 | IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", | ||
1726 | priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); | ||
1727 | |||
1728 | /* | ||
1729 | * Runtime data | ||
1730 | * NOTE: Copy into backup buffer will be done in iwl_up() | ||
1731 | */ | ||
1732 | IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", | ||
1733 | pieces.data_size); | ||
1734 | memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size); | ||
1735 | |||
1736 | /* Initialization instructions */ | ||
1737 | if (pieces.init_size) { | ||
1738 | IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n", | ||
1739 | pieces.init_size); | ||
1740 | memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size); | ||
1741 | } | ||
1742 | |||
1743 | /* Initialization data */ | ||
1744 | if (pieces.init_data_size) { | ||
1745 | IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n", | ||
1746 | pieces.init_data_size); | ||
1747 | memcpy(priv->ucode_init_data.v_addr, pieces.init_data, | ||
1748 | pieces.init_data_size); | ||
1749 | } | ||
1750 | |||
1751 | /* | 1733 | /* |
1752 | * figure out the offset of chain noise reset and gain commands | 1734 | * figure out the offset of chain noise reset and gain commands |
1753 | * base on the size of standard phy calibration commands table size | 1735 | * base on the size of standard phy calibration commands table size |
@@ -1878,9 +1860,10 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1878 | u32 desc, time, count, base, data1; | 1860 | u32 desc, time, count, base, data1; |
1879 | u32 blink1, blink2, ilink1, ilink2; | 1861 | u32 blink1, blink2, ilink1, ilink2; |
1880 | u32 pc, hcmd; | 1862 | u32 pc, hcmd; |
1863 | struct iwl_error_event_table table; | ||
1881 | 1864 | ||
1882 | base = priv->device_pointers.error_event_table; | 1865 | base = priv->device_pointers.error_event_table; |
1883 | if (priv->ucode_type == UCODE_INIT) { | 1866 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) { |
1884 | if (!base) | 1867 | if (!base) |
1885 | base = priv->_agn.init_errlog_ptr; | 1868 | base = priv->_agn.init_errlog_ptr; |
1886 | } else { | 1869 | } else { |
@@ -1891,11 +1874,15 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1891 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | 1874 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
1892 | IWL_ERR(priv, | 1875 | IWL_ERR(priv, |
1893 | "Not valid error log pointer 0x%08X for %s uCode\n", | 1876 | "Not valid error log pointer 0x%08X for %s uCode\n", |
1894 | base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | 1877 | base, |
1878 | (priv->ucode_type == UCODE_SUBTYPE_INIT) | ||
1879 | ? "Init" : "RT"); | ||
1895 | return; | 1880 | return; |
1896 | } | 1881 | } |
1897 | 1882 | ||
1898 | count = iwl_read_targ_mem(priv, base); | 1883 | iwl_read_targ_mem_words(priv, base, &table, sizeof(table)); |
1884 | |||
1885 | count = table.valid; | ||
1899 | 1886 | ||
1900 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { | 1887 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { |
1901 | IWL_ERR(priv, "Start IWL Error Log Dump:\n"); | 1888 | IWL_ERR(priv, "Start IWL Error Log Dump:\n"); |
@@ -1903,18 +1890,18 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1903 | priv->status, count); | 1890 | priv->status, count); |
1904 | } | 1891 | } |
1905 | 1892 | ||
1906 | desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32)); | 1893 | desc = table.error_id; |
1907 | priv->isr_stats.err_code = desc; | 1894 | priv->isr_stats.err_code = desc; |
1908 | pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32)); | 1895 | pc = table.pc; |
1909 | blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32)); | 1896 | blink1 = table.blink1; |
1910 | blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32)); | 1897 | blink2 = table.blink2; |
1911 | ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32)); | 1898 | ilink1 = table.ilink1; |
1912 | ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32)); | 1899 | ilink2 = table.ilink2; |
1913 | data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32)); | 1900 | data1 = table.data1; |
1914 | data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32)); | 1901 | data2 = table.data2; |
1915 | line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32)); | 1902 | line = table.line; |
1916 | time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32)); | 1903 | time = table.tsf_low; |
1917 | hcmd = iwl_read_targ_mem(priv, base + 22 * sizeof(u32)); | 1904 | hcmd = table.hcmd; |
1918 | 1905 | ||
1919 | trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, | 1906 | trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, |
1920 | blink1, blink2, ilink1, ilink2); | 1907 | blink1, blink2, ilink1, ilink2); |
@@ -1949,7 +1936,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1949 | return pos; | 1936 | return pos; |
1950 | 1937 | ||
1951 | base = priv->device_pointers.log_event_table; | 1938 | base = priv->device_pointers.log_event_table; |
1952 | if (priv->ucode_type == UCODE_INIT) { | 1939 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) { |
1953 | if (!base) | 1940 | if (!base) |
1954 | base = priv->_agn.init_evtlog_ptr; | 1941 | base = priv->_agn.init_evtlog_ptr; |
1955 | } else { | 1942 | } else { |
@@ -2062,7 +2049,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
2062 | size_t bufsz = 0; | 2049 | size_t bufsz = 0; |
2063 | 2050 | ||
2064 | base = priv->device_pointers.log_event_table; | 2051 | base = priv->device_pointers.log_event_table; |
2065 | if (priv->ucode_type == UCODE_INIT) { | 2052 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) { |
2066 | logsize = priv->_agn.init_evtlog_size; | 2053 | logsize = priv->_agn.init_evtlog_size; |
2067 | if (!base) | 2054 | if (!base) |
2068 | base = priv->_agn.init_evtlog_ptr; | 2055 | base = priv->_agn.init_evtlog_ptr; |
@@ -2075,7 +2062,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
2075 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | 2062 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
2076 | IWL_ERR(priv, | 2063 | IWL_ERR(priv, |
2077 | "Invalid event log pointer 0x%08X for %s uCode\n", | 2064 | "Invalid event log pointer 0x%08X for %s uCode\n", |
2078 | base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | 2065 | base, |
2066 | (priv->ucode_type == UCODE_SUBTYPE_INIT) | ||
2067 | ? "Init" : "RT"); | ||
2079 | return -EINVAL; | 2068 | return -EINVAL; |
2080 | } | 2069 | } |
2081 | 2070 | ||
@@ -2222,30 +2211,14 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) | |||
2222 | * from protocol/runtime uCode (initialization uCode's | 2211 | * from protocol/runtime uCode (initialization uCode's |
2223 | * Alive gets handled by iwl_init_alive_start()). | 2212 | * Alive gets handled by iwl_init_alive_start()). |
2224 | */ | 2213 | */ |
2225 | static void iwl_alive_start(struct iwl_priv *priv) | 2214 | static int iwl_alive_start(struct iwl_priv *priv) |
2226 | { | 2215 | { |
2227 | int ret = 0; | 2216 | int ret = 0; |
2228 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 2217 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
2229 | 2218 | ||
2230 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | 2219 | iwl_reset_ict(priv); |
2231 | |||
2232 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. | ||
2233 | * This is a paranoid check, because we would not have gotten the | ||
2234 | * "runtime" alive if code weren't properly loaded. */ | ||
2235 | if (iwl_verify_ucode(priv, &priv->ucode_code)) { | ||
2236 | /* Runtime instruction load was bad; | ||
2237 | * take it all the way back down so we can try again */ | ||
2238 | IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); | ||
2239 | goto restart; | ||
2240 | } | ||
2241 | |||
2242 | ret = iwlagn_alive_notify(priv); | ||
2243 | if (ret) { | ||
2244 | IWL_WARN(priv, | ||
2245 | "Could not complete ALIVE transition [ntf]: %d\n", ret); | ||
2246 | goto restart; | ||
2247 | } | ||
2248 | 2220 | ||
2221 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | ||
2249 | 2222 | ||
2250 | /* After the ALIVE response, we can send host commands to the uCode */ | 2223 | /* After the ALIVE response, we can send host commands to the uCode */ |
2251 | set_bit(STATUS_ALIVE, &priv->status); | 2224 | set_bit(STATUS_ALIVE, &priv->status); |
@@ -2254,7 +2227,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2254 | iwl_setup_watchdog(priv); | 2227 | iwl_setup_watchdog(priv); |
2255 | 2228 | ||
2256 | if (iwl_is_rfkill(priv)) | 2229 | if (iwl_is_rfkill(priv)) |
2257 | return; | 2230 | return -ERFKILL; |
2258 | 2231 | ||
2259 | /* download priority table before any calibration request */ | 2232 | /* download priority table before any calibration request */ |
2260 | if (priv->cfg->bt_params && | 2233 | if (priv->cfg->bt_params && |
@@ -2268,10 +2241,14 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2268 | iwlagn_send_prio_tbl(priv); | 2241 | iwlagn_send_prio_tbl(priv); |
2269 | 2242 | ||
2270 | /* FIXME: w/a to force change uCode BT state machine */ | 2243 | /* FIXME: w/a to force change uCode BT state machine */ |
2271 | iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, | 2244 | ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, |
2272 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 2245 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
2273 | iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, | 2246 | if (ret) |
2274 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 2247 | return ret; |
2248 | ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, | ||
2249 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | ||
2250 | if (ret) | ||
2251 | return ret; | ||
2275 | } | 2252 | } |
2276 | if (priv->hw_params.calib_rt_cfg) | 2253 | if (priv->hw_params.calib_rt_cfg) |
2277 | iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); | 2254 | iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); |
@@ -2313,29 +2290,22 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2313 | set_bit(STATUS_READY, &priv->status); | 2290 | set_bit(STATUS_READY, &priv->status); |
2314 | 2291 | ||
2315 | /* Configure the adapter for unassociated operation */ | 2292 | /* Configure the adapter for unassociated operation */ |
2316 | iwlcore_commit_rxon(priv, ctx); | 2293 | ret = iwlcore_commit_rxon(priv, ctx); |
2294 | if (ret) | ||
2295 | return ret; | ||
2317 | 2296 | ||
2318 | /* At this point, the NIC is initialized and operational */ | 2297 | /* At this point, the NIC is initialized and operational */ |
2319 | iwl_rf_kill_ct_config(priv); | 2298 | iwl_rf_kill_ct_config(priv); |
2320 | 2299 | ||
2321 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); | 2300 | IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); |
2322 | wake_up_interruptible(&priv->wait_command_queue); | ||
2323 | |||
2324 | iwl_power_update_mode(priv, true); | ||
2325 | IWL_DEBUG_INFO(priv, "Updated power mode\n"); | ||
2326 | 2301 | ||
2327 | 2302 | return iwl_power_update_mode(priv, true); | |
2328 | return; | ||
2329 | |||
2330 | restart: | ||
2331 | queue_work(priv->workqueue, &priv->restart); | ||
2332 | } | 2303 | } |
2333 | 2304 | ||
2334 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); | 2305 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); |
2335 | 2306 | ||
2336 | static void __iwl_down(struct iwl_priv *priv) | 2307 | static void __iwl_down(struct iwl_priv *priv) |
2337 | { | 2308 | { |
2338 | unsigned long flags; | ||
2339 | int exit_pending; | 2309 | int exit_pending; |
2340 | 2310 | ||
2341 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); | 2311 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); |
@@ -2367,32 +2337,10 @@ static void __iwl_down(struct iwl_priv *priv) | |||
2367 | if (!exit_pending) | 2337 | if (!exit_pending) |
2368 | clear_bit(STATUS_EXIT_PENDING, &priv->status); | 2338 | clear_bit(STATUS_EXIT_PENDING, &priv->status); |
2369 | 2339 | ||
2370 | /* stop and reset the on-board processor */ | ||
2371 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
2372 | |||
2373 | /* tell the device to stop sending interrupts */ | ||
2374 | spin_lock_irqsave(&priv->lock, flags); | ||
2375 | iwl_disable_interrupts(priv); | ||
2376 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2377 | iwl_synchronize_irq(priv); | ||
2378 | |||
2379 | if (priv->mac80211_registered) | 2340 | if (priv->mac80211_registered) |
2380 | ieee80211_stop_queues(priv->hw); | 2341 | ieee80211_stop_queues(priv->hw); |
2381 | 2342 | ||
2382 | /* If we have not previously called iwl_init() then | 2343 | /* Clear out all status bits but a few that are stable across reset */ |
2383 | * clear all bits but the RF Kill bit and return */ | ||
2384 | if (!iwl_is_init(priv)) { | ||
2385 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | ||
2386 | STATUS_RF_KILL_HW | | ||
2387 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | ||
2388 | STATUS_GEO_CONFIGURED | | ||
2389 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
2390 | STATUS_EXIT_PENDING; | ||
2391 | goto exit; | ||
2392 | } | ||
2393 | |||
2394 | /* ...otherwise clear out all the status bits but the RF Kill | ||
2395 | * bit and continue taking the NIC down. */ | ||
2396 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 2344 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
2397 | STATUS_RF_KILL_HW | | 2345 | STATUS_RF_KILL_HW | |
2398 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2346 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
@@ -2402,23 +2350,8 @@ static void __iwl_down(struct iwl_priv *priv) | |||
2402 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 2350 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
2403 | STATUS_EXIT_PENDING; | 2351 | STATUS_EXIT_PENDING; |
2404 | 2352 | ||
2405 | /* device going down, Stop using ICT table */ | 2353 | iwlagn_stop_device(priv); |
2406 | iwl_disable_ict(priv); | ||
2407 | |||
2408 | iwlagn_txq_ctx_stop(priv); | ||
2409 | iwlagn_rxq_stop(priv); | ||
2410 | |||
2411 | /* Power-down device's busmaster DMA clocks */ | ||
2412 | iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); | ||
2413 | udelay(5); | ||
2414 | |||
2415 | /* Make sure (redundant) we've released our request to stay awake */ | ||
2416 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
2417 | |||
2418 | /* Stop the device, and put it in low power state */ | ||
2419 | iwl_apm_stop(priv); | ||
2420 | 2354 | ||
2421 | exit: | ||
2422 | dev_kfree_skb(priv->beacon_skb); | 2355 | dev_kfree_skb(priv->beacon_skb); |
2423 | priv->beacon_skb = NULL; | 2356 | priv->beacon_skb = NULL; |
2424 | 2357 | ||
@@ -2437,9 +2370,10 @@ static void iwl_down(struct iwl_priv *priv) | |||
2437 | 2370 | ||
2438 | #define HW_READY_TIMEOUT (50) | 2371 | #define HW_READY_TIMEOUT (50) |
2439 | 2372 | ||
2373 | /* Note: returns poll_bit return value, which is >= 0 if success */ | ||
2440 | static int iwl_set_hw_ready(struct iwl_priv *priv) | 2374 | static int iwl_set_hw_ready(struct iwl_priv *priv) |
2441 | { | 2375 | { |
2442 | int ret = 0; | 2376 | int ret; |
2443 | 2377 | ||
2444 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 2378 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
2445 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); | 2379 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); |
@@ -2449,25 +2383,21 @@ static int iwl_set_hw_ready(struct iwl_priv *priv) | |||
2449 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | 2383 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, |
2450 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | 2384 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, |
2451 | HW_READY_TIMEOUT); | 2385 | HW_READY_TIMEOUT); |
2452 | if (ret != -ETIMEDOUT) | ||
2453 | priv->hw_ready = true; | ||
2454 | else | ||
2455 | priv->hw_ready = false; | ||
2456 | 2386 | ||
2457 | IWL_DEBUG_INFO(priv, "hardware %s\n", | 2387 | IWL_DEBUG_INFO(priv, "hardware%s ready\n", ret < 0 ? " not" : ""); |
2458 | (priv->hw_ready == 1) ? "ready" : "not ready"); | ||
2459 | return ret; | 2388 | return ret; |
2460 | } | 2389 | } |
2461 | 2390 | ||
2462 | static int iwl_prepare_card_hw(struct iwl_priv *priv) | 2391 | /* Note: returns standard 0/-ERROR code */ |
2392 | int iwl_prepare_card_hw(struct iwl_priv *priv) | ||
2463 | { | 2393 | { |
2464 | int ret = 0; | 2394 | int ret; |
2465 | 2395 | ||
2466 | IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n"); | 2396 | IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n"); |
2467 | 2397 | ||
2468 | ret = iwl_set_hw_ready(priv); | 2398 | ret = iwl_set_hw_ready(priv); |
2469 | if (priv->hw_ready) | 2399 | if (ret >= 0) |
2470 | return ret; | 2400 | return 0; |
2471 | 2401 | ||
2472 | /* If HW is not ready, prepare the conditions to check again */ | 2402 | /* If HW is not ready, prepare the conditions to check again */ |
2473 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 2403 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
@@ -2477,10 +2407,13 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv) | |||
2477 | ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, | 2407 | ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, |
2478 | CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); | 2408 | CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); |
2479 | 2409 | ||
2480 | /* HW should be ready by now, check again. */ | 2410 | if (ret < 0) |
2481 | if (ret != -ETIMEDOUT) | 2411 | return ret; |
2482 | iwl_set_hw_ready(priv); | ||
2483 | 2412 | ||
2413 | /* HW should be ready by now, check again. */ | ||
2414 | ret = iwl_set_hw_ready(priv); | ||
2415 | if (ret >= 0) | ||
2416 | return 0; | ||
2484 | return ret; | 2417 | return ret; |
2485 | } | 2418 | } |
2486 | 2419 | ||
@@ -2489,9 +2422,10 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv) | |||
2489 | static int __iwl_up(struct iwl_priv *priv) | 2422 | static int __iwl_up(struct iwl_priv *priv) |
2490 | { | 2423 | { |
2491 | struct iwl_rxon_context *ctx; | 2424 | struct iwl_rxon_context *ctx; |
2492 | int i; | ||
2493 | int ret; | 2425 | int ret; |
2494 | 2426 | ||
2427 | lockdep_assert_held(&priv->mutex); | ||
2428 | |||
2495 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 2429 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
2496 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | 2430 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); |
2497 | return -EIO; | 2431 | return -EIO; |
@@ -2505,77 +2439,33 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2505 | } | 2439 | } |
2506 | } | 2440 | } |
2507 | 2441 | ||
2508 | iwl_prepare_card_hw(priv); | 2442 | ret = iwlagn_run_init_ucode(priv); |
2509 | 2443 | if (ret) { | |
2510 | if (!priv->hw_ready) { | 2444 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); |
2511 | IWL_WARN(priv, "Exit HW not ready\n"); | 2445 | goto error; |
2512 | return -EIO; | ||
2513 | } | ||
2514 | |||
2515 | /* If platform's RF_KILL switch is NOT set to KILL */ | ||
2516 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | ||
2517 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
2518 | else | ||
2519 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
2520 | |||
2521 | if (iwl_is_rfkill(priv)) { | ||
2522 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); | ||
2523 | |||
2524 | iwl_enable_interrupts(priv); | ||
2525 | IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); | ||
2526 | return 0; | ||
2527 | } | 2446 | } |
2528 | 2447 | ||
2529 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | 2448 | ret = iwlagn_load_ucode_wait_alive(priv, |
2530 | 2449 | &priv->ucode_rt, | |
2531 | ret = iwlagn_hw_nic_init(priv); | 2450 | UCODE_SUBTYPE_REGULAR, |
2451 | UCODE_SUBTYPE_REGULAR_NEW); | ||
2532 | if (ret) { | 2452 | if (ret) { |
2533 | IWL_ERR(priv, "Unable to init nic\n"); | 2453 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); |
2534 | return ret; | 2454 | goto error; |
2535 | } | 2455 | } |
2536 | 2456 | ||
2537 | /* make sure rfkill handshake bits are cleared */ | 2457 | ret = iwl_alive_start(priv); |
2538 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 2458 | if (ret) |
2539 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | 2459 | goto error; |
2540 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 2460 | return 0; |
2541 | |||
2542 | /* clear (again), then enable host interrupts */ | ||
2543 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | ||
2544 | iwl_enable_interrupts(priv); | ||
2545 | |||
2546 | /* really make sure rfkill handshake bits are cleared */ | ||
2547 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
2548 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
2549 | |||
2550 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | ||
2551 | |||
2552 | /* load bootstrap state machine, | ||
2553 | * load bootstrap program into processor's memory, | ||
2554 | * prepare to load the "initialize" uCode */ | ||
2555 | ret = iwlagn_load_ucode(priv); | ||
2556 | |||
2557 | if (ret) { | ||
2558 | IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n", | ||
2559 | ret); | ||
2560 | continue; | ||
2561 | } | ||
2562 | |||
2563 | /* start card; "initialize" will load runtime ucode */ | ||
2564 | iwl_nic_start(priv); | ||
2565 | |||
2566 | IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); | ||
2567 | |||
2568 | return 0; | ||
2569 | } | ||
2570 | 2461 | ||
2462 | error: | ||
2571 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2463 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
2572 | __iwl_down(priv); | 2464 | __iwl_down(priv); |
2573 | clear_bit(STATUS_EXIT_PENDING, &priv->status); | 2465 | clear_bit(STATUS_EXIT_PENDING, &priv->status); |
2574 | 2466 | ||
2575 | /* tried to restart and config the device for as long as our | 2467 | IWL_ERR(priv, "Unable to initialize device.\n"); |
2576 | * patience could withstand */ | 2468 | return ret; |
2577 | IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); | ||
2578 | return -EIO; | ||
2579 | } | 2469 | } |
2580 | 2470 | ||
2581 | 2471 | ||
@@ -2585,39 +2475,6 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2585 | * | 2475 | * |
2586 | *****************************************************************************/ | 2476 | *****************************************************************************/ |
2587 | 2477 | ||
2588 | static void iwl_bg_init_alive_start(struct work_struct *data) | ||
2589 | { | ||
2590 | struct iwl_priv *priv = | ||
2591 | container_of(data, struct iwl_priv, init_alive_start.work); | ||
2592 | |||
2593 | mutex_lock(&priv->mutex); | ||
2594 | |||
2595 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
2596 | mutex_unlock(&priv->mutex); | ||
2597 | return; | ||
2598 | } | ||
2599 | |||
2600 | iwlagn_init_alive_start(priv); | ||
2601 | mutex_unlock(&priv->mutex); | ||
2602 | } | ||
2603 | |||
2604 | static void iwl_bg_alive_start(struct work_struct *data) | ||
2605 | { | ||
2606 | struct iwl_priv *priv = | ||
2607 | container_of(data, struct iwl_priv, alive_start.work); | ||
2608 | |||
2609 | mutex_lock(&priv->mutex); | ||
2610 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2611 | goto unlock; | ||
2612 | |||
2613 | /* enable dram interrupt */ | ||
2614 | iwl_reset_ict(priv); | ||
2615 | |||
2616 | iwl_alive_start(priv); | ||
2617 | unlock: | ||
2618 | mutex_unlock(&priv->mutex); | ||
2619 | } | ||
2620 | |||
2621 | static void iwl_bg_run_time_calib_work(struct work_struct *work) | 2478 | static void iwl_bg_run_time_calib_work(struct work_struct *work) |
2622 | { | 2479 | { |
2623 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 2480 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
@@ -2639,6 +2496,42 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
2639 | mutex_unlock(&priv->mutex); | 2496 | mutex_unlock(&priv->mutex); |
2640 | } | 2497 | } |
2641 | 2498 | ||
2499 | static void iwlagn_prepare_restart(struct iwl_priv *priv) | ||
2500 | { | ||
2501 | struct iwl_rxon_context *ctx; | ||
2502 | bool bt_full_concurrent; | ||
2503 | u8 bt_ci_compliance; | ||
2504 | u8 bt_load; | ||
2505 | u8 bt_status; | ||
2506 | |||
2507 | lockdep_assert_held(&priv->mutex); | ||
2508 | |||
2509 | for_each_context(priv, ctx) | ||
2510 | ctx->vif = NULL; | ||
2511 | priv->is_open = 0; | ||
2512 | |||
2513 | /* | ||
2514 | * __iwl_down() will clear the BT status variables, | ||
2515 | * which is correct, but when we restart we really | ||
2516 | * want to keep them so restore them afterwards. | ||
2517 | * | ||
2518 | * The restart process will later pick them up and | ||
2519 | * re-configure the hw when we reconfigure the BT | ||
2520 | * command. | ||
2521 | */ | ||
2522 | bt_full_concurrent = priv->bt_full_concurrent; | ||
2523 | bt_ci_compliance = priv->bt_ci_compliance; | ||
2524 | bt_load = priv->bt_traffic_load; | ||
2525 | bt_status = priv->bt_status; | ||
2526 | |||
2527 | __iwl_down(priv); | ||
2528 | |||
2529 | priv->bt_full_concurrent = bt_full_concurrent; | ||
2530 | priv->bt_ci_compliance = bt_ci_compliance; | ||
2531 | priv->bt_traffic_load = bt_load; | ||
2532 | priv->bt_status = bt_status; | ||
2533 | } | ||
2534 | |||
2642 | static void iwl_bg_restart(struct work_struct *data) | 2535 | static void iwl_bg_restart(struct work_struct *data) |
2643 | { | 2536 | { |
2644 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); | 2537 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); |
@@ -2647,50 +2540,13 @@ static void iwl_bg_restart(struct work_struct *data) | |||
2647 | return; | 2540 | return; |
2648 | 2541 | ||
2649 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { | 2542 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { |
2650 | struct iwl_rxon_context *ctx; | ||
2651 | bool bt_full_concurrent; | ||
2652 | u8 bt_ci_compliance; | ||
2653 | u8 bt_load; | ||
2654 | u8 bt_status; | ||
2655 | |||
2656 | mutex_lock(&priv->mutex); | 2543 | mutex_lock(&priv->mutex); |
2657 | for_each_context(priv, ctx) | 2544 | iwlagn_prepare_restart(priv); |
2658 | ctx->vif = NULL; | ||
2659 | priv->is_open = 0; | ||
2660 | |||
2661 | /* | ||
2662 | * __iwl_down() will clear the BT status variables, | ||
2663 | * which is correct, but when we restart we really | ||
2664 | * want to keep them so restore them afterwards. | ||
2665 | * | ||
2666 | * The restart process will later pick them up and | ||
2667 | * re-configure the hw when we reconfigure the BT | ||
2668 | * command. | ||
2669 | */ | ||
2670 | bt_full_concurrent = priv->bt_full_concurrent; | ||
2671 | bt_ci_compliance = priv->bt_ci_compliance; | ||
2672 | bt_load = priv->bt_traffic_load; | ||
2673 | bt_status = priv->bt_status; | ||
2674 | |||
2675 | __iwl_down(priv); | ||
2676 | |||
2677 | priv->bt_full_concurrent = bt_full_concurrent; | ||
2678 | priv->bt_ci_compliance = bt_ci_compliance; | ||
2679 | priv->bt_traffic_load = bt_load; | ||
2680 | priv->bt_status = bt_status; | ||
2681 | |||
2682 | mutex_unlock(&priv->mutex); | 2545 | mutex_unlock(&priv->mutex); |
2683 | iwl_cancel_deferred_work(priv); | 2546 | iwl_cancel_deferred_work(priv); |
2684 | ieee80211_restart_hw(priv->hw); | 2547 | ieee80211_restart_hw(priv->hw); |
2685 | } else { | 2548 | } else { |
2686 | iwl_down(priv); | 2549 | WARN_ON(1); |
2687 | |||
2688 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2689 | return; | ||
2690 | |||
2691 | mutex_lock(&priv->mutex); | ||
2692 | __iwl_up(priv); | ||
2693 | mutex_unlock(&priv->mutex); | ||
2694 | } | 2550 | } |
2695 | } | 2551 | } |
2696 | 2552 | ||
@@ -2801,8 +2657,6 @@ unlock: | |||
2801 | * | 2657 | * |
2802 | *****************************************************************************/ | 2658 | *****************************************************************************/ |
2803 | 2659 | ||
2804 | #define UCODE_READY_TIMEOUT (4 * HZ) | ||
2805 | |||
2806 | /* | 2660 | /* |
2807 | * Not a mac80211 entry point function, but it fits in with all the | 2661 | * Not a mac80211 entry point function, but it fits in with all the |
2808 | * other mac80211 functions grouped here. | 2662 | * other mac80211 functions grouped here. |
@@ -2895,31 +2749,17 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
2895 | mutex_lock(&priv->mutex); | 2749 | mutex_lock(&priv->mutex); |
2896 | ret = __iwl_up(priv); | 2750 | ret = __iwl_up(priv); |
2897 | mutex_unlock(&priv->mutex); | 2751 | mutex_unlock(&priv->mutex); |
2898 | |||
2899 | if (ret) | 2752 | if (ret) |
2900 | return ret; | 2753 | return ret; |
2901 | 2754 | ||
2902 | if (iwl_is_rfkill(priv)) | ||
2903 | goto out; | ||
2904 | |||
2905 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | 2755 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); |
2906 | 2756 | ||
2907 | /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from | 2757 | /* Now we should be done, and the READY bit should be set. */ |
2908 | * mac80211 will not be run successfully. */ | 2758 | if (WARN_ON(!test_bit(STATUS_READY, &priv->status))) |
2909 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 2759 | ret = -EIO; |
2910 | test_bit(STATUS_READY, &priv->status), | ||
2911 | UCODE_READY_TIMEOUT); | ||
2912 | if (!ret) { | ||
2913 | if (!test_bit(STATUS_READY, &priv->status)) { | ||
2914 | IWL_ERR(priv, "START_ALIVE timeout after %dms.\n", | ||
2915 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); | ||
2916 | return -ETIMEDOUT; | ||
2917 | } | ||
2918 | } | ||
2919 | 2760 | ||
2920 | iwlagn_led_enable(priv); | 2761 | iwlagn_led_enable(priv); |
2921 | 2762 | ||
2922 | out: | ||
2923 | priv->is_open = 1; | 2763 | priv->is_open = 1; |
2924 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2764 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2925 | return 0; | 2765 | return 0; |
@@ -2994,7 +2834,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2994 | 2834 | ||
2995 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 2835 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
2996 | 2836 | ||
2997 | if (priv->cfg->mod_params->sw_crypto) { | 2837 | if (iwlagn_mod_params.sw_crypto) { |
2998 | IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); | 2838 | IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); |
2999 | return -EOPNOTSUPP; | 2839 | return -EOPNOTSUPP; |
3000 | } | 2840 | } |
@@ -3506,8 +3346,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
3506 | INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); | 3346 | INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); |
3507 | INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); | 3347 | INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); |
3508 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); | 3348 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); |
3509 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | ||
3510 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | ||
3511 | INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done); | 3349 | INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done); |
3512 | 3350 | ||
3513 | iwl_setup_scan_deferred_work(priv); | 3351 | iwl_setup_scan_deferred_work(priv); |
@@ -3536,8 +3374,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
3536 | if (priv->cfg->ops->lib->cancel_deferred_work) | 3374 | if (priv->cfg->ops->lib->cancel_deferred_work) |
3537 | priv->cfg->ops->lib->cancel_deferred_work(priv); | 3375 | priv->cfg->ops->lib->cancel_deferred_work(priv); |
3538 | 3376 | ||
3539 | cancel_delayed_work_sync(&priv->init_alive_start); | ||
3540 | cancel_delayed_work(&priv->alive_start); | ||
3541 | cancel_work_sync(&priv->run_time_calib_work); | 3377 | cancel_work_sync(&priv->run_time_calib_work); |
3542 | cancel_work_sync(&priv->beacon_update); | 3378 | cancel_work_sync(&priv->beacon_update); |
3543 | 3379 | ||
@@ -3617,12 +3453,6 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
3617 | priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; | 3453 | priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; |
3618 | } | 3454 | } |
3619 | 3455 | ||
3620 | /* Set the tx_power_user_lmt to the lowest power level | ||
3621 | * this value will get overwritten by channel max power avg | ||
3622 | * from eeprom */ | ||
3623 | priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN; | ||
3624 | priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN; | ||
3625 | |||
3626 | ret = iwl_init_channel_map(priv); | 3456 | ret = iwl_init_channel_map(priv); |
3627 | if (ret) { | 3457 | if (ret) { |
3628 | IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); | 3458 | IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); |
@@ -3692,14 +3522,14 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
3692 | { | 3522 | { |
3693 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | 3523 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
3694 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | 3524 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; |
3695 | if (priv->cfg->mod_params->amsdu_size_8K) | 3525 | if (iwlagn_mod_params.amsdu_size_8K) |
3696 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); | 3526 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); |
3697 | else | 3527 | else |
3698 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); | 3528 | priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); |
3699 | 3529 | ||
3700 | priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; | 3530 | priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; |
3701 | 3531 | ||
3702 | if (priv->cfg->mod_params->disable_11n) | 3532 | if (iwlagn_mod_params.disable_11n) |
3703 | priv->cfg->sku &= ~IWL_SKU_N; | 3533 | priv->cfg->sku &= ~IWL_SKU_N; |
3704 | 3534 | ||
3705 | /* Device-specific setup */ | 3535 | /* Device-specific setup */ |
@@ -3772,6 +3602,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3772 | priv = hw->priv; | 3602 | priv = hw->priv; |
3773 | /* At this point both hw and priv are allocated. */ | 3603 | /* At this point both hw and priv are allocated. */ |
3774 | 3604 | ||
3605 | priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED; | ||
3606 | |||
3775 | /* | 3607 | /* |
3776 | * The default context is always valid, | 3608 | * The default context is always valid, |
3777 | * more may be discovered when firmware | 3609 | * more may be discovered when firmware |
@@ -3912,8 +3744,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3912 | * PCI Tx retries from interfering with C3 CPU state */ | 3744 | * PCI Tx retries from interfering with C3 CPU state */ |
3913 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | 3745 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); |
3914 | 3746 | ||
3915 | iwl_prepare_card_hw(priv); | 3747 | if (iwl_prepare_card_hw(priv)) { |
3916 | if (!priv->hw_ready) { | ||
3917 | IWL_WARN(priv, "Failed, HW not ready\n"); | 3748 | IWL_WARN(priv, "Failed, HW not ready\n"); |
3918 | goto out_iounmap; | 3749 | goto out_iounmap; |
3919 | } | 3750 | } |
@@ -4069,17 +3900,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
4069 | if (priv->mac80211_registered) { | 3900 | if (priv->mac80211_registered) { |
4070 | ieee80211_unregister_hw(priv->hw); | 3901 | ieee80211_unregister_hw(priv->hw); |
4071 | priv->mac80211_registered = 0; | 3902 | priv->mac80211_registered = 0; |
4072 | } else { | ||
4073 | iwl_down(priv); | ||
4074 | } | 3903 | } |
4075 | 3904 | ||
4076 | /* | 3905 | /* Reset to low power before unloading driver. */ |
4077 | * Make sure device is reset to low power before unloading driver. | ||
4078 | * This may be redundant with iwl_down(), but there are paths to | ||
4079 | * run iwl_down() without calling apm_ops.stop(), and there are | ||
4080 | * paths to avoid running iwl_down() at all before leaving driver. | ||
4081 | * This (inexpensive) call *makes sure* device is reset. | ||
4082 | */ | ||
4083 | iwl_apm_stop(priv); | 3906 | iwl_apm_stop(priv); |
4084 | 3907 | ||
4085 | iwl_tt_exit(priv); | 3908 | iwl_tt_exit(priv); |
@@ -4306,21 +4129,21 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
4306 | {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, | 4129 | {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, |
4307 | {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, | 4130 | {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, |
4308 | 4131 | ||
4309 | /* 200 Series */ | 4132 | /* 105 Series */ |
4310 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)}, | 4133 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, |
4311 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)}, | 4134 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, |
4312 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)}, | 4135 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, |
4313 | {IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)}, | 4136 | {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, |
4314 | {IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)}, | 4137 | {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, |
4315 | {IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)}, | 4138 | {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, |
4316 | 4139 | ||
4317 | /* 230 Series */ | 4140 | /* 135 Series */ |
4318 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)}, | 4141 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, |
4319 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)}, | 4142 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, |
4320 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)}, | 4143 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, |
4321 | {IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)}, | 4144 | {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, |
4322 | {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)}, | 4145 | {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, |
4323 | {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)}, | 4146 | {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, |
4324 | 4147 | ||
4325 | {0} | 4148 | {0} |
4326 | }; | 4149 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 078a23e5d99d..b477336ff53a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -102,10 +102,10 @@ extern struct iwl_cfg iwl2030_2bg_cfg; | |||
102 | extern struct iwl_cfg iwl6035_2agn_cfg; | 102 | extern struct iwl_cfg iwl6035_2agn_cfg; |
103 | extern struct iwl_cfg iwl6035_2abg_cfg; | 103 | extern struct iwl_cfg iwl6035_2abg_cfg; |
104 | extern struct iwl_cfg iwl6035_2bg_cfg; | 104 | extern struct iwl_cfg iwl6035_2bg_cfg; |
105 | extern struct iwl_cfg iwl200_bg_cfg; | 105 | extern struct iwl_cfg iwl105_bg_cfg; |
106 | extern struct iwl_cfg iwl200_bgn_cfg; | 106 | extern struct iwl_cfg iwl105_bgn_cfg; |
107 | extern struct iwl_cfg iwl230_bg_cfg; | 107 | extern struct iwl_cfg iwl135_bg_cfg; |
108 | extern struct iwl_cfg iwl230_bgn_cfg; | 108 | extern struct iwl_cfg iwl135_bgn_cfg; |
109 | 109 | ||
110 | extern struct iwl_mod_params iwlagn_mod_params; | 110 | extern struct iwl_mod_params iwlagn_mod_params; |
111 | extern struct iwl_hcmd_ops iwlagn_hcmd; | 111 | extern struct iwl_hcmd_ops iwlagn_hcmd; |
@@ -120,6 +120,19 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv); | |||
120 | void iwl_free_isr_ict(struct iwl_priv *priv); | 120 | void iwl_free_isr_ict(struct iwl_priv *priv); |
121 | irqreturn_t iwl_isr_ict(int irq, void *data); | 121 | irqreturn_t iwl_isr_ict(int irq, void *data); |
122 | 122 | ||
123 | /* call this function to flush any scheduled tasklet */ | ||
124 | static inline void iwl_synchronize_irq(struct iwl_priv *priv) | ||
125 | { | ||
126 | /* wait to make sure we flush pending tasklet*/ | ||
127 | synchronize_irq(priv->pci_dev->irq); | ||
128 | tasklet_kill(&priv->irq_tasklet); | ||
129 | } | ||
130 | |||
131 | int iwl_prepare_card_hw(struct iwl_priv *priv); | ||
132 | |||
133 | int iwlagn_start_device(struct iwl_priv *priv); | ||
134 | void iwlagn_stop_device(struct iwl_priv *priv); | ||
135 | |||
123 | /* tx queue */ | 136 | /* tx queue */ |
124 | void iwlagn_set_wr_ptrs(struct iwl_priv *priv, | 137 | void iwlagn_set_wr_ptrs(struct iwl_priv *priv, |
125 | int txq_id, u32 index); | 138 | int txq_id, u32 index); |
@@ -145,16 +158,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
145 | u32 changes); | 158 | u32 changes); |
146 | 159 | ||
147 | /* uCode */ | 160 | /* uCode */ |
148 | int iwlagn_load_ucode(struct iwl_priv *priv); | ||
149 | void iwlagn_rx_calib_result(struct iwl_priv *priv, | 161 | void iwlagn_rx_calib_result(struct iwl_priv *priv, |
150 | struct iwl_rx_mem_buffer *rxb); | 162 | struct iwl_rx_mem_buffer *rxb); |
151 | void iwlagn_rx_calib_complete(struct iwl_priv *priv, | 163 | int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); |
152 | struct iwl_rx_mem_buffer *rxb); | ||
153 | void iwlagn_init_alive_start(struct iwl_priv *priv); | ||
154 | int iwlagn_alive_notify(struct iwl_priv *priv); | ||
155 | int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc); | ||
156 | void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | ||
157 | void iwlagn_send_prio_tbl(struct iwl_priv *priv); | 164 | void iwlagn_send_prio_tbl(struct iwl_priv *priv); |
165 | int iwlagn_run_init_ucode(struct iwl_priv *priv); | ||
166 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | ||
167 | struct fw_img *image, | ||
168 | int subtype, int alternate_subtype); | ||
158 | 169 | ||
159 | /* lib */ | 170 | /* lib */ |
160 | void iwl_check_abort_status(struct iwl_priv *priv, | 171 | void iwl_check_abort_status(struct iwl_priv *priv, |
@@ -245,8 +256,6 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, | |||
245 | struct ieee80211_vif *vif, bool add); | 256 | struct ieee80211_vif *vif, bool add); |
246 | 257 | ||
247 | /* hcmd */ | 258 | /* hcmd */ |
248 | int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | ||
249 | struct iwl_rxon_context *ctx); | ||
250 | int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); | 259 | int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); |
251 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | 260 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); |
252 | 261 | ||
@@ -318,17 +327,17 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | |||
318 | /* eeprom */ | 327 | /* eeprom */ |
319 | void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv); | 328 | void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv); |
320 | void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); | 329 | void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); |
321 | int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); | ||
322 | void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); | ||
323 | 330 | ||
324 | /* notification wait support */ | 331 | /* notification wait support */ |
325 | void __acquires(wait_entry) | 332 | void __acquires(wait_entry) |
326 | iwlagn_init_notification_wait(struct iwl_priv *priv, | 333 | iwlagn_init_notification_wait(struct iwl_priv *priv, |
327 | struct iwl_notification_wait *wait_entry, | 334 | struct iwl_notification_wait *wait_entry, |
335 | u8 cmd, | ||
328 | void (*fn)(struct iwl_priv *priv, | 336 | void (*fn)(struct iwl_priv *priv, |
329 | struct iwl_rx_packet *pkt), | 337 | struct iwl_rx_packet *pkt, |
330 | u8 cmd); | 338 | void *data), |
331 | signed long __releases(wait_entry) | 339 | void *fn_data); |
340 | int __must_check __releases(wait_entry) | ||
332 | iwlagn_wait_notification(struct iwl_priv *priv, | 341 | iwlagn_wait_notification(struct iwl_priv *priv, |
333 | struct iwl_notification_wait *wait_entry, | 342 | struct iwl_notification_wait *wait_entry, |
334 | unsigned long timeout); | 343 | unsigned long timeout); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 0edba8a6419b..5fdad6532118 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -386,7 +386,18 @@ struct iwl_tx_ant_config_cmd { | |||
386 | *****************************************************************************/ | 386 | *****************************************************************************/ |
387 | 387 | ||
388 | #define UCODE_VALID_OK cpu_to_le32(0x1) | 388 | #define UCODE_VALID_OK cpu_to_le32(0x1) |
389 | #define INITIALIZE_SUBTYPE (9) | 389 | |
390 | enum iwlagn_ucode_subtype { | ||
391 | UCODE_SUBTYPE_REGULAR = 0, | ||
392 | UCODE_SUBTYPE_REGULAR_NEW = 1, | ||
393 | UCODE_SUBTYPE_INIT = 9, | ||
394 | |||
395 | /* | ||
396 | * Not a valid subtype, the ucode has just a u8, so | ||
397 | * we can use something > 0xff for this value. | ||
398 | */ | ||
399 | UCODE_SUBTYPE_NONE_LOADED = 0x100, | ||
400 | }; | ||
390 | 401 | ||
391 | /** | 402 | /** |
392 | * REPLY_ALIVE = 0x1 (response only, not a command) | 403 | * REPLY_ALIVE = 0x1 (response only, not a command) |
@@ -422,49 +433,61 @@ struct iwl_tx_ant_config_cmd { | |||
422 | * | 433 | * |
423 | * 2) error_event_table_ptr indicates base of the error log. This contains | 434 | * 2) error_event_table_ptr indicates base of the error log. This contains |
424 | * information about any uCode error that occurs. For agn, the format | 435 | * information about any uCode error that occurs. For agn, the format |
425 | * of the error log is: | 436 | * of the error log is defined by struct iwl_error_event_table. |
426 | * | ||
427 | * __le32 valid; (nonzero) valid, (0) log is empty | ||
428 | * __le32 error_id; type of error | ||
429 | * __le32 pc; program counter | ||
430 | * __le32 blink1; branch link | ||
431 | * __le32 blink2; branch link | ||
432 | * __le32 ilink1; interrupt link | ||
433 | * __le32 ilink2; interrupt link | ||
434 | * __le32 data1; error-specific data | ||
435 | * __le32 data2; error-specific data | ||
436 | * __le32 line; source code line of error | ||
437 | * __le32 bcon_time; beacon timer | ||
438 | * __le32 tsf_low; network timestamp function timer | ||
439 | * __le32 tsf_hi; network timestamp function timer | ||
440 | * __le32 gp1; GP1 timer register | ||
441 | * __le32 gp2; GP2 timer register | ||
442 | * __le32 gp3; GP3 timer register | ||
443 | * __le32 ucode_ver; uCode version | ||
444 | * __le32 hw_ver; HW Silicon version | ||
445 | * __le32 brd_ver; HW board version | ||
446 | * __le32 log_pc; log program counter | ||
447 | * __le32 frame_ptr; frame pointer | ||
448 | * __le32 stack_ptr; stack pointer | ||
449 | * __le32 hcmd; last host command | ||
450 | * __le32 isr0; isr status register LMPM_NIC_ISR0: rxtx_flag | ||
451 | * __le32 isr1; isr status register LMPM_NIC_ISR1: host_flag | ||
452 | * __le32 isr2; isr status register LMPM_NIC_ISR2: enc_flag | ||
453 | * __le32 isr3; isr status register LMPM_NIC_ISR3: time_flag | ||
454 | * __le32 isr4; isr status register LMPM_NIC_ISR4: wico interrupt | ||
455 | * __le32 isr_pref; isr status register LMPM_NIC_PREF_STAT | ||
456 | * __le32 wait_event; wait event() caller address | ||
457 | * __le32 l2p_control; L2pControlField | ||
458 | * __le32 l2p_duration; L2pDurationField | ||
459 | * __le32 l2p_mhvalid; L2pMhValidBits | ||
460 | * __le32 l2p_addr_match; L2pAddrMatchStat | ||
461 | * __le32 lmpm_pmg_sel; indicate which clocks are turned on (LMPM_PMG_SEL) | ||
462 | * __le32 u_timestamp; indicate when the date and time of the compilation | ||
463 | * __le32 reserved; | ||
464 | * | 437 | * |
465 | * The Linux driver can print both logs to the system log when a uCode error | 438 | * The Linux driver can print both logs to the system log when a uCode error |
466 | * occurs. | 439 | * occurs. |
467 | */ | 440 | */ |
441 | |||
442 | /* | ||
443 | * Note: This structure is read from the device with IO accesses, | ||
444 | * and the reading already does the endian conversion. As it is | ||
445 | * read with u32-sized accesses, any members with a different size | ||
446 | * need to be ordered correctly though! | ||
447 | */ | ||
448 | struct iwl_error_event_table { | ||
449 | u32 valid; /* (nonzero) valid, (0) log is empty */ | ||
450 | u32 error_id; /* type of error */ | ||
451 | u32 pc; /* program counter */ | ||
452 | u32 blink1; /* branch link */ | ||
453 | u32 blink2; /* branch link */ | ||
454 | u32 ilink1; /* interrupt link */ | ||
455 | u32 ilink2; /* interrupt link */ | ||
456 | u32 data1; /* error-specific data */ | ||
457 | u32 data2; /* error-specific data */ | ||
458 | u32 line; /* source code line of error */ | ||
459 | u32 bcon_time; /* beacon timer */ | ||
460 | u32 tsf_low; /* network timestamp function timer */ | ||
461 | u32 tsf_hi; /* network timestamp function timer */ | ||
462 | u32 gp1; /* GP1 timer register */ | ||
463 | u32 gp2; /* GP2 timer register */ | ||
464 | u32 gp3; /* GP3 timer register */ | ||
465 | u32 ucode_ver; /* uCode version */ | ||
466 | u32 hw_ver; /* HW Silicon version */ | ||
467 | u32 brd_ver; /* HW board version */ | ||
468 | u32 log_pc; /* log program counter */ | ||
469 | u32 frame_ptr; /* frame pointer */ | ||
470 | u32 stack_ptr; /* stack pointer */ | ||
471 | u32 hcmd; /* last host command header */ | ||
472 | #if 0 | ||
473 | /* no need to read the remainder, we don't use the values */ | ||
474 | u32 isr0; /* isr status register LMPM_NIC_ISR0: rxtx_flag */ | ||
475 | u32 isr1; /* isr status register LMPM_NIC_ISR1: host_flag */ | ||
476 | u32 isr2; /* isr status register LMPM_NIC_ISR2: enc_flag */ | ||
477 | u32 isr3; /* isr status register LMPM_NIC_ISR3: time_flag */ | ||
478 | u32 isr4; /* isr status register LMPM_NIC_ISR4: wico interrupt */ | ||
479 | u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */ | ||
480 | u32 wait_event; /* wait event() caller address */ | ||
481 | u32 l2p_control; /* L2pControlField */ | ||
482 | u32 l2p_duration; /* L2pDurationField */ | ||
483 | u32 l2p_mhvalid; /* L2pMhValidBits */ | ||
484 | u32 l2p_addr_match; /* L2pAddrMatchStat */ | ||
485 | u32 lmpm_pmg_sel; /* indicate which clocks are turned on (LMPM_PMG_SEL) */ | ||
486 | u32 u_timestamp; /* indicate when the date and time of the compilation */ | ||
487 | u32 flow_handler; /* FH read/write pointers, RX credit */ | ||
488 | #endif | ||
489 | } __packed; | ||
490 | |||
468 | struct iwl_alive_resp { | 491 | struct iwl_alive_resp { |
469 | u8 ucode_minor; | 492 | u8 ucode_minor; |
470 | u8 ucode_major; | 493 | u8 ucode_major; |
@@ -638,7 +661,7 @@ struct iwl_rxon_cmd { | |||
638 | /* | 661 | /* |
639 | * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) | 662 | * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) |
640 | */ | 663 | */ |
641 | struct iwl5000_rxon_assoc_cmd { | 664 | struct iwl_rxon_assoc_cmd { |
642 | __le32 flags; | 665 | __le32 flags; |
643 | __le32 filter_flags; | 666 | __le32 filter_flags; |
644 | u8 ofdm_basic_rates; | 667 | u8 ofdm_basic_rates; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 885167f8168d..4653deada05b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "iwl-power.h" | 41 | #include "iwl-power.h" |
42 | #include "iwl-sta.h" | 42 | #include "iwl-sta.h" |
43 | #include "iwl-helpers.h" | 43 | #include "iwl-helpers.h" |
44 | #include "iwl-agn.h" | ||
44 | 45 | ||
45 | 46 | ||
46 | /* | 47 | /* |
@@ -94,7 +95,7 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | |||
94 | max_bit_rate = MAX_BIT_RATE_40_MHZ; | 95 | max_bit_rate = MAX_BIT_RATE_40_MHZ; |
95 | } | 96 | } |
96 | 97 | ||
97 | if (priv->cfg->mod_params->amsdu_size_8K) | 98 | if (iwlagn_mod_params.amsdu_size_8K) |
98 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | 99 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; |
99 | 100 | ||
100 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; | 101 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; |
@@ -135,6 +136,7 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
135 | struct ieee80211_channel *geo_ch; | 136 | struct ieee80211_channel *geo_ch; |
136 | struct ieee80211_rate *rates; | 137 | struct ieee80211_rate *rates; |
137 | int i = 0; | 138 | int i = 0; |
139 | s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN; | ||
138 | 140 | ||
139 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | 141 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
140 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | 142 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { |
@@ -208,8 +210,8 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
208 | 210 | ||
209 | geo_ch->flags |= ch->ht40_extension_channel; | 211 | geo_ch->flags |= ch->ht40_extension_channel; |
210 | 212 | ||
211 | if (ch->max_power_avg > priv->tx_power_device_lmt) | 213 | if (ch->max_power_avg > max_tx_power) |
212 | priv->tx_power_device_lmt = ch->max_power_avg; | 214 | max_tx_power = ch->max_power_avg; |
213 | } else { | 215 | } else { |
214 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | 216 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; |
215 | } | 217 | } |
@@ -222,6 +224,10 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
222 | geo_ch->flags); | 224 | geo_ch->flags); |
223 | } | 225 | } |
224 | 226 | ||
227 | priv->tx_power_device_lmt = max_tx_power; | ||
228 | priv->tx_power_user_lmt = max_tx_power; | ||
229 | priv->tx_power_next = max_tx_power; | ||
230 | |||
225 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | 231 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
226 | priv->cfg->sku & IWL_SKU_A) { | 232 | priv->cfg->sku & IWL_SKU_A) { |
227 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | 233 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " |
@@ -410,72 +416,72 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
410 | int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | 416 | int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) |
411 | { | 417 | { |
412 | struct iwl_rxon_cmd *rxon = &ctx->staging; | 418 | struct iwl_rxon_cmd *rxon = &ctx->staging; |
413 | bool error = false; | 419 | u32 errors = 0; |
414 | 420 | ||
415 | if (rxon->flags & RXON_FLG_BAND_24G_MSK) { | 421 | if (rxon->flags & RXON_FLG_BAND_24G_MSK) { |
416 | if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) { | 422 | if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) { |
417 | IWL_WARN(priv, "check 2.4G: wrong narrow\n"); | 423 | IWL_WARN(priv, "check 2.4G: wrong narrow\n"); |
418 | error = true; | 424 | errors |= BIT(0); |
419 | } | 425 | } |
420 | if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) { | 426 | if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) { |
421 | IWL_WARN(priv, "check 2.4G: wrong radar\n"); | 427 | IWL_WARN(priv, "check 2.4G: wrong radar\n"); |
422 | error = true; | 428 | errors |= BIT(1); |
423 | } | 429 | } |
424 | } else { | 430 | } else { |
425 | if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) { | 431 | if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) { |
426 | IWL_WARN(priv, "check 5.2G: not short slot!\n"); | 432 | IWL_WARN(priv, "check 5.2G: not short slot!\n"); |
427 | error = true; | 433 | errors |= BIT(2); |
428 | } | 434 | } |
429 | if (rxon->flags & RXON_FLG_CCK_MSK) { | 435 | if (rxon->flags & RXON_FLG_CCK_MSK) { |
430 | IWL_WARN(priv, "check 5.2G: CCK!\n"); | 436 | IWL_WARN(priv, "check 5.2G: CCK!\n"); |
431 | error = true; | 437 | errors |= BIT(3); |
432 | } | 438 | } |
433 | } | 439 | } |
434 | if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) { | 440 | if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) { |
435 | IWL_WARN(priv, "mac/bssid mcast!\n"); | 441 | IWL_WARN(priv, "mac/bssid mcast!\n"); |
436 | error = true; | 442 | errors |= BIT(4); |
437 | } | 443 | } |
438 | 444 | ||
439 | /* make sure basic rates 6Mbps and 1Mbps are supported */ | 445 | /* make sure basic rates 6Mbps and 1Mbps are supported */ |
440 | if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 && | 446 | if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 && |
441 | (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) { | 447 | (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) { |
442 | IWL_WARN(priv, "neither 1 nor 6 are basic\n"); | 448 | IWL_WARN(priv, "neither 1 nor 6 are basic\n"); |
443 | error = true; | 449 | errors |= BIT(5); |
444 | } | 450 | } |
445 | 451 | ||
446 | if (le16_to_cpu(rxon->assoc_id) > 2007) { | 452 | if (le16_to_cpu(rxon->assoc_id) > 2007) { |
447 | IWL_WARN(priv, "aid > 2007\n"); | 453 | IWL_WARN(priv, "aid > 2007\n"); |
448 | error = true; | 454 | errors |= BIT(6); |
449 | } | 455 | } |
450 | 456 | ||
451 | if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) | 457 | if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) |
452 | == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) { | 458 | == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) { |
453 | IWL_WARN(priv, "CCK and short slot\n"); | 459 | IWL_WARN(priv, "CCK and short slot\n"); |
454 | error = true; | 460 | errors |= BIT(7); |
455 | } | 461 | } |
456 | 462 | ||
457 | if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) | 463 | if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) |
458 | == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) { | 464 | == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) { |
459 | IWL_WARN(priv, "CCK and auto detect"); | 465 | IWL_WARN(priv, "CCK and auto detect"); |
460 | error = true; | 466 | errors |= BIT(8); |
461 | } | 467 | } |
462 | 468 | ||
463 | if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | | 469 | if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | |
464 | RXON_FLG_TGG_PROTECT_MSK)) == | 470 | RXON_FLG_TGG_PROTECT_MSK)) == |
465 | RXON_FLG_TGG_PROTECT_MSK) { | 471 | RXON_FLG_TGG_PROTECT_MSK) { |
466 | IWL_WARN(priv, "TGg but no auto-detect\n"); | 472 | IWL_WARN(priv, "TGg but no auto-detect\n"); |
467 | error = true; | 473 | errors |= BIT(9); |
468 | } | 474 | } |
469 | 475 | ||
470 | if (error) | 476 | if (rxon->channel == 0) { |
471 | IWL_WARN(priv, "Tuning to channel %d\n", | 477 | IWL_WARN(priv, "zero channel is invalid\n"); |
472 | le16_to_cpu(rxon->channel)); | 478 | errors |= BIT(10); |
473 | |||
474 | if (error) { | ||
475 | IWL_ERR(priv, "Invalid RXON\n"); | ||
476 | return -EINVAL; | ||
477 | } | 479 | } |
478 | return 0; | 480 | |
481 | WARN(errors, "Invalid RXON (%#x), channel %d", | ||
482 | errors, le16_to_cpu(rxon->channel)); | ||
483 | |||
484 | return errors ? -EINVAL : 0; | ||
479 | } | 485 | } |
480 | 486 | ||
481 | /** | 487 | /** |
@@ -867,6 +873,19 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, | |||
867 | } | 873 | } |
868 | #endif | 874 | #endif |
869 | 875 | ||
876 | static void iwlagn_abort_notification_waits(struct iwl_priv *priv) | ||
877 | { | ||
878 | unsigned long flags; | ||
879 | struct iwl_notification_wait *wait_entry; | ||
880 | |||
881 | spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags); | ||
882 | list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list) | ||
883 | wait_entry->aborted = true; | ||
884 | spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags); | ||
885 | |||
886 | wake_up_all(&priv->_agn.notif_waitq); | ||
887 | } | ||
888 | |||
870 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | 889 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) |
871 | { | 890 | { |
872 | unsigned int reload_msec; | 891 | unsigned int reload_msec; |
@@ -878,6 +897,8 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
878 | /* Cancel currently queued command. */ | 897 | /* Cancel currently queued command. */ |
879 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 898 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
880 | 899 | ||
900 | iwlagn_abort_notification_waits(priv); | ||
901 | |||
881 | /* Keep the restart process from trying to send host | 902 | /* Keep the restart process from trying to send host |
882 | * commands by clearing the ready bit */ | 903 | * commands by clearing the ready bit */ |
883 | clear_bit(STATUS_READY, &priv->status); | 904 | clear_bit(STATUS_READY, &priv->status); |
@@ -906,7 +927,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
906 | } | 927 | } |
907 | 928 | ||
908 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 929 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
909 | if (priv->cfg->mod_params->restart_fw) { | 930 | if (iwlagn_mod_params.restart_fw) { |
910 | IWL_DEBUG(priv, IWL_DL_FW_ERRORS, | 931 | IWL_DEBUG(priv, IWL_DL_FW_ERRORS, |
911 | "Restarting adapter due to uCode error.\n"); | 932 | "Restarting adapter due to uCode error.\n"); |
912 | queue_work(priv->workqueue, &priv->restart); | 933 | queue_work(priv->workqueue, &priv->restart); |
@@ -975,6 +996,8 @@ void iwl_apm_stop(struct iwl_priv *priv) | |||
975 | { | 996 | { |
976 | IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); | 997 | IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); |
977 | 998 | ||
999 | clear_bit(STATUS_DEVICE_ENABLED, &priv->status); | ||
1000 | |||
978 | /* Stop device's DMA activity */ | 1001 | /* Stop device's DMA activity */ |
979 | iwl_apm_stop_master(priv); | 1002 | iwl_apm_stop_master(priv); |
980 | 1003 | ||
@@ -1089,6 +1112,8 @@ int iwl_apm_init(struct iwl_priv *priv) | |||
1089 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | 1112 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, |
1090 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | 1113 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
1091 | 1114 | ||
1115 | set_bit(STATUS_DEVICE_ENABLED, &priv->status); | ||
1116 | |||
1092 | out: | 1117 | out: |
1093 | return ret; | 1118 | return ret; |
1094 | } | 1119 | } |
@@ -1723,7 +1748,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
1723 | * detect failure), then fw_restart module parameter | 1748 | * detect failure), then fw_restart module parameter |
1724 | * need to be check before performing firmware reload | 1749 | * need to be check before performing firmware reload |
1725 | */ | 1750 | */ |
1726 | if (!external && !priv->cfg->mod_params->restart_fw) { | 1751 | if (!external && !iwlagn_mod_params.restart_fw) { |
1727 | IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " | 1752 | IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " |
1728 | "module parameter setting\n"); | 1753 | "module parameter setting\n"); |
1729 | break; | 1754 | break; |
@@ -1740,6 +1765,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1740 | { | 1765 | { |
1741 | struct iwl_priv *priv = hw->priv; | 1766 | struct iwl_priv *priv = hw->priv; |
1742 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 1767 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
1768 | struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
1743 | struct iwl_rxon_context *tmp; | 1769 | struct iwl_rxon_context *tmp; |
1744 | u32 interface_modes; | 1770 | u32 interface_modes; |
1745 | int err; | 1771 | int err; |
@@ -1764,6 +1790,19 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1764 | goto out; | 1790 | goto out; |
1765 | } | 1791 | } |
1766 | 1792 | ||
1793 | /* | ||
1794 | * Refuse a change that should be done by moving from the PAN | ||
1795 | * context to the BSS context instead, if the BSS context is | ||
1796 | * available and can support the new interface type. | ||
1797 | */ | ||
1798 | if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif && | ||
1799 | (bss_ctx->interface_modes & BIT(newtype) || | ||
1800 | bss_ctx->exclusive_interface_modes & BIT(newtype))) { | ||
1801 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
1802 | err = -EBUSY; | ||
1803 | goto out; | ||
1804 | } | ||
1805 | |||
1767 | if (ctx->exclusive_interface_modes & BIT(newtype)) { | 1806 | if (ctx->exclusive_interface_modes & BIT(newtype)) { |
1768 | for_each_context(priv, tmp) { | 1807 | for_each_context(priv, tmp) { |
1769 | if (ctx == tmp) | 1808 | if (ctx == tmp) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 32a990ff09ae..dec9820753f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -90,7 +90,6 @@ struct iwl_cmd; | |||
90 | #define IWL_CMD(x) case x: return #x | 90 | #define IWL_CMD(x) case x: return #x |
91 | 91 | ||
92 | struct iwl_hcmd_ops { | 92 | struct iwl_hcmd_ops { |
93 | int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
94 | int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 93 | int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
95 | void (*set_rxon_chain)(struct iwl_priv *priv, | 94 | void (*set_rxon_chain)(struct iwl_priv *priv, |
96 | struct iwl_rxon_context *ctx); | 95 | struct iwl_rxon_context *ctx); |
@@ -122,19 +121,6 @@ struct iwl_apm_ops { | |||
122 | void (*config)(struct iwl_priv *priv); | 121 | void (*config)(struct iwl_priv *priv); |
123 | }; | 122 | }; |
124 | 123 | ||
125 | struct iwl_debugfs_ops { | ||
126 | ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf, | ||
127 | size_t count, loff_t *ppos); | ||
128 | ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf, | ||
129 | size_t count, loff_t *ppos); | ||
130 | ssize_t (*general_stats_read)(struct file *file, char __user *user_buf, | ||
131 | size_t count, loff_t *ppos); | ||
132 | ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf, | ||
133 | size_t count, loff_t *ppos); | ||
134 | ssize_t (*reply_tx_error)(struct file *file, char __user *user_buf, | ||
135 | size_t count, loff_t *ppos); | ||
136 | }; | ||
137 | |||
138 | struct iwl_temp_ops { | 124 | struct iwl_temp_ops { |
139 | void (*temperature)(struct iwl_priv *priv); | 125 | void (*temperature)(struct iwl_priv *priv); |
140 | }; | 126 | }; |
@@ -183,7 +169,6 @@ struct iwl_lib_ops { | |||
183 | int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); | 169 | int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); |
184 | void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); | 170 | void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); |
185 | 171 | ||
186 | struct iwl_debugfs_ops debugfs_ops; | ||
187 | }; | 172 | }; |
188 | 173 | ||
189 | /* NIC specific ops */ | 174 | /* NIC specific ops */ |
@@ -326,8 +311,6 @@ struct iwl_cfg { | |||
326 | u16 eeprom_ver; | 311 | u16 eeprom_ver; |
327 | u16 eeprom_calib_ver; | 312 | u16 eeprom_calib_ver; |
328 | const struct iwl_ops *ops; | 313 | const struct iwl_ops *ops; |
329 | /* module based parameters which can be set from modprobe cmd */ | ||
330 | const struct iwl_mod_params *mod_params; | ||
331 | /* params not likely to change within a device family */ | 314 | /* params not likely to change within a device family */ |
332 | struct iwl_base_params *base_params; | 315 | struct iwl_base_params *base_params; |
333 | /* params likely to change within a device family */ | 316 | /* params likely to change within a device family */ |
@@ -592,6 +575,7 @@ void iwlcore_free_geos(struct iwl_priv *priv); | |||
592 | #define STATUS_SCAN_HW 15 | 575 | #define STATUS_SCAN_HW 15 |
593 | #define STATUS_POWER_PMI 16 | 576 | #define STATUS_POWER_PMI 16 |
594 | #define STATUS_FW_ERROR 17 | 577 | #define STATUS_FW_ERROR 17 |
578 | #define STATUS_DEVICE_ENABLED 18 | ||
595 | 579 | ||
596 | 580 | ||
597 | static inline int iwl_is_ready(struct iwl_priv *priv) | 581 | static inline int iwl_is_ready(struct iwl_priv *priv) |
@@ -644,11 +628,6 @@ void iwl_apm_stop(struct iwl_priv *priv); | |||
644 | int iwl_apm_init(struct iwl_priv *priv); | 628 | int iwl_apm_init(struct iwl_priv *priv); |
645 | 629 | ||
646 | int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 630 | int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
647 | static inline int iwl_send_rxon_assoc(struct iwl_priv *priv, | ||
648 | struct iwl_rxon_context *ctx) | ||
649 | { | ||
650 | return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx); | ||
651 | } | ||
652 | static inline int iwlcore_commit_rxon(struct iwl_priv *priv, | 631 | static inline int iwlcore_commit_rxon(struct iwl_priv *priv, |
653 | struct iwl_rxon_context *ctx) | 632 | struct iwl_rxon_context *ctx) |
654 | { | 633 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index c272204fccff..0e6a04b739ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "iwl-debug.h" | 39 | #include "iwl-debug.h" |
40 | #include "iwl-core.h" | 40 | #include "iwl-core.h" |
41 | #include "iwl-io.h" | 41 | #include "iwl-io.h" |
42 | #include "iwl-agn.h" | ||
42 | 43 | ||
43 | /* create and remove of files */ | 44 | /* create and remove of files */ |
44 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ | 45 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ |
@@ -226,10 +227,10 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
226 | /* default is to dump the entire data segment */ | 227 | /* default is to dump the entire data segment */ |
227 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 228 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
228 | priv->dbgfs_sram_offset = 0x800000; | 229 | priv->dbgfs_sram_offset = 0x800000; |
229 | if (priv->ucode_type == UCODE_INIT) | 230 | if (priv->ucode_type == UCODE_SUBTYPE_INIT) |
230 | priv->dbgfs_sram_len = priv->ucode_init_data.len; | 231 | priv->dbgfs_sram_len = priv->ucode_init.data.len; |
231 | else | 232 | else |
232 | priv->dbgfs_sram_len = priv->ucode_data.len; | 233 | priv->dbgfs_sram_len = priv->ucode_rt.data.len; |
233 | } | 234 | } |
234 | len = priv->dbgfs_sram_len; | 235 | len = priv->dbgfs_sram_len; |
235 | 236 | ||
@@ -1037,13 +1038,463 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, | |||
1037 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1038 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1038 | } | 1039 | } |
1039 | 1040 | ||
1041 | static const char *fmt_value = " %-30s %10u\n"; | ||
1042 | static const char *fmt_hex = " %-30s 0x%02X\n"; | ||
1043 | static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; | ||
1044 | static const char *fmt_header = | ||
1045 | "%-32s current cumulative delta max\n"; | ||
1046 | |||
1047 | static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) | ||
1048 | { | ||
1049 | int p = 0; | ||
1050 | u32 flag; | ||
1051 | |||
1052 | flag = le32_to_cpu(priv->statistics.flag); | ||
1053 | |||
1054 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); | ||
1055 | if (flag & UCODE_STATISTICS_CLEAR_MSK) | ||
1056 | p += scnprintf(buf + p, bufsz - p, | ||
1057 | "\tStatistics have been cleared\n"); | ||
1058 | p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", | ||
1059 | (flag & UCODE_STATISTICS_FREQUENCY_MSK) | ||
1060 | ? "2.4 GHz" : "5.2 GHz"); | ||
1061 | p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", | ||
1062 | (flag & UCODE_STATISTICS_NARROW_BAND_MSK) | ||
1063 | ? "enabled" : "disabled"); | ||
1064 | |||
1065 | return p; | ||
1066 | } | ||
1067 | |||
1040 | static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | 1068 | static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, |
1041 | char __user *user_buf, | 1069 | char __user *user_buf, |
1042 | size_t count, loff_t *ppos) | 1070 | size_t count, loff_t *ppos) |
1043 | { | 1071 | { |
1044 | struct iwl_priv *priv = file->private_data; | 1072 | struct iwl_priv *priv = file->private_data; |
1045 | return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file, | 1073 | int pos = 0; |
1046 | user_buf, count, ppos); | 1074 | char *buf; |
1075 | int bufsz = sizeof(struct statistics_rx_phy) * 40 + | ||
1076 | sizeof(struct statistics_rx_non_phy) * 40 + | ||
1077 | sizeof(struct statistics_rx_ht_phy) * 40 + 400; | ||
1078 | ssize_t ret; | ||
1079 | struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; | ||
1080 | struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; | ||
1081 | struct statistics_rx_non_phy *general, *accum_general; | ||
1082 | struct statistics_rx_non_phy *delta_general, *max_general; | ||
1083 | struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; | ||
1084 | |||
1085 | if (!iwl_is_alive(priv)) | ||
1086 | return -EAGAIN; | ||
1087 | |||
1088 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
1089 | if (!buf) { | ||
1090 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
1091 | return -ENOMEM; | ||
1092 | } | ||
1093 | |||
1094 | /* | ||
1095 | * the statistic information display here is based on | ||
1096 | * the last statistics notification from uCode | ||
1097 | * might not reflect the current uCode activity | ||
1098 | */ | ||
1099 | ofdm = &priv->statistics.rx_ofdm; | ||
1100 | cck = &priv->statistics.rx_cck; | ||
1101 | general = &priv->statistics.rx_non_phy; | ||
1102 | ht = &priv->statistics.rx_ofdm_ht; | ||
1103 | accum_ofdm = &priv->accum_stats.rx_ofdm; | ||
1104 | accum_cck = &priv->accum_stats.rx_cck; | ||
1105 | accum_general = &priv->accum_stats.rx_non_phy; | ||
1106 | accum_ht = &priv->accum_stats.rx_ofdm_ht; | ||
1107 | delta_ofdm = &priv->delta_stats.rx_ofdm; | ||
1108 | delta_cck = &priv->delta_stats.rx_cck; | ||
1109 | delta_general = &priv->delta_stats.rx_non_phy; | ||
1110 | delta_ht = &priv->delta_stats.rx_ofdm_ht; | ||
1111 | max_ofdm = &priv->max_delta_stats.rx_ofdm; | ||
1112 | max_cck = &priv->max_delta_stats.rx_cck; | ||
1113 | max_general = &priv->max_delta_stats.rx_non_phy; | ||
1114 | max_ht = &priv->max_delta_stats.rx_ofdm_ht; | ||
1115 | |||
1116 | pos += iwl_statistics_flag(priv, buf, bufsz); | ||
1117 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1118 | fmt_header, "Statistics_Rx - OFDM:"); | ||
1119 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1120 | fmt_table, "ina_cnt:", | ||
1121 | le32_to_cpu(ofdm->ina_cnt), | ||
1122 | accum_ofdm->ina_cnt, | ||
1123 | delta_ofdm->ina_cnt, max_ofdm->ina_cnt); | ||
1124 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1125 | fmt_table, "fina_cnt:", | ||
1126 | le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, | ||
1127 | delta_ofdm->fina_cnt, max_ofdm->fina_cnt); | ||
1128 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1129 | fmt_table, "plcp_err:", | ||
1130 | le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, | ||
1131 | delta_ofdm->plcp_err, max_ofdm->plcp_err); | ||
1132 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1133 | fmt_table, "crc32_err:", | ||
1134 | le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, | ||
1135 | delta_ofdm->crc32_err, max_ofdm->crc32_err); | ||
1136 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1137 | fmt_table, "overrun_err:", | ||
1138 | le32_to_cpu(ofdm->overrun_err), | ||
1139 | accum_ofdm->overrun_err, delta_ofdm->overrun_err, | ||
1140 | max_ofdm->overrun_err); | ||
1141 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1142 | fmt_table, "early_overrun_err:", | ||
1143 | le32_to_cpu(ofdm->early_overrun_err), | ||
1144 | accum_ofdm->early_overrun_err, | ||
1145 | delta_ofdm->early_overrun_err, | ||
1146 | max_ofdm->early_overrun_err); | ||
1147 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1148 | fmt_table, "crc32_good:", | ||
1149 | le32_to_cpu(ofdm->crc32_good), | ||
1150 | accum_ofdm->crc32_good, delta_ofdm->crc32_good, | ||
1151 | max_ofdm->crc32_good); | ||
1152 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1153 | fmt_table, "false_alarm_cnt:", | ||
1154 | le32_to_cpu(ofdm->false_alarm_cnt), | ||
1155 | accum_ofdm->false_alarm_cnt, | ||
1156 | delta_ofdm->false_alarm_cnt, | ||
1157 | max_ofdm->false_alarm_cnt); | ||
1158 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1159 | fmt_table, "fina_sync_err_cnt:", | ||
1160 | le32_to_cpu(ofdm->fina_sync_err_cnt), | ||
1161 | accum_ofdm->fina_sync_err_cnt, | ||
1162 | delta_ofdm->fina_sync_err_cnt, | ||
1163 | max_ofdm->fina_sync_err_cnt); | ||
1164 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1165 | fmt_table, "sfd_timeout:", | ||
1166 | le32_to_cpu(ofdm->sfd_timeout), | ||
1167 | accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout, | ||
1168 | max_ofdm->sfd_timeout); | ||
1169 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1170 | fmt_table, "fina_timeout:", | ||
1171 | le32_to_cpu(ofdm->fina_timeout), | ||
1172 | accum_ofdm->fina_timeout, delta_ofdm->fina_timeout, | ||
1173 | max_ofdm->fina_timeout); | ||
1174 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1175 | fmt_table, "unresponded_rts:", | ||
1176 | le32_to_cpu(ofdm->unresponded_rts), | ||
1177 | accum_ofdm->unresponded_rts, | ||
1178 | delta_ofdm->unresponded_rts, | ||
1179 | max_ofdm->unresponded_rts); | ||
1180 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1181 | fmt_table, "rxe_frame_lmt_ovrun:", | ||
1182 | le32_to_cpu(ofdm->rxe_frame_limit_overrun), | ||
1183 | accum_ofdm->rxe_frame_limit_overrun, | ||
1184 | delta_ofdm->rxe_frame_limit_overrun, | ||
1185 | max_ofdm->rxe_frame_limit_overrun); | ||
1186 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1187 | fmt_table, "sent_ack_cnt:", | ||
1188 | le32_to_cpu(ofdm->sent_ack_cnt), | ||
1189 | accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt, | ||
1190 | max_ofdm->sent_ack_cnt); | ||
1191 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1192 | fmt_table, "sent_cts_cnt:", | ||
1193 | le32_to_cpu(ofdm->sent_cts_cnt), | ||
1194 | accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt, | ||
1195 | max_ofdm->sent_cts_cnt); | ||
1196 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1197 | fmt_table, "sent_ba_rsp_cnt:", | ||
1198 | le32_to_cpu(ofdm->sent_ba_rsp_cnt), | ||
1199 | accum_ofdm->sent_ba_rsp_cnt, | ||
1200 | delta_ofdm->sent_ba_rsp_cnt, | ||
1201 | max_ofdm->sent_ba_rsp_cnt); | ||
1202 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1203 | fmt_table, "dsp_self_kill:", | ||
1204 | le32_to_cpu(ofdm->dsp_self_kill), | ||
1205 | accum_ofdm->dsp_self_kill, | ||
1206 | delta_ofdm->dsp_self_kill, | ||
1207 | max_ofdm->dsp_self_kill); | ||
1208 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1209 | fmt_table, "mh_format_err:", | ||
1210 | le32_to_cpu(ofdm->mh_format_err), | ||
1211 | accum_ofdm->mh_format_err, | ||
1212 | delta_ofdm->mh_format_err, | ||
1213 | max_ofdm->mh_format_err); | ||
1214 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1215 | fmt_table, "re_acq_main_rssi_sum:", | ||
1216 | le32_to_cpu(ofdm->re_acq_main_rssi_sum), | ||
1217 | accum_ofdm->re_acq_main_rssi_sum, | ||
1218 | delta_ofdm->re_acq_main_rssi_sum, | ||
1219 | max_ofdm->re_acq_main_rssi_sum); | ||
1220 | |||
1221 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1222 | fmt_header, "Statistics_Rx - CCK:"); | ||
1223 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1224 | fmt_table, "ina_cnt:", | ||
1225 | le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, | ||
1226 | delta_cck->ina_cnt, max_cck->ina_cnt); | ||
1227 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1228 | fmt_table, "fina_cnt:", | ||
1229 | le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, | ||
1230 | delta_cck->fina_cnt, max_cck->fina_cnt); | ||
1231 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1232 | fmt_table, "plcp_err:", | ||
1233 | le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, | ||
1234 | delta_cck->plcp_err, max_cck->plcp_err); | ||
1235 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1236 | fmt_table, "crc32_err:", | ||
1237 | le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, | ||
1238 | delta_cck->crc32_err, max_cck->crc32_err); | ||
1239 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1240 | fmt_table, "overrun_err:", | ||
1241 | le32_to_cpu(cck->overrun_err), | ||
1242 | accum_cck->overrun_err, delta_cck->overrun_err, | ||
1243 | max_cck->overrun_err); | ||
1244 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1245 | fmt_table, "early_overrun_err:", | ||
1246 | le32_to_cpu(cck->early_overrun_err), | ||
1247 | accum_cck->early_overrun_err, | ||
1248 | delta_cck->early_overrun_err, | ||
1249 | max_cck->early_overrun_err); | ||
1250 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1251 | fmt_table, "crc32_good:", | ||
1252 | le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, | ||
1253 | delta_cck->crc32_good, max_cck->crc32_good); | ||
1254 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1255 | fmt_table, "false_alarm_cnt:", | ||
1256 | le32_to_cpu(cck->false_alarm_cnt), | ||
1257 | accum_cck->false_alarm_cnt, | ||
1258 | delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); | ||
1259 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1260 | fmt_table, "fina_sync_err_cnt:", | ||
1261 | le32_to_cpu(cck->fina_sync_err_cnt), | ||
1262 | accum_cck->fina_sync_err_cnt, | ||
1263 | delta_cck->fina_sync_err_cnt, | ||
1264 | max_cck->fina_sync_err_cnt); | ||
1265 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1266 | fmt_table, "sfd_timeout:", | ||
1267 | le32_to_cpu(cck->sfd_timeout), | ||
1268 | accum_cck->sfd_timeout, delta_cck->sfd_timeout, | ||
1269 | max_cck->sfd_timeout); | ||
1270 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1271 | fmt_table, "fina_timeout:", | ||
1272 | le32_to_cpu(cck->fina_timeout), | ||
1273 | accum_cck->fina_timeout, delta_cck->fina_timeout, | ||
1274 | max_cck->fina_timeout); | ||
1275 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1276 | fmt_table, "unresponded_rts:", | ||
1277 | le32_to_cpu(cck->unresponded_rts), | ||
1278 | accum_cck->unresponded_rts, delta_cck->unresponded_rts, | ||
1279 | max_cck->unresponded_rts); | ||
1280 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1281 | fmt_table, "rxe_frame_lmt_ovrun:", | ||
1282 | le32_to_cpu(cck->rxe_frame_limit_overrun), | ||
1283 | accum_cck->rxe_frame_limit_overrun, | ||
1284 | delta_cck->rxe_frame_limit_overrun, | ||
1285 | max_cck->rxe_frame_limit_overrun); | ||
1286 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1287 | fmt_table, "sent_ack_cnt:", | ||
1288 | le32_to_cpu(cck->sent_ack_cnt), | ||
1289 | accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt, | ||
1290 | max_cck->sent_ack_cnt); | ||
1291 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1292 | fmt_table, "sent_cts_cnt:", | ||
1293 | le32_to_cpu(cck->sent_cts_cnt), | ||
1294 | accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt, | ||
1295 | max_cck->sent_cts_cnt); | ||
1296 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1297 | fmt_table, "sent_ba_rsp_cnt:", | ||
1298 | le32_to_cpu(cck->sent_ba_rsp_cnt), | ||
1299 | accum_cck->sent_ba_rsp_cnt, | ||
1300 | delta_cck->sent_ba_rsp_cnt, | ||
1301 | max_cck->sent_ba_rsp_cnt); | ||
1302 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1303 | fmt_table, "dsp_self_kill:", | ||
1304 | le32_to_cpu(cck->dsp_self_kill), | ||
1305 | accum_cck->dsp_self_kill, delta_cck->dsp_self_kill, | ||
1306 | max_cck->dsp_self_kill); | ||
1307 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1308 | fmt_table, "mh_format_err:", | ||
1309 | le32_to_cpu(cck->mh_format_err), | ||
1310 | accum_cck->mh_format_err, delta_cck->mh_format_err, | ||
1311 | max_cck->mh_format_err); | ||
1312 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1313 | fmt_table, "re_acq_main_rssi_sum:", | ||
1314 | le32_to_cpu(cck->re_acq_main_rssi_sum), | ||
1315 | accum_cck->re_acq_main_rssi_sum, | ||
1316 | delta_cck->re_acq_main_rssi_sum, | ||
1317 | max_cck->re_acq_main_rssi_sum); | ||
1318 | |||
1319 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1320 | fmt_header, "Statistics_Rx - GENERAL:"); | ||
1321 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1322 | fmt_table, "bogus_cts:", | ||
1323 | le32_to_cpu(general->bogus_cts), | ||
1324 | accum_general->bogus_cts, delta_general->bogus_cts, | ||
1325 | max_general->bogus_cts); | ||
1326 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1327 | fmt_table, "bogus_ack:", | ||
1328 | le32_to_cpu(general->bogus_ack), | ||
1329 | accum_general->bogus_ack, delta_general->bogus_ack, | ||
1330 | max_general->bogus_ack); | ||
1331 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1332 | fmt_table, "non_bssid_frames:", | ||
1333 | le32_to_cpu(general->non_bssid_frames), | ||
1334 | accum_general->non_bssid_frames, | ||
1335 | delta_general->non_bssid_frames, | ||
1336 | max_general->non_bssid_frames); | ||
1337 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1338 | fmt_table, "filtered_frames:", | ||
1339 | le32_to_cpu(general->filtered_frames), | ||
1340 | accum_general->filtered_frames, | ||
1341 | delta_general->filtered_frames, | ||
1342 | max_general->filtered_frames); | ||
1343 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1344 | fmt_table, "non_channel_beacons:", | ||
1345 | le32_to_cpu(general->non_channel_beacons), | ||
1346 | accum_general->non_channel_beacons, | ||
1347 | delta_general->non_channel_beacons, | ||
1348 | max_general->non_channel_beacons); | ||
1349 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1350 | fmt_table, "channel_beacons:", | ||
1351 | le32_to_cpu(general->channel_beacons), | ||
1352 | accum_general->channel_beacons, | ||
1353 | delta_general->channel_beacons, | ||
1354 | max_general->channel_beacons); | ||
1355 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1356 | fmt_table, "num_missed_bcon:", | ||
1357 | le32_to_cpu(general->num_missed_bcon), | ||
1358 | accum_general->num_missed_bcon, | ||
1359 | delta_general->num_missed_bcon, | ||
1360 | max_general->num_missed_bcon); | ||
1361 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1362 | fmt_table, "adc_rx_saturation_time:", | ||
1363 | le32_to_cpu(general->adc_rx_saturation_time), | ||
1364 | accum_general->adc_rx_saturation_time, | ||
1365 | delta_general->adc_rx_saturation_time, | ||
1366 | max_general->adc_rx_saturation_time); | ||
1367 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1368 | fmt_table, "ina_detect_search_tm:", | ||
1369 | le32_to_cpu(general->ina_detection_search_time), | ||
1370 | accum_general->ina_detection_search_time, | ||
1371 | delta_general->ina_detection_search_time, | ||
1372 | max_general->ina_detection_search_time); | ||
1373 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1374 | fmt_table, "beacon_silence_rssi_a:", | ||
1375 | le32_to_cpu(general->beacon_silence_rssi_a), | ||
1376 | accum_general->beacon_silence_rssi_a, | ||
1377 | delta_general->beacon_silence_rssi_a, | ||
1378 | max_general->beacon_silence_rssi_a); | ||
1379 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1380 | fmt_table, "beacon_silence_rssi_b:", | ||
1381 | le32_to_cpu(general->beacon_silence_rssi_b), | ||
1382 | accum_general->beacon_silence_rssi_b, | ||
1383 | delta_general->beacon_silence_rssi_b, | ||
1384 | max_general->beacon_silence_rssi_b); | ||
1385 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1386 | fmt_table, "beacon_silence_rssi_c:", | ||
1387 | le32_to_cpu(general->beacon_silence_rssi_c), | ||
1388 | accum_general->beacon_silence_rssi_c, | ||
1389 | delta_general->beacon_silence_rssi_c, | ||
1390 | max_general->beacon_silence_rssi_c); | ||
1391 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1392 | fmt_table, "interference_data_flag:", | ||
1393 | le32_to_cpu(general->interference_data_flag), | ||
1394 | accum_general->interference_data_flag, | ||
1395 | delta_general->interference_data_flag, | ||
1396 | max_general->interference_data_flag); | ||
1397 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1398 | fmt_table, "channel_load:", | ||
1399 | le32_to_cpu(general->channel_load), | ||
1400 | accum_general->channel_load, | ||
1401 | delta_general->channel_load, | ||
1402 | max_general->channel_load); | ||
1403 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1404 | fmt_table, "dsp_false_alarms:", | ||
1405 | le32_to_cpu(general->dsp_false_alarms), | ||
1406 | accum_general->dsp_false_alarms, | ||
1407 | delta_general->dsp_false_alarms, | ||
1408 | max_general->dsp_false_alarms); | ||
1409 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1410 | fmt_table, "beacon_rssi_a:", | ||
1411 | le32_to_cpu(general->beacon_rssi_a), | ||
1412 | accum_general->beacon_rssi_a, | ||
1413 | delta_general->beacon_rssi_a, | ||
1414 | max_general->beacon_rssi_a); | ||
1415 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1416 | fmt_table, "beacon_rssi_b:", | ||
1417 | le32_to_cpu(general->beacon_rssi_b), | ||
1418 | accum_general->beacon_rssi_b, | ||
1419 | delta_general->beacon_rssi_b, | ||
1420 | max_general->beacon_rssi_b); | ||
1421 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1422 | fmt_table, "beacon_rssi_c:", | ||
1423 | le32_to_cpu(general->beacon_rssi_c), | ||
1424 | accum_general->beacon_rssi_c, | ||
1425 | delta_general->beacon_rssi_c, | ||
1426 | max_general->beacon_rssi_c); | ||
1427 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1428 | fmt_table, "beacon_energy_a:", | ||
1429 | le32_to_cpu(general->beacon_energy_a), | ||
1430 | accum_general->beacon_energy_a, | ||
1431 | delta_general->beacon_energy_a, | ||
1432 | max_general->beacon_energy_a); | ||
1433 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1434 | fmt_table, "beacon_energy_b:", | ||
1435 | le32_to_cpu(general->beacon_energy_b), | ||
1436 | accum_general->beacon_energy_b, | ||
1437 | delta_general->beacon_energy_b, | ||
1438 | max_general->beacon_energy_b); | ||
1439 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1440 | fmt_table, "beacon_energy_c:", | ||
1441 | le32_to_cpu(general->beacon_energy_c), | ||
1442 | accum_general->beacon_energy_c, | ||
1443 | delta_general->beacon_energy_c, | ||
1444 | max_general->beacon_energy_c); | ||
1445 | |||
1446 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1447 | fmt_header, "Statistics_Rx - OFDM_HT:"); | ||
1448 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1449 | fmt_table, "plcp_err:", | ||
1450 | le32_to_cpu(ht->plcp_err), accum_ht->plcp_err, | ||
1451 | delta_ht->plcp_err, max_ht->plcp_err); | ||
1452 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1453 | fmt_table, "overrun_err:", | ||
1454 | le32_to_cpu(ht->overrun_err), accum_ht->overrun_err, | ||
1455 | delta_ht->overrun_err, max_ht->overrun_err); | ||
1456 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1457 | fmt_table, "early_overrun_err:", | ||
1458 | le32_to_cpu(ht->early_overrun_err), | ||
1459 | accum_ht->early_overrun_err, | ||
1460 | delta_ht->early_overrun_err, | ||
1461 | max_ht->early_overrun_err); | ||
1462 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1463 | fmt_table, "crc32_good:", | ||
1464 | le32_to_cpu(ht->crc32_good), accum_ht->crc32_good, | ||
1465 | delta_ht->crc32_good, max_ht->crc32_good); | ||
1466 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1467 | fmt_table, "crc32_err:", | ||
1468 | le32_to_cpu(ht->crc32_err), accum_ht->crc32_err, | ||
1469 | delta_ht->crc32_err, max_ht->crc32_err); | ||
1470 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1471 | fmt_table, "mh_format_err:", | ||
1472 | le32_to_cpu(ht->mh_format_err), | ||
1473 | accum_ht->mh_format_err, | ||
1474 | delta_ht->mh_format_err, max_ht->mh_format_err); | ||
1475 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1476 | fmt_table, "agg_crc32_good:", | ||
1477 | le32_to_cpu(ht->agg_crc32_good), | ||
1478 | accum_ht->agg_crc32_good, | ||
1479 | delta_ht->agg_crc32_good, max_ht->agg_crc32_good); | ||
1480 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1481 | fmt_table, "agg_mpdu_cnt:", | ||
1482 | le32_to_cpu(ht->agg_mpdu_cnt), | ||
1483 | accum_ht->agg_mpdu_cnt, | ||
1484 | delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt); | ||
1485 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1486 | fmt_table, "agg_cnt:", | ||
1487 | le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt, | ||
1488 | delta_ht->agg_cnt, max_ht->agg_cnt); | ||
1489 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1490 | fmt_table, "unsupport_mcs:", | ||
1491 | le32_to_cpu(ht->unsupport_mcs), | ||
1492 | accum_ht->unsupport_mcs, | ||
1493 | delta_ht->unsupport_mcs, max_ht->unsupport_mcs); | ||
1494 | |||
1495 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
1496 | kfree(buf); | ||
1497 | return ret; | ||
1047 | } | 1498 | } |
1048 | 1499 | ||
1049 | static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | 1500 | static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, |
@@ -1051,8 +1502,190 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1051 | size_t count, loff_t *ppos) | 1502 | size_t count, loff_t *ppos) |
1052 | { | 1503 | { |
1053 | struct iwl_priv *priv = file->private_data; | 1504 | struct iwl_priv *priv = file->private_data; |
1054 | return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file, | 1505 | int pos = 0; |
1055 | user_buf, count, ppos); | 1506 | char *buf; |
1507 | int bufsz = (sizeof(struct statistics_tx) * 48) + 250; | ||
1508 | ssize_t ret; | ||
1509 | struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; | ||
1510 | |||
1511 | if (!iwl_is_alive(priv)) | ||
1512 | return -EAGAIN; | ||
1513 | |||
1514 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
1515 | if (!buf) { | ||
1516 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
1517 | return -ENOMEM; | ||
1518 | } | ||
1519 | |||
1520 | /* the statistic information display here is based on | ||
1521 | * the last statistics notification from uCode | ||
1522 | * might not reflect the current uCode activity | ||
1523 | */ | ||
1524 | tx = &priv->statistics.tx; | ||
1525 | accum_tx = &priv->accum_stats.tx; | ||
1526 | delta_tx = &priv->delta_stats.tx; | ||
1527 | max_tx = &priv->max_delta_stats.tx; | ||
1528 | |||
1529 | pos += iwl_statistics_flag(priv, buf, bufsz); | ||
1530 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1531 | fmt_header, "Statistics_Tx:"); | ||
1532 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1533 | fmt_table, "preamble:", | ||
1534 | le32_to_cpu(tx->preamble_cnt), | ||
1535 | accum_tx->preamble_cnt, | ||
1536 | delta_tx->preamble_cnt, max_tx->preamble_cnt); | ||
1537 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1538 | fmt_table, "rx_detected_cnt:", | ||
1539 | le32_to_cpu(tx->rx_detected_cnt), | ||
1540 | accum_tx->rx_detected_cnt, | ||
1541 | delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); | ||
1542 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1543 | fmt_table, "bt_prio_defer_cnt:", | ||
1544 | le32_to_cpu(tx->bt_prio_defer_cnt), | ||
1545 | accum_tx->bt_prio_defer_cnt, | ||
1546 | delta_tx->bt_prio_defer_cnt, | ||
1547 | max_tx->bt_prio_defer_cnt); | ||
1548 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1549 | fmt_table, "bt_prio_kill_cnt:", | ||
1550 | le32_to_cpu(tx->bt_prio_kill_cnt), | ||
1551 | accum_tx->bt_prio_kill_cnt, | ||
1552 | delta_tx->bt_prio_kill_cnt, | ||
1553 | max_tx->bt_prio_kill_cnt); | ||
1554 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1555 | fmt_table, "few_bytes_cnt:", | ||
1556 | le32_to_cpu(tx->few_bytes_cnt), | ||
1557 | accum_tx->few_bytes_cnt, | ||
1558 | delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); | ||
1559 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1560 | fmt_table, "cts_timeout:", | ||
1561 | le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, | ||
1562 | delta_tx->cts_timeout, max_tx->cts_timeout); | ||
1563 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1564 | fmt_table, "ack_timeout:", | ||
1565 | le32_to_cpu(tx->ack_timeout), | ||
1566 | accum_tx->ack_timeout, | ||
1567 | delta_tx->ack_timeout, max_tx->ack_timeout); | ||
1568 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1569 | fmt_table, "expected_ack_cnt:", | ||
1570 | le32_to_cpu(tx->expected_ack_cnt), | ||
1571 | accum_tx->expected_ack_cnt, | ||
1572 | delta_tx->expected_ack_cnt, | ||
1573 | max_tx->expected_ack_cnt); | ||
1574 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1575 | fmt_table, "actual_ack_cnt:", | ||
1576 | le32_to_cpu(tx->actual_ack_cnt), | ||
1577 | accum_tx->actual_ack_cnt, | ||
1578 | delta_tx->actual_ack_cnt, | ||
1579 | max_tx->actual_ack_cnt); | ||
1580 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1581 | fmt_table, "dump_msdu_cnt:", | ||
1582 | le32_to_cpu(tx->dump_msdu_cnt), | ||
1583 | accum_tx->dump_msdu_cnt, | ||
1584 | delta_tx->dump_msdu_cnt, | ||
1585 | max_tx->dump_msdu_cnt); | ||
1586 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1587 | fmt_table, "abort_nxt_frame_mismatch:", | ||
1588 | le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), | ||
1589 | accum_tx->burst_abort_next_frame_mismatch_cnt, | ||
1590 | delta_tx->burst_abort_next_frame_mismatch_cnt, | ||
1591 | max_tx->burst_abort_next_frame_mismatch_cnt); | ||
1592 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1593 | fmt_table, "abort_missing_nxt_frame:", | ||
1594 | le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), | ||
1595 | accum_tx->burst_abort_missing_next_frame_cnt, | ||
1596 | delta_tx->burst_abort_missing_next_frame_cnt, | ||
1597 | max_tx->burst_abort_missing_next_frame_cnt); | ||
1598 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1599 | fmt_table, "cts_timeout_collision:", | ||
1600 | le32_to_cpu(tx->cts_timeout_collision), | ||
1601 | accum_tx->cts_timeout_collision, | ||
1602 | delta_tx->cts_timeout_collision, | ||
1603 | max_tx->cts_timeout_collision); | ||
1604 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1605 | fmt_table, "ack_ba_timeout_collision:", | ||
1606 | le32_to_cpu(tx->ack_or_ba_timeout_collision), | ||
1607 | accum_tx->ack_or_ba_timeout_collision, | ||
1608 | delta_tx->ack_or_ba_timeout_collision, | ||
1609 | max_tx->ack_or_ba_timeout_collision); | ||
1610 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1611 | fmt_table, "agg ba_timeout:", | ||
1612 | le32_to_cpu(tx->agg.ba_timeout), | ||
1613 | accum_tx->agg.ba_timeout, | ||
1614 | delta_tx->agg.ba_timeout, | ||
1615 | max_tx->agg.ba_timeout); | ||
1616 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1617 | fmt_table, "agg ba_resched_frames:", | ||
1618 | le32_to_cpu(tx->agg.ba_reschedule_frames), | ||
1619 | accum_tx->agg.ba_reschedule_frames, | ||
1620 | delta_tx->agg.ba_reschedule_frames, | ||
1621 | max_tx->agg.ba_reschedule_frames); | ||
1622 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1623 | fmt_table, "agg scd_query_agg_frame:", | ||
1624 | le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), | ||
1625 | accum_tx->agg.scd_query_agg_frame_cnt, | ||
1626 | delta_tx->agg.scd_query_agg_frame_cnt, | ||
1627 | max_tx->agg.scd_query_agg_frame_cnt); | ||
1628 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1629 | fmt_table, "agg scd_query_no_agg:", | ||
1630 | le32_to_cpu(tx->agg.scd_query_no_agg), | ||
1631 | accum_tx->agg.scd_query_no_agg, | ||
1632 | delta_tx->agg.scd_query_no_agg, | ||
1633 | max_tx->agg.scd_query_no_agg); | ||
1634 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1635 | fmt_table, "agg scd_query_agg:", | ||
1636 | le32_to_cpu(tx->agg.scd_query_agg), | ||
1637 | accum_tx->agg.scd_query_agg, | ||
1638 | delta_tx->agg.scd_query_agg, | ||
1639 | max_tx->agg.scd_query_agg); | ||
1640 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1641 | fmt_table, "agg scd_query_mismatch:", | ||
1642 | le32_to_cpu(tx->agg.scd_query_mismatch), | ||
1643 | accum_tx->agg.scd_query_mismatch, | ||
1644 | delta_tx->agg.scd_query_mismatch, | ||
1645 | max_tx->agg.scd_query_mismatch); | ||
1646 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1647 | fmt_table, "agg frame_not_ready:", | ||
1648 | le32_to_cpu(tx->agg.frame_not_ready), | ||
1649 | accum_tx->agg.frame_not_ready, | ||
1650 | delta_tx->agg.frame_not_ready, | ||
1651 | max_tx->agg.frame_not_ready); | ||
1652 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1653 | fmt_table, "agg underrun:", | ||
1654 | le32_to_cpu(tx->agg.underrun), | ||
1655 | accum_tx->agg.underrun, | ||
1656 | delta_tx->agg.underrun, max_tx->agg.underrun); | ||
1657 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1658 | fmt_table, "agg bt_prio_kill:", | ||
1659 | le32_to_cpu(tx->agg.bt_prio_kill), | ||
1660 | accum_tx->agg.bt_prio_kill, | ||
1661 | delta_tx->agg.bt_prio_kill, | ||
1662 | max_tx->agg.bt_prio_kill); | ||
1663 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1664 | fmt_table, "agg rx_ba_rsp_cnt:", | ||
1665 | le32_to_cpu(tx->agg.rx_ba_rsp_cnt), | ||
1666 | accum_tx->agg.rx_ba_rsp_cnt, | ||
1667 | delta_tx->agg.rx_ba_rsp_cnt, | ||
1668 | max_tx->agg.rx_ba_rsp_cnt); | ||
1669 | |||
1670 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { | ||
1671 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1672 | "tx power: (1/2 dB step)\n"); | ||
1673 | if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) | ||
1674 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1675 | fmt_hex, "antenna A:", | ||
1676 | tx->tx_power.ant_a); | ||
1677 | if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) | ||
1678 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1679 | fmt_hex, "antenna B:", | ||
1680 | tx->tx_power.ant_b); | ||
1681 | if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) | ||
1682 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1683 | fmt_hex, "antenna C:", | ||
1684 | tx->tx_power.ant_c); | ||
1685 | } | ||
1686 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
1687 | kfree(buf); | ||
1688 | return ret; | ||
1056 | } | 1689 | } |
1057 | 1690 | ||
1058 | static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | 1691 | static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, |
@@ -1060,8 +1693,347 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1060 | size_t count, loff_t *ppos) | 1693 | size_t count, loff_t *ppos) |
1061 | { | 1694 | { |
1062 | struct iwl_priv *priv = file->private_data; | 1695 | struct iwl_priv *priv = file->private_data; |
1063 | return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file, | 1696 | int pos = 0; |
1064 | user_buf, count, ppos); | 1697 | char *buf; |
1698 | int bufsz = sizeof(struct statistics_general) * 10 + 300; | ||
1699 | ssize_t ret; | ||
1700 | struct statistics_general_common *general, *accum_general; | ||
1701 | struct statistics_general_common *delta_general, *max_general; | ||
1702 | struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; | ||
1703 | struct statistics_div *div, *accum_div, *delta_div, *max_div; | ||
1704 | |||
1705 | if (!iwl_is_alive(priv)) | ||
1706 | return -EAGAIN; | ||
1707 | |||
1708 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
1709 | if (!buf) { | ||
1710 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
1711 | return -ENOMEM; | ||
1712 | } | ||
1713 | |||
1714 | /* the statistic information display here is based on | ||
1715 | * the last statistics notification from uCode | ||
1716 | * might not reflect the current uCode activity | ||
1717 | */ | ||
1718 | general = &priv->statistics.common; | ||
1719 | dbg = &priv->statistics.common.dbg; | ||
1720 | div = &priv->statistics.common.div; | ||
1721 | accum_general = &priv->accum_stats.common; | ||
1722 | accum_dbg = &priv->accum_stats.common.dbg; | ||
1723 | accum_div = &priv->accum_stats.common.div; | ||
1724 | delta_general = &priv->delta_stats.common; | ||
1725 | max_general = &priv->max_delta_stats.common; | ||
1726 | delta_dbg = &priv->delta_stats.common.dbg; | ||
1727 | max_dbg = &priv->max_delta_stats.common.dbg; | ||
1728 | delta_div = &priv->delta_stats.common.div; | ||
1729 | max_div = &priv->max_delta_stats.common.div; | ||
1730 | |||
1731 | pos += iwl_statistics_flag(priv, buf, bufsz); | ||
1732 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1733 | fmt_header, "Statistics_General:"); | ||
1734 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1735 | fmt_value, "temperature:", | ||
1736 | le32_to_cpu(general->temperature)); | ||
1737 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1738 | fmt_value, "temperature_m:", | ||
1739 | le32_to_cpu(general->temperature_m)); | ||
1740 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1741 | fmt_value, "ttl_timestamp:", | ||
1742 | le32_to_cpu(general->ttl_timestamp)); | ||
1743 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1744 | fmt_table, "burst_check:", | ||
1745 | le32_to_cpu(dbg->burst_check), | ||
1746 | accum_dbg->burst_check, | ||
1747 | delta_dbg->burst_check, max_dbg->burst_check); | ||
1748 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1749 | fmt_table, "burst_count:", | ||
1750 | le32_to_cpu(dbg->burst_count), | ||
1751 | accum_dbg->burst_count, | ||
1752 | delta_dbg->burst_count, max_dbg->burst_count); | ||
1753 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1754 | fmt_table, "wait_for_silence_timeout_count:", | ||
1755 | le32_to_cpu(dbg->wait_for_silence_timeout_cnt), | ||
1756 | accum_dbg->wait_for_silence_timeout_cnt, | ||
1757 | delta_dbg->wait_for_silence_timeout_cnt, | ||
1758 | max_dbg->wait_for_silence_timeout_cnt); | ||
1759 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1760 | fmt_table, "sleep_time:", | ||
1761 | le32_to_cpu(general->sleep_time), | ||
1762 | accum_general->sleep_time, | ||
1763 | delta_general->sleep_time, max_general->sleep_time); | ||
1764 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1765 | fmt_table, "slots_out:", | ||
1766 | le32_to_cpu(general->slots_out), | ||
1767 | accum_general->slots_out, | ||
1768 | delta_general->slots_out, max_general->slots_out); | ||
1769 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1770 | fmt_table, "slots_idle:", | ||
1771 | le32_to_cpu(general->slots_idle), | ||
1772 | accum_general->slots_idle, | ||
1773 | delta_general->slots_idle, max_general->slots_idle); | ||
1774 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1775 | fmt_table, "tx_on_a:", | ||
1776 | le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, | ||
1777 | delta_div->tx_on_a, max_div->tx_on_a); | ||
1778 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1779 | fmt_table, "tx_on_b:", | ||
1780 | le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, | ||
1781 | delta_div->tx_on_b, max_div->tx_on_b); | ||
1782 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1783 | fmt_table, "exec_time:", | ||
1784 | le32_to_cpu(div->exec_time), accum_div->exec_time, | ||
1785 | delta_div->exec_time, max_div->exec_time); | ||
1786 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1787 | fmt_table, "probe_time:", | ||
1788 | le32_to_cpu(div->probe_time), accum_div->probe_time, | ||
1789 | delta_div->probe_time, max_div->probe_time); | ||
1790 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1791 | fmt_table, "rx_enable_counter:", | ||
1792 | le32_to_cpu(general->rx_enable_counter), | ||
1793 | accum_general->rx_enable_counter, | ||
1794 | delta_general->rx_enable_counter, | ||
1795 | max_general->rx_enable_counter); | ||
1796 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1797 | fmt_table, "num_of_sos_states:", | ||
1798 | le32_to_cpu(general->num_of_sos_states), | ||
1799 | accum_general->num_of_sos_states, | ||
1800 | delta_general->num_of_sos_states, | ||
1801 | max_general->num_of_sos_states); | ||
1802 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
1803 | kfree(buf); | ||
1804 | return ret; | ||
1805 | } | ||
1806 | |||
1807 | static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | ||
1808 | char __user *user_buf, | ||
1809 | size_t count, loff_t *ppos) | ||
1810 | { | ||
1811 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
1812 | int pos = 0; | ||
1813 | char *buf; | ||
1814 | int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200; | ||
1815 | ssize_t ret; | ||
1816 | struct statistics_bt_activity *bt, *accum_bt; | ||
1817 | |||
1818 | if (!iwl_is_alive(priv)) | ||
1819 | return -EAGAIN; | ||
1820 | |||
1821 | if (!priv->bt_enable_flag) | ||
1822 | return -EINVAL; | ||
1823 | |||
1824 | /* make request to uCode to retrieve statistics information */ | ||
1825 | mutex_lock(&priv->mutex); | ||
1826 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); | ||
1827 | mutex_unlock(&priv->mutex); | ||
1828 | |||
1829 | if (ret) { | ||
1830 | IWL_ERR(priv, | ||
1831 | "Error sending statistics request: %zd\n", ret); | ||
1832 | return -EAGAIN; | ||
1833 | } | ||
1834 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
1835 | if (!buf) { | ||
1836 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
1837 | return -ENOMEM; | ||
1838 | } | ||
1839 | |||
1840 | /* | ||
1841 | * the statistic information display here is based on | ||
1842 | * the last statistics notification from uCode | ||
1843 | * might not reflect the current uCode activity | ||
1844 | */ | ||
1845 | bt = &priv->statistics.bt_activity; | ||
1846 | accum_bt = &priv->accum_stats.bt_activity; | ||
1847 | |||
1848 | pos += iwl_statistics_flag(priv, buf, bufsz); | ||
1849 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); | ||
1850 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1851 | "\t\t\tcurrent\t\t\taccumulative\n"); | ||
1852 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1853 | "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", | ||
1854 | le32_to_cpu(bt->hi_priority_tx_req_cnt), | ||
1855 | accum_bt->hi_priority_tx_req_cnt); | ||
1856 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1857 | "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n", | ||
1858 | le32_to_cpu(bt->hi_priority_tx_denied_cnt), | ||
1859 | accum_bt->hi_priority_tx_denied_cnt); | ||
1860 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1861 | "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", | ||
1862 | le32_to_cpu(bt->lo_priority_tx_req_cnt), | ||
1863 | accum_bt->lo_priority_tx_req_cnt); | ||
1864 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1865 | "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n", | ||
1866 | le32_to_cpu(bt->lo_priority_tx_denied_cnt), | ||
1867 | accum_bt->lo_priority_tx_denied_cnt); | ||
1868 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1869 | "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", | ||
1870 | le32_to_cpu(bt->hi_priority_rx_req_cnt), | ||
1871 | accum_bt->hi_priority_rx_req_cnt); | ||
1872 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1873 | "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n", | ||
1874 | le32_to_cpu(bt->hi_priority_rx_denied_cnt), | ||
1875 | accum_bt->hi_priority_rx_denied_cnt); | ||
1876 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1877 | "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", | ||
1878 | le32_to_cpu(bt->lo_priority_rx_req_cnt), | ||
1879 | accum_bt->lo_priority_rx_req_cnt); | ||
1880 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1881 | "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", | ||
1882 | le32_to_cpu(bt->lo_priority_rx_denied_cnt), | ||
1883 | accum_bt->lo_priority_rx_denied_cnt); | ||
1884 | |||
1885 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1886 | "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", | ||
1887 | le32_to_cpu(priv->statistics.num_bt_kills), | ||
1888 | priv->statistics.accum_num_bt_kills); | ||
1889 | |||
1890 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
1891 | kfree(buf); | ||
1892 | return ret; | ||
1893 | } | ||
1894 | |||
1895 | static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, | ||
1896 | char __user *user_buf, | ||
1897 | size_t count, loff_t *ppos) | ||
1898 | { | ||
1899 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
1900 | int pos = 0; | ||
1901 | char *buf; | ||
1902 | int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) + | ||
1903 | (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; | ||
1904 | ssize_t ret; | ||
1905 | |||
1906 | if (!iwl_is_alive(priv)) | ||
1907 | return -EAGAIN; | ||
1908 | |||
1909 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
1910 | if (!buf) { | ||
1911 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
1912 | return -ENOMEM; | ||
1913 | } | ||
1914 | |||
1915 | pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n"); | ||
1916 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n", | ||
1917 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY), | ||
1918 | priv->_agn.reply_tx_stats.pp_delay); | ||
1919 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1920 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES), | ||
1921 | priv->_agn.reply_tx_stats.pp_few_bytes); | ||
1922 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1923 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO), | ||
1924 | priv->_agn.reply_tx_stats.pp_bt_prio); | ||
1925 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1926 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD), | ||
1927 | priv->_agn.reply_tx_stats.pp_quiet_period); | ||
1928 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1929 | iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK), | ||
1930 | priv->_agn.reply_tx_stats.pp_calc_ttak); | ||
1931 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
1932 | iwl_get_tx_fail_reason( | ||
1933 | TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY), | ||
1934 | priv->_agn.reply_tx_stats.int_crossed_retry); | ||
1935 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1936 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT), | ||
1937 | priv->_agn.reply_tx_stats.short_limit); | ||
1938 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1939 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT), | ||
1940 | priv->_agn.reply_tx_stats.long_limit); | ||
1941 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1942 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN), | ||
1943 | priv->_agn.reply_tx_stats.fifo_underrun); | ||
1944 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1945 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW), | ||
1946 | priv->_agn.reply_tx_stats.drain_flow); | ||
1947 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1948 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH), | ||
1949 | priv->_agn.reply_tx_stats.rfkill_flush); | ||
1950 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1951 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE), | ||
1952 | priv->_agn.reply_tx_stats.life_expire); | ||
1953 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1954 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS), | ||
1955 | priv->_agn.reply_tx_stats.dest_ps); | ||
1956 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1957 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED), | ||
1958 | priv->_agn.reply_tx_stats.host_abort); | ||
1959 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1960 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY), | ||
1961 | priv->_agn.reply_tx_stats.pp_delay); | ||
1962 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1963 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID), | ||
1964 | priv->_agn.reply_tx_stats.sta_invalid); | ||
1965 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1966 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED), | ||
1967 | priv->_agn.reply_tx_stats.frag_drop); | ||
1968 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1969 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE), | ||
1970 | priv->_agn.reply_tx_stats.tid_disable); | ||
1971 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1972 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED), | ||
1973 | priv->_agn.reply_tx_stats.fifo_flush); | ||
1974 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
1975 | iwl_get_tx_fail_reason( | ||
1976 | TX_STATUS_FAIL_INSUFFICIENT_CF_POLL), | ||
1977 | priv->_agn.reply_tx_stats.insuff_cf_poll); | ||
1978 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1979 | iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX), | ||
1980 | priv->_agn.reply_tx_stats.fail_hw_drop); | ||
1981 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
1982 | iwl_get_tx_fail_reason( | ||
1983 | TX_STATUS_FAIL_NO_BEACON_ON_RADAR), | ||
1984 | priv->_agn.reply_tx_stats.sta_color_mismatch); | ||
1985 | pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", | ||
1986 | priv->_agn.reply_tx_stats.unknown); | ||
1987 | |||
1988 | pos += scnprintf(buf + pos, bufsz - pos, | ||
1989 | "\nStatistics_Agg_TX_Error:\n"); | ||
1990 | |||
1991 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1992 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK), | ||
1993 | priv->_agn.reply_agg_tx_stats.underrun); | ||
1994 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1995 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK), | ||
1996 | priv->_agn.reply_agg_tx_stats.bt_prio); | ||
1997 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
1998 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK), | ||
1999 | priv->_agn.reply_agg_tx_stats.few_bytes); | ||
2000 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
2001 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK), | ||
2002 | priv->_agn.reply_agg_tx_stats.abort); | ||
2003 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
2004 | iwl_get_agg_tx_fail_reason( | ||
2005 | AGG_TX_STATE_LAST_SENT_TTL_MSK), | ||
2006 | priv->_agn.reply_agg_tx_stats.last_sent_ttl); | ||
2007 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
2008 | iwl_get_agg_tx_fail_reason( | ||
2009 | AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK), | ||
2010 | priv->_agn.reply_agg_tx_stats.last_sent_try); | ||
2011 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
2012 | iwl_get_agg_tx_fail_reason( | ||
2013 | AGG_TX_STATE_LAST_SENT_BT_KILL_MSK), | ||
2014 | priv->_agn.reply_agg_tx_stats.last_sent_bt_kill); | ||
2015 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
2016 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK), | ||
2017 | priv->_agn.reply_agg_tx_stats.scd_query); | ||
2018 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", | ||
2019 | iwl_get_agg_tx_fail_reason( | ||
2020 | AGG_TX_STATE_TEST_BAD_CRC32_MSK), | ||
2021 | priv->_agn.reply_agg_tx_stats.bad_crc32); | ||
2022 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
2023 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK), | ||
2024 | priv->_agn.reply_agg_tx_stats.response); | ||
2025 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
2026 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK), | ||
2027 | priv->_agn.reply_agg_tx_stats.dump_tx); | ||
2028 | pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", | ||
2029 | iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK), | ||
2030 | priv->_agn.reply_agg_tx_stats.delay_tx); | ||
2031 | pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", | ||
2032 | priv->_agn.reply_agg_tx_stats.unknown); | ||
2033 | |||
2034 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
2035 | kfree(buf); | ||
2036 | return ret; | ||
1065 | } | 2037 | } |
1066 | 2038 | ||
1067 | static ssize_t iwl_dbgfs_sensitivity_read(struct file *file, | 2039 | static ssize_t iwl_dbgfs_sensitivity_read(struct file *file, |
@@ -1526,16 +2498,6 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, | |||
1526 | return count; | 2498 | return count; |
1527 | } | 2499 | } |
1528 | 2500 | ||
1529 | static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | ||
1530 | char __user *user_buf, | ||
1531 | size_t count, loff_t *ppos) | ||
1532 | { | ||
1533 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
1534 | |||
1535 | return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file, | ||
1536 | user_buf, count, ppos); | ||
1537 | } | ||
1538 | |||
1539 | static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, | 2501 | static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, |
1540 | const char __user *user_buf, | 2502 | const char __user *user_buf, |
1541 | size_t count, loff_t *ppos) { | 2503 | size_t count, loff_t *ppos) { |
@@ -1650,18 +2612,6 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, | |||
1650 | return count; | 2612 | return count; |
1651 | } | 2613 | } |
1652 | 2614 | ||
1653 | static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, | ||
1654 | char __user *user_buf, | ||
1655 | size_t count, loff_t *ppos) | ||
1656 | { | ||
1657 | struct iwl_priv *priv = file->private_data; | ||
1658 | |||
1659 | if (priv->cfg->ops->lib->debugfs_ops.reply_tx_error) | ||
1660 | return priv->cfg->ops->lib->debugfs_ops.reply_tx_error( | ||
1661 | file, user_buf, count, ppos); | ||
1662 | else | ||
1663 | return -ENODATA; | ||
1664 | } | ||
1665 | DEBUGFS_READ_FILE_OPS(rx_statistics); | 2615 | DEBUGFS_READ_FILE_OPS(rx_statistics); |
1666 | DEBUGFS_READ_FILE_OPS(tx_statistics); | 2616 | DEBUGFS_READ_FILE_OPS(tx_statistics); |
1667 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | 2617 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e84534c4d956..f098eff263f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -479,6 +479,10 @@ struct fw_desc { | |||
479 | u32 len; /* bytes */ | 479 | u32 len; /* bytes */ |
480 | }; | 480 | }; |
481 | 481 | ||
482 | struct fw_img { | ||
483 | struct fw_desc code, data; | ||
484 | }; | ||
485 | |||
482 | /* v1/v2 uCode file layout */ | 486 | /* v1/v2 uCode file layout */ |
483 | struct iwl_ucode_header { | 487 | struct iwl_ucode_header { |
484 | __le32 ver; /* major/minor/API/serial */ | 488 | __le32 ver; /* major/minor/API/serial */ |
@@ -543,12 +547,13 @@ enum iwl_ucode_tlv_type { | |||
543 | * enum iwl_ucode_tlv_flag - ucode API flags | 547 | * enum iwl_ucode_tlv_flag - ucode API flags |
544 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | 548 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously |
545 | * was a separate TLV but moved here to save space. | 549 | * was a separate TLV but moved here to save space. |
546 | * @IWL_UCODE_TLV_FLAGS_RESERVED_1: reserved | 550 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, |
551 | * treats good CRC threshold as a boolean | ||
547 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | 552 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). |
548 | */ | 553 | */ |
549 | enum iwl_ucode_tlv_flag { | 554 | enum iwl_ucode_tlv_flag { |
550 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | 555 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), |
551 | IWL_UCODE_TLV_FLAGS_RESERVED_1 = BIT(1), | 556 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), |
552 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | 557 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), |
553 | }; | 558 | }; |
554 | 559 | ||
@@ -794,12 +799,6 @@ struct iwl_calib_result { | |||
794 | size_t buf_len; | 799 | size_t buf_len; |
795 | }; | 800 | }; |
796 | 801 | ||
797 | enum ucode_type { | ||
798 | UCODE_NONE = 0, | ||
799 | UCODE_INIT, | ||
800 | UCODE_RT | ||
801 | }; | ||
802 | |||
803 | /* Sensitivity calib data */ | 802 | /* Sensitivity calib data */ |
804 | struct iwl_sensitivity_data { | 803 | struct iwl_sensitivity_data { |
805 | u32 auto_corr_ofdm; | 804 | u32 auto_corr_ofdm; |
@@ -1105,10 +1104,12 @@ struct iwl_force_reset { | |||
1105 | struct iwl_notification_wait { | 1104 | struct iwl_notification_wait { |
1106 | struct list_head list; | 1105 | struct list_head list; |
1107 | 1106 | ||
1108 | void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt); | 1107 | void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt, |
1108 | void *data); | ||
1109 | void *fn_data; | ||
1109 | 1110 | ||
1110 | u8 cmd; | 1111 | u8 cmd; |
1111 | bool triggered; | 1112 | bool triggered, aborted; |
1112 | }; | 1113 | }; |
1113 | 1114 | ||
1114 | enum iwl_rxon_context_id { | 1115 | enum iwl_rxon_context_id { |
@@ -1263,6 +1264,8 @@ struct iwl_priv { | |||
1263 | /* max number of station keys */ | 1264 | /* max number of station keys */ |
1264 | u8 sta_key_max_num; | 1265 | u8 sta_key_max_num; |
1265 | 1266 | ||
1267 | bool new_scan_threshold_behaviour; | ||
1268 | |||
1266 | /* EEPROM MAC addresses */ | 1269 | /* EEPROM MAC addresses */ |
1267 | struct mac_address addresses[2]; | 1270 | struct mac_address addresses[2]; |
1268 | 1271 | ||
@@ -1270,11 +1273,10 @@ struct iwl_priv { | |||
1270 | int fw_index; /* firmware we're trying to load */ | 1273 | int fw_index; /* firmware we're trying to load */ |
1271 | u32 ucode_ver; /* version of ucode, copy of | 1274 | u32 ucode_ver; /* version of ucode, copy of |
1272 | iwl_ucode.ver */ | 1275 | iwl_ucode.ver */ |
1273 | struct fw_desc ucode_code; /* runtime inst */ | 1276 | struct fw_img ucode_rt; |
1274 | struct fw_desc ucode_data; /* runtime data original */ | 1277 | struct fw_img ucode_init; |
1275 | struct fw_desc ucode_init; /* initialization inst */ | 1278 | |
1276 | struct fw_desc ucode_init_data; /* initialization data */ | 1279 | enum iwlagn_ucode_subtype ucode_type; |
1277 | enum ucode_type ucode_type; | ||
1278 | u8 ucode_write_complete; /* the image write is complete */ | 1280 | u8 ucode_write_complete; /* the image write is complete */ |
1279 | char firmware_name[25]; | 1281 | char firmware_name[25]; |
1280 | 1282 | ||
@@ -1472,8 +1474,6 @@ struct iwl_priv { | |||
1472 | 1474 | ||
1473 | struct tasklet_struct irq_tasklet; | 1475 | struct tasklet_struct irq_tasklet; |
1474 | 1476 | ||
1475 | struct delayed_work init_alive_start; | ||
1476 | struct delayed_work alive_start; | ||
1477 | struct delayed_work scan_check; | 1477 | struct delayed_work scan_check; |
1478 | 1478 | ||
1479 | /* TX Power */ | 1479 | /* TX Power */ |
@@ -1506,7 +1506,6 @@ struct iwl_priv { | |||
1506 | struct timer_list statistics_periodic; | 1506 | struct timer_list statistics_periodic; |
1507 | struct timer_list ucode_trace; | 1507 | struct timer_list ucode_trace; |
1508 | struct timer_list watchdog; | 1508 | struct timer_list watchdog; |
1509 | bool hw_ready; | ||
1510 | 1509 | ||
1511 | struct iwl_event_log event_log; | 1510 | struct iwl_event_log event_log; |
1512 | 1511 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 402733638f50..c8397962632c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -142,6 +142,45 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ | |||
142 | * | 142 | * |
143 | ******************************************************************************/ | 143 | ******************************************************************************/ |
144 | 144 | ||
145 | /* | ||
146 | * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||
147 | * when accessing the EEPROM; each access is a series of pulses to/from the | ||
148 | * EEPROM chip, not a single event, so even reads could conflict if they | ||
149 | * weren't arbitrated by the semaphore. | ||
150 | */ | ||
151 | static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv) | ||
152 | { | ||
153 | u16 count; | ||
154 | int ret; | ||
155 | |||
156 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||
157 | /* Request semaphore */ | ||
158 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
159 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
160 | |||
161 | /* See if we got it */ | ||
162 | ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
163 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
164 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
165 | EEPROM_SEM_TIMEOUT); | ||
166 | if (ret >= 0) { | ||
167 | IWL_DEBUG_EEPROM(priv, | ||
168 | "Acquired semaphore after %d tries.\n", | ||
169 | count+1); | ||
170 | return ret; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | static void iwl_eeprom_release_semaphore(struct iwl_priv *priv) | ||
178 | { | ||
179 | iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, | ||
180 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
181 | |||
182 | } | ||
183 | |||
145 | static int iwl_eeprom_verify_signature(struct iwl_priv *priv) | 184 | static int iwl_eeprom_verify_signature(struct iwl_priv *priv) |
146 | { | 185 | { |
147 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; | 186 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; |
@@ -421,7 +460,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
421 | } | 460 | } |
422 | 461 | ||
423 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | 462 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ |
424 | ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); | 463 | ret = iwl_eeprom_acquire_semaphore(priv); |
425 | if (ret < 0) { | 464 | if (ret < 0) { |
426 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); | 465 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); |
427 | ret = -ENOENT; | 466 | ret = -ENOENT; |
@@ -488,7 +527,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
488 | 527 | ||
489 | ret = 0; | 528 | ret = 0; |
490 | done: | 529 | done: |
491 | priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); | 530 | iwl_eeprom_release_semaphore(priv); |
492 | 531 | ||
493 | err: | 532 | err: |
494 | if (ret) | 533 | if (ret) |
@@ -711,13 +750,6 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
711 | flags & EEPROM_CHANNEL_RADAR)) | 750 | flags & EEPROM_CHANNEL_RADAR)) |
712 | ? "" : "not "); | 751 | ? "" : "not "); |
713 | 752 | ||
714 | /* Set the tx_power_user_lmt to the highest power | ||
715 | * supported by any channel */ | ||
716 | if (eeprom_ch_info[ch].max_power_avg > | ||
717 | priv->tx_power_user_lmt) | ||
718 | priv->tx_power_user_lmt = | ||
719 | eeprom_ch_info[ch].max_power_avg; | ||
720 | |||
721 | ch_info++; | 753 | ch_info++; |
722 | } | 754 | } |
723 | } | 755 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 9ce052573c6a..c960c6fa009b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -294,9 +294,6 @@ extern const u8 iwl_eeprom_band_1[14]; | |||
294 | 294 | ||
295 | struct iwl_eeprom_ops { | 295 | struct iwl_eeprom_ops { |
296 | const u32 regulatory_bands[7]; | 296 | const u32 regulatory_bands[7]; |
297 | int (*acquire_semaphore) (struct iwl_priv *priv); | ||
298 | void (*release_semaphore) (struct iwl_priv *priv); | ||
299 | u16 (*calib_version) (struct iwl_priv *priv); | ||
300 | const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset); | 297 | const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset); |
301 | void (*update_enhanced_txpower) (struct iwl_priv *priv); | 298 | void (*update_enhanced_txpower) (struct iwl_priv *priv); |
302 | }; | 299 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 9309ff2df4c2..41207a3645b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h | |||
@@ -64,30 +64,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd) | |||
64 | return --index & (n_bd - 1); | 64 | return --index & (n_bd - 1); |
65 | } | 65 | } |
66 | 66 | ||
67 | /* TODO: Move fw_desc functions to iwl-pci.ko */ | ||
68 | static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, | ||
69 | struct fw_desc *desc) | ||
70 | { | ||
71 | if (desc->v_addr) | ||
72 | dma_free_coherent(&pci_dev->dev, desc->len, | ||
73 | desc->v_addr, desc->p_addr); | ||
74 | desc->v_addr = NULL; | ||
75 | desc->len = 0; | ||
76 | } | ||
77 | |||
78 | static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, | ||
79 | struct fw_desc *desc) | ||
80 | { | ||
81 | if (!desc->len) { | ||
82 | desc->v_addr = NULL; | ||
83 | return -EINVAL; | ||
84 | } | ||
85 | |||
86 | desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, | ||
87 | &desc->p_addr, GFP_KERNEL); | ||
88 | return (desc->v_addr != NULL) ? 0 : -ENOMEM; | ||
89 | } | ||
90 | |||
91 | /* | 67 | /* |
92 | * we have 8 bits used like this: | 68 | * we have 8 bits used like this: |
93 | * | 69 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 51337416e4ca..aa4a90674452 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -73,10 +73,9 @@ int iwl_poll_bit(struct iwl_priv *priv, u32 addr, | |||
73 | return -ETIMEDOUT; | 73 | return -ETIMEDOUT; |
74 | } | 74 | } |
75 | 75 | ||
76 | int iwl_grab_nic_access(struct iwl_priv *priv) | 76 | int iwl_grab_nic_access_silent(struct iwl_priv *priv) |
77 | { | 77 | { |
78 | int ret; | 78 | int ret; |
79 | u32 val; | ||
80 | 79 | ||
81 | lockdep_assert_held(&priv->reg_lock); | 80 | lockdep_assert_held(&priv->reg_lock); |
82 | 81 | ||
@@ -107,9 +106,6 @@ int iwl_grab_nic_access(struct iwl_priv *priv) | |||
107 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | 106 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | |
108 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); | 107 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); |
109 | if (ret < 0) { | 108 | if (ret < 0) { |
110 | val = iwl_read32(priv, CSR_GP_CNTRL); | ||
111 | IWL_ERR(priv, | ||
112 | "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); | ||
113 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); | 109 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); |
114 | return -EIO; | 110 | return -EIO; |
115 | } | 111 | } |
@@ -117,6 +113,18 @@ int iwl_grab_nic_access(struct iwl_priv *priv) | |||
117 | return 0; | 113 | return 0; |
118 | } | 114 | } |
119 | 115 | ||
116 | int iwl_grab_nic_access(struct iwl_priv *priv) | ||
117 | { | ||
118 | int ret = iwl_grab_nic_access_silent(priv); | ||
119 | if (ret) { | ||
120 | u32 val = iwl_read32(priv, CSR_GP_CNTRL); | ||
121 | IWL_ERR(priv, | ||
122 | "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); | ||
123 | } | ||
124 | |||
125 | return ret; | ||
126 | } | ||
127 | |||
120 | void iwl_release_nic_access(struct iwl_priv *priv) | 128 | void iwl_release_nic_access(struct iwl_priv *priv) |
121 | { | 129 | { |
122 | lockdep_assert_held(&priv->reg_lock); | 130 | lockdep_assert_held(&priv->reg_lock); |
@@ -242,20 +250,32 @@ void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask) | |||
242 | spin_unlock_irqrestore(&priv->reg_lock, flags); | 250 | spin_unlock_irqrestore(&priv->reg_lock, flags); |
243 | } | 251 | } |
244 | 252 | ||
245 | u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr) | 253 | void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr, |
254 | void *buf, int words) | ||
246 | { | 255 | { |
247 | unsigned long flags; | 256 | unsigned long flags; |
248 | u32 value; | 257 | int offs; |
258 | u32 *vals = buf; | ||
249 | 259 | ||
250 | spin_lock_irqsave(&priv->reg_lock, flags); | 260 | spin_lock_irqsave(&priv->reg_lock, flags); |
251 | iwl_grab_nic_access(priv); | 261 | iwl_grab_nic_access(priv); |
252 | 262 | ||
253 | iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr); | 263 | iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr); |
254 | rmb(); | 264 | rmb(); |
255 | value = iwl_read32(priv, HBUS_TARG_MEM_RDAT); | 265 | |
266 | for (offs = 0; offs < words; offs++) | ||
267 | vals[offs] = iwl_read32(priv, HBUS_TARG_MEM_RDAT); | ||
256 | 268 | ||
257 | iwl_release_nic_access(priv); | 269 | iwl_release_nic_access(priv); |
258 | spin_unlock_irqrestore(&priv->reg_lock, flags); | 270 | spin_unlock_irqrestore(&priv->reg_lock, flags); |
271 | } | ||
272 | |||
273 | u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr) | ||
274 | { | ||
275 | u32 value; | ||
276 | |||
277 | _iwl_read_targ_mem_words(priv, addr, &value, 1); | ||
278 | |||
259 | return value; | 279 | return value; |
260 | } | 280 | } |
261 | 281 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index ab632baf49d5..869edc580ec6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -62,6 +62,7 @@ int iwl_poll_bit(struct iwl_priv *priv, u32 addr, | |||
62 | int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask, | 62 | int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask, |
63 | int timeout); | 63 | int timeout); |
64 | 64 | ||
65 | int iwl_grab_nic_access_silent(struct iwl_priv *priv); | ||
65 | int iwl_grab_nic_access(struct iwl_priv *priv); | 66 | int iwl_grab_nic_access(struct iwl_priv *priv); |
66 | void iwl_release_nic_access(struct iwl_priv *priv); | 67 | void iwl_release_nic_access(struct iwl_priv *priv); |
67 | 68 | ||
@@ -76,6 +77,16 @@ void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, | |||
76 | u32 bits, u32 mask); | 77 | u32 bits, u32 mask); |
77 | void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask); | 78 | void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask); |
78 | 79 | ||
80 | void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr, | ||
81 | void *buf, int words); | ||
82 | |||
83 | #define iwl_read_targ_mem_words(priv, addr, buf, bufsize) \ | ||
84 | do { \ | ||
85 | BUILD_BUG_ON((bufsize) % sizeof(u32)); \ | ||
86 | _iwl_read_targ_mem_words(priv, addr, buf, \ | ||
87 | (bufsize) / sizeof(u32));\ | ||
88 | } while (0) | ||
89 | |||
79 | u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr); | 90 | u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr); |
80 | void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val); | 91 | void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val); |
81 | #endif | 92 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index b49819ca2cd6..0053e9ea9021 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -225,55 +225,6 @@ err_bd: | |||
225 | * | 225 | * |
226 | ******************************************************************************/ | 226 | ******************************************************************************/ |
227 | 227 | ||
228 | static void iwl_rx_reply_alive(struct iwl_priv *priv, | ||
229 | struct iwl_rx_mem_buffer *rxb) | ||
230 | { | ||
231 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
232 | struct iwl_alive_resp *palive; | ||
233 | struct delayed_work *pwork; | ||
234 | |||
235 | palive = &pkt->u.alive_frame; | ||
236 | |||
237 | IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " | ||
238 | "0x%01X 0x%01X\n", | ||
239 | palive->is_valid, palive->ver_type, | ||
240 | palive->ver_subtype); | ||
241 | |||
242 | priv->device_pointers.log_event_table = | ||
243 | le32_to_cpu(palive->log_event_table_ptr); | ||
244 | priv->device_pointers.error_event_table = | ||
245 | le32_to_cpu(palive->error_event_table_ptr); | ||
246 | |||
247 | if (palive->ver_subtype == INITIALIZE_SUBTYPE) { | ||
248 | IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); | ||
249 | pwork = &priv->init_alive_start; | ||
250 | } else { | ||
251 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | ||
252 | pwork = &priv->alive_start; | ||
253 | } | ||
254 | |||
255 | /* We delay the ALIVE response by 5ms to | ||
256 | * give the HW RF Kill time to activate... */ | ||
257 | if (palive->is_valid == UCODE_VALID_OK) | ||
258 | queue_delayed_work(priv->workqueue, pwork, | ||
259 | msecs_to_jiffies(5)); | ||
260 | else { | ||
261 | IWL_WARN(priv, "%s uCode did not respond OK.\n", | ||
262 | (palive->ver_subtype == INITIALIZE_SUBTYPE) ? | ||
263 | "init" : "runtime"); | ||
264 | /* | ||
265 | * If fail to load init uCode, | ||
266 | * let's try to load the init uCode again. | ||
267 | * We should not get into this situation, but if it | ||
268 | * does happen, we should not move on and loading "runtime" | ||
269 | * without proper calibrate the device. | ||
270 | */ | ||
271 | if (palive->ver_subtype == INITIALIZE_SUBTYPE) | ||
272 | priv->ucode_type = UCODE_NONE; | ||
273 | queue_work(priv->workqueue, &priv->restart); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | static void iwl_rx_reply_error(struct iwl_priv *priv, | 228 | static void iwl_rx_reply_error(struct iwl_priv *priv, |
278 | struct iwl_rx_mem_buffer *rxb) | 229 | struct iwl_rx_mem_buffer *rxb) |
279 | { | 230 | { |
@@ -482,7 +433,6 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv, | |||
482 | struct statistics_tx *tx, | 433 | struct statistics_tx *tx, |
483 | unsigned long stamp) | 434 | unsigned long stamp) |
484 | { | 435 | { |
485 | const struct iwl_mod_params *mod_params = priv->cfg->mod_params; | ||
486 | unsigned int msecs; | 436 | unsigned int msecs; |
487 | 437 | ||
488 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 438 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
@@ -498,13 +448,13 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv, | |||
498 | if (msecs < 99) | 448 | if (msecs < 99) |
499 | return; | 449 | return; |
500 | 450 | ||
501 | if (mod_params->ack_check && !iwl_good_ack_health(priv, tx)) { | 451 | if (iwlagn_mod_params.ack_check && !iwl_good_ack_health(priv, tx)) { |
502 | IWL_ERR(priv, "low ack count detected, restart firmware\n"); | 452 | IWL_ERR(priv, "low ack count detected, restart firmware\n"); |
503 | if (!iwl_force_reset(priv, IWL_FW_RESET, false)) | 453 | if (!iwl_force_reset(priv, IWL_FW_RESET, false)) |
504 | return; | 454 | return; |
505 | } | 455 | } |
506 | 456 | ||
507 | if (mod_params->plcp_check && | 457 | if (iwlagn_mod_params.plcp_check && |
508 | !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) | 458 | !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) |
509 | iwl_force_reset(priv, IWL_RF_RESET, false); | 459 | iwl_force_reset(priv, IWL_RF_RESET, false); |
510 | } | 460 | } |
@@ -895,7 +845,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
895 | } | 845 | } |
896 | 846 | ||
897 | /* In case of HW accelerated crypto and bad decryption, drop */ | 847 | /* In case of HW accelerated crypto and bad decryption, drop */ |
898 | if (!priv->cfg->mod_params->sw_crypto && | 848 | if (!iwlagn_mod_params.sw_crypto && |
899 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | 849 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) |
900 | return; | 850 | return; |
901 | 851 | ||
@@ -1125,7 +1075,6 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
1125 | 1075 | ||
1126 | handlers = priv->rx_handlers; | 1076 | handlers = priv->rx_handlers; |
1127 | 1077 | ||
1128 | handlers[REPLY_ALIVE] = iwl_rx_reply_alive; | ||
1129 | handlers[REPLY_ERROR] = iwl_rx_reply_error; | 1078 | handlers[REPLY_ERROR] = iwl_rx_reply_error; |
1130 | handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; | 1079 | handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; |
1131 | handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif; | 1080 | handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h deleted file mode 100644 index cb80bb4ce45e..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h +++ /dev/null | |||
@@ -1,92 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ieee80211 subsystem header files. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
19 | * | ||
20 | * The full GNU General Public License is included in this distribution in the | ||
21 | * file called LICENSE. | ||
22 | * | ||
23 | * Contact Information: | ||
24 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
25 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
26 | * | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #ifndef __iwl_spectrum_h__ | ||
30 | #define __iwl_spectrum_h__ | ||
31 | enum { /* ieee80211_basic_report.map */ | ||
32 | IEEE80211_BASIC_MAP_BSS = (1 << 0), | ||
33 | IEEE80211_BASIC_MAP_OFDM = (1 << 1), | ||
34 | IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2), | ||
35 | IEEE80211_BASIC_MAP_RADAR = (1 << 3), | ||
36 | IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4), | ||
37 | /* Bits 5-7 are reserved */ | ||
38 | |||
39 | }; | ||
40 | struct ieee80211_basic_report { | ||
41 | u8 channel; | ||
42 | __le64 start_time; | ||
43 | __le16 duration; | ||
44 | u8 map; | ||
45 | } __packed; | ||
46 | |||
47 | enum { /* ieee80211_measurement_request.mode */ | ||
48 | /* Bit 0 is reserved */ | ||
49 | IEEE80211_MEASUREMENT_ENABLE = (1 << 1), | ||
50 | IEEE80211_MEASUREMENT_REQUEST = (1 << 2), | ||
51 | IEEE80211_MEASUREMENT_REPORT = (1 << 3), | ||
52 | /* Bits 4-7 are reserved */ | ||
53 | }; | ||
54 | |||
55 | enum { | ||
56 | IEEE80211_REPORT_BASIC = 0, /* required */ | ||
57 | IEEE80211_REPORT_CCA = 1, /* optional */ | ||
58 | IEEE80211_REPORT_RPI = 2, /* optional */ | ||
59 | /* 3-255 reserved */ | ||
60 | }; | ||
61 | |||
62 | struct ieee80211_measurement_params { | ||
63 | u8 channel; | ||
64 | __le64 start_time; | ||
65 | __le16 duration; | ||
66 | } __packed; | ||
67 | |||
68 | struct ieee80211_info_element { | ||
69 | u8 id; | ||
70 | u8 len; | ||
71 | u8 data[0]; | ||
72 | } __packed; | ||
73 | |||
74 | struct ieee80211_measurement_request { | ||
75 | struct ieee80211_info_element ie; | ||
76 | u8 token; | ||
77 | u8 mode; | ||
78 | u8 type; | ||
79 | struct ieee80211_measurement_params params[0]; | ||
80 | } __packed; | ||
81 | |||
82 | struct ieee80211_measurement_report { | ||
83 | struct ieee80211_info_element ie; | ||
84 | u8 token; | ||
85 | u8 mode; | ||
86 | u8 type; | ||
87 | union { | ||
88 | struct ieee80211_basic_report basic[0]; | ||
89 | } u; | ||
90 | } __packed; | ||
91 | |||
92 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 80c3565a66ae..52b1b66f32d0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -621,9 +621,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
621 | struct iwl_cmd_meta *meta; | 621 | struct iwl_cmd_meta *meta; |
622 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | 622 | struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; |
623 | unsigned long flags; | 623 | unsigned long flags; |
624 | void (*callback) (struct iwl_priv *priv, struct iwl_device_cmd *cmd, | ||
625 | struct iwl_rx_packet *pkt); | ||
626 | |||
627 | 624 | ||
628 | /* If a Tx command is being handled and it isn't in the actual | 625 | /* If a Tx command is being handled and it isn't in the actual |
629 | * command queue then there a command routing bug has been introduced | 626 | * command queue then there a command routing bug has been introduced |
@@ -637,8 +634,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
637 | return; | 634 | return; |
638 | } | 635 | } |
639 | 636 | ||
640 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
641 | |||
642 | cmd_index = get_cmd_index(&txq->q, index, huge); | 637 | cmd_index = get_cmd_index(&txq->q, index, huge); |
643 | cmd = txq->cmd[cmd_index]; | 638 | cmd = txq->cmd[cmd_index]; |
644 | meta = &txq->meta[cmd_index]; | 639 | meta = &txq->meta[cmd_index]; |
@@ -648,13 +643,14 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
648 | dma_unmap_len(meta, len), | 643 | dma_unmap_len(meta, len), |
649 | PCI_DMA_BIDIRECTIONAL); | 644 | PCI_DMA_BIDIRECTIONAL); |
650 | 645 | ||
651 | callback = NULL; | ||
652 | /* Input error checking is done when commands are added to queue. */ | 646 | /* Input error checking is done when commands are added to queue. */ |
653 | if (meta->flags & CMD_WANT_SKB) { | 647 | if (meta->flags & CMD_WANT_SKB) { |
654 | meta->source->reply_page = (unsigned long)rxb_addr(rxb); | 648 | meta->source->reply_page = (unsigned long)rxb_addr(rxb); |
655 | rxb->page = NULL; | 649 | rxb->page = NULL; |
656 | } else | 650 | } else if (meta->callback) |
657 | callback = meta->callback; | 651 | meta->callback(priv, cmd, pkt); |
652 | |||
653 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
658 | 654 | ||
659 | iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); | 655 | iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); |
660 | 656 | ||
@@ -669,7 +665,4 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
669 | meta->flags = 0; | 665 | meta->flags = 0; |
670 | 666 | ||
671 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | 667 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); |
672 | |||
673 | if (callback) | ||
674 | callback(priv, cmd, pkt); | ||
675 | } | 668 | } |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 5caa2ac14d61..486544e01a56 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -122,8 +122,10 @@ static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) | |||
122 | } | 122 | } |
123 | 123 | ||
124 | 124 | ||
125 | /* Various firmware commands need the list of supported rates, but with | 125 | /* |
126 | the hight-bit set for basic rates */ | 126 | * Various firmware commands need the list of supported rates, but with |
127 | * the hight-bit set for basic rates | ||
128 | */ | ||
127 | static int lbs_add_rates(u8 *rates) | 129 | static int lbs_add_rates(u8 *rates) |
128 | { | 130 | { |
129 | size_t i; | 131 | size_t i; |
@@ -425,7 +427,7 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len) | |||
425 | return ie_len + 2; | 427 | return ie_len + 2; |
426 | } | 428 | } |
427 | 429 | ||
428 | /*************************************************************************** | 430 | /* |
429 | * Set Channel | 431 | * Set Channel |
430 | */ | 432 | */ |
431 | 433 | ||
@@ -452,7 +454,7 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy, | |||
452 | 454 | ||
453 | 455 | ||
454 | 456 | ||
455 | /*************************************************************************** | 457 | /* |
456 | * Scanning | 458 | * Scanning |
457 | */ | 459 | */ |
458 | 460 | ||
@@ -538,8 +540,10 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
538 | goto done; | 540 | goto done; |
539 | } | 541 | } |
540 | 542 | ||
541 | /* Validity check: the TLV holds TSF values with 8 bytes each, so | 543 | /* |
542 | * the size in the TLV must match the nr_sets value */ | 544 | * Validity check: the TLV holds TSF values with 8 bytes each, so |
545 | * the size in the TLV must match the nr_sets value | ||
546 | */ | ||
543 | i = get_unaligned_le16(tsfdesc); | 547 | i = get_unaligned_le16(tsfdesc); |
544 | tsfdesc += 2; | 548 | tsfdesc += 2; |
545 | if (i / 8 != scanresp->nr_sets) { | 549 | if (i / 8 != scanresp->nr_sets) { |
@@ -581,8 +585,10 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
581 | 585 | ||
582 | /* To find out the channel, we must parse the IEs */ | 586 | /* To find out the channel, we must parse the IEs */ |
583 | ie = pos; | 587 | ie = pos; |
584 | /* 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon | 588 | /* |
585 | interval, capabilities */ | 589 | * 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon |
590 | * interval, capabilities | ||
591 | */ | ||
586 | ielen = left = len - (6 + 1 + 8 + 2 + 2); | 592 | ielen = left = len - (6 + 1 + 8 + 2 + 2); |
587 | while (left >= 2) { | 593 | while (left >= 2) { |
588 | u8 id, elen; | 594 | u8 id, elen; |
@@ -790,7 +796,7 @@ static int lbs_cfg_scan(struct wiphy *wiphy, | |||
790 | 796 | ||
791 | 797 | ||
792 | 798 | ||
793 | /*************************************************************************** | 799 | /* |
794 | * Events | 800 | * Events |
795 | */ | 801 | */ |
796 | 802 | ||
@@ -825,7 +831,7 @@ void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event) | |||
825 | 831 | ||
826 | 832 | ||
827 | 833 | ||
828 | /*************************************************************************** | 834 | /* |
829 | * Connect/disconnect | 835 | * Connect/disconnect |
830 | */ | 836 | */ |
831 | 837 | ||
@@ -950,8 +956,10 @@ static int lbs_enable_rsn(struct lbs_private *priv, int enable) | |||
950 | * Set WPA/WPA key material | 956 | * Set WPA/WPA key material |
951 | */ | 957 | */ |
952 | 958 | ||
953 | /* like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we | 959 | /* |
954 | * get rid of WEXT, this should go into host.h */ | 960 | * like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we |
961 | * get rid of WEXT, this should go into host.h | ||
962 | */ | ||
955 | 963 | ||
956 | struct cmd_key_material { | 964 | struct cmd_key_material { |
957 | struct cmd_header hdr; | 965 | struct cmd_header hdr; |
@@ -1536,7 +1544,7 @@ static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, | |||
1536 | } | 1544 | } |
1537 | 1545 | ||
1538 | 1546 | ||
1539 | /*************************************************************************** | 1547 | /* |
1540 | * Get station | 1548 | * Get station |
1541 | */ | 1549 | */ |
1542 | 1550 | ||
@@ -1581,7 +1589,7 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1581 | 1589 | ||
1582 | 1590 | ||
1583 | 1591 | ||
1584 | /*************************************************************************** | 1592 | /* |
1585 | * "Site survey", here just current channel and noise level | 1593 | * "Site survey", here just current channel and noise level |
1586 | */ | 1594 | */ |
1587 | 1595 | ||
@@ -1614,7 +1622,7 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, | |||
1614 | 1622 | ||
1615 | 1623 | ||
1616 | 1624 | ||
1617 | /*************************************************************************** | 1625 | /* |
1618 | * Change interface | 1626 | * Change interface |
1619 | */ | 1627 | */ |
1620 | 1628 | ||
@@ -1656,11 +1664,12 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev, | |||
1656 | 1664 | ||
1657 | 1665 | ||
1658 | 1666 | ||
1659 | /*************************************************************************** | 1667 | /* |
1660 | * IBSS (Ad-Hoc) | 1668 | * IBSS (Ad-Hoc) |
1661 | */ | 1669 | */ |
1662 | 1670 | ||
1663 | /* The firmware needs the following bits masked out of the beacon-derived | 1671 | /* |
1672 | * The firmware needs the following bits masked out of the beacon-derived | ||
1664 | * capability field when associating/joining to a BSS: | 1673 | * capability field when associating/joining to a BSS: |
1665 | * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused) | 1674 | * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused) |
1666 | */ | 1675 | */ |
@@ -1999,7 +2008,7 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | |||
1999 | 2008 | ||
2000 | 2009 | ||
2001 | 2010 | ||
2002 | /*************************************************************************** | 2011 | /* |
2003 | * Initialization | 2012 | * Initialization |
2004 | */ | 2013 | */ |
2005 | 2014 | ||
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 7e8a658b7670..6a96fc9c1cea 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /* |
2 | * This file contains the handling of command. | 2 | * This file contains the handling of command. |
3 | * It prepares command and sends it to firmware when it is ready. | 3 | * It prepares command and sends it to firmware when it is ready. |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/kfifo.h> | 6 | #include <linux/kfifo.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
@@ -16,14 +16,14 @@ | |||
16 | #define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf))) | 16 | #define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf))) |
17 | 17 | ||
18 | /** | 18 | /** |
19 | * @brief Simple callback that copies response back into command | 19 | * lbs_cmd_copyback - Simple callback that copies response back into command |
20 | * | 20 | * |
21 | * @param priv A pointer to struct lbs_private structure | 21 | * @priv: A pointer to &struct lbs_private structure |
22 | * @param extra A pointer to the original command structure for which | 22 | * @extra: A pointer to the original command structure for which |
23 | * 'resp' is a response | 23 | * 'resp' is a response |
24 | * @param resp A pointer to the command response | 24 | * @resp: A pointer to the command response |
25 | * | 25 | * |
26 | * @return 0 on success, error on failure | 26 | * returns: 0 on success, error on failure |
27 | */ | 27 | */ |
28 | int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, | 28 | int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, |
29 | struct cmd_header *resp) | 29 | struct cmd_header *resp) |
@@ -38,15 +38,15 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, | |||
38 | EXPORT_SYMBOL_GPL(lbs_cmd_copyback); | 38 | EXPORT_SYMBOL_GPL(lbs_cmd_copyback); |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * @brief Simple callback that ignores the result. Use this if | 41 | * lbs_cmd_async_callback - Simple callback that ignores the result. |
42 | * you just want to send a command to the hardware, but don't | 42 | * Use this if you just want to send a command to the hardware, but don't |
43 | * care for the result. | 43 | * care for the result. |
44 | * | 44 | * |
45 | * @param priv ignored | 45 | * @priv: ignored |
46 | * @param extra ignored | 46 | * @extra: ignored |
47 | * @param resp ignored | 47 | * @resp: ignored |
48 | * | 48 | * |
49 | * @return 0 for success | 49 | * returns: 0 for success |
50 | */ | 50 | */ |
51 | static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra, | 51 | static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra, |
52 | struct cmd_header *resp) | 52 | struct cmd_header *resp) |
@@ -56,10 +56,11 @@ static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra, | |||
56 | 56 | ||
57 | 57 | ||
58 | /** | 58 | /** |
59 | * @brief Checks whether a command is allowed in Power Save mode | 59 | * is_command_allowed_in_ps - tests if a command is allowed in Power Save mode |
60 | * | ||
61 | * @cmd: the command ID | ||
60 | * | 62 | * |
61 | * @param command the command ID | 63 | * returns: 1 if allowed, 0 if not allowed |
62 | * @return 1 if allowed, 0 if not allowed | ||
63 | */ | 64 | */ |
64 | static u8 is_command_allowed_in_ps(u16 cmd) | 65 | static u8 is_command_allowed_in_ps(u16 cmd) |
65 | { | 66 | { |
@@ -75,11 +76,12 @@ static u8 is_command_allowed_in_ps(u16 cmd) | |||
75 | } | 76 | } |
76 | 77 | ||
77 | /** | 78 | /** |
78 | * @brief Updates the hardware details like MAC address and regulatory region | 79 | * lbs_update_hw_spec - Updates the hardware details like MAC address |
80 | * and regulatory region | ||
79 | * | 81 | * |
80 | * @param priv A pointer to struct lbs_private structure | 82 | * @priv: A pointer to &struct lbs_private structure |
81 | * | 83 | * |
82 | * @return 0 on success, error on failure | 84 | * returns: 0 on success, error on failure |
83 | */ | 85 | */ |
84 | int lbs_update_hw_spec(struct lbs_private *priv) | 86 | int lbs_update_hw_spec(struct lbs_private *priv) |
85 | { | 87 | { |
@@ -217,14 +219,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, | |||
217 | EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); | 219 | EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); |
218 | 220 | ||
219 | /** | 221 | /** |
220 | * @brief Sets the Power Save mode | 222 | * lbs_set_ps_mode - Sets the Power Save mode |
221 | * | 223 | * |
222 | * @param priv A pointer to struct lbs_private structure | 224 | * @priv: A pointer to &struct lbs_private structure |
223 | * @param cmd_action The Power Save operation (PS_MODE_ACTION_ENTER_PS or | 225 | * @cmd_action: The Power Save operation (PS_MODE_ACTION_ENTER_PS or |
224 | * PS_MODE_ACTION_EXIT_PS) | 226 | * PS_MODE_ACTION_EXIT_PS) |
225 | * @param block Whether to block on a response or not | 227 | * @block: Whether to block on a response or not |
226 | * | 228 | * |
227 | * @return 0 on success, error on failure | 229 | * returns: 0 on success, error on failure |
228 | */ | 230 | */ |
229 | int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block) | 231 | int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block) |
230 | { | 232 | { |
@@ -417,13 +419,13 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep) | |||
417 | } | 419 | } |
418 | 420 | ||
419 | /** | 421 | /** |
420 | * @brief Set an SNMP MIB value | 422 | * lbs_set_snmp_mib - Set an SNMP MIB value |
421 | * | 423 | * |
422 | * @param priv A pointer to struct lbs_private structure | 424 | * @priv: A pointer to &struct lbs_private structure |
423 | * @param oid The OID to set in the firmware | 425 | * @oid: The OID to set in the firmware |
424 | * @param val Value to set the OID to | 426 | * @val: Value to set the OID to |
425 | * | 427 | * |
426 | * @return 0 on success, error on failure | 428 | * returns: 0 on success, error on failure |
427 | */ | 429 | */ |
428 | int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val) | 430 | int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val) |
429 | { | 431 | { |
@@ -467,13 +469,13 @@ out: | |||
467 | } | 469 | } |
468 | 470 | ||
469 | /** | 471 | /** |
470 | * @brief Get an SNMP MIB value | 472 | * lbs_get_snmp_mib - Get an SNMP MIB value |
471 | * | 473 | * |
472 | * @param priv A pointer to struct lbs_private structure | 474 | * @priv: A pointer to &struct lbs_private structure |
473 | * @param oid The OID to retrieve from the firmware | 475 | * @oid: The OID to retrieve from the firmware |
474 | * @param out_val Location for the returned value | 476 | * @out_val: Location for the returned value |
475 | * | 477 | * |
476 | * @return 0 on success, error on failure | 478 | * returns: 0 on success, error on failure |
477 | */ | 479 | */ |
478 | int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val) | 480 | int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val) |
479 | { | 481 | { |
@@ -510,14 +512,14 @@ out: | |||
510 | } | 512 | } |
511 | 513 | ||
512 | /** | 514 | /** |
513 | * @brief Get the min, max, and current TX power | 515 | * lbs_get_tx_power - Get the min, max, and current TX power |
514 | * | 516 | * |
515 | * @param priv A pointer to struct lbs_private structure | 517 | * @priv: A pointer to &struct lbs_private structure |
516 | * @param curlevel Current power level in dBm | 518 | * @curlevel: Current power level in dBm |
517 | * @param minlevel Minimum supported power level in dBm (optional) | 519 | * @minlevel: Minimum supported power level in dBm (optional) |
518 | * @param maxlevel Maximum supported power level in dBm (optional) | 520 | * @maxlevel: Maximum supported power level in dBm (optional) |
519 | * | 521 | * |
520 | * @return 0 on success, error on failure | 522 | * returns: 0 on success, error on failure |
521 | */ | 523 | */ |
522 | int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel, | 524 | int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel, |
523 | s16 *maxlevel) | 525 | s16 *maxlevel) |
@@ -545,12 +547,12 @@ int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel, | |||
545 | } | 547 | } |
546 | 548 | ||
547 | /** | 549 | /** |
548 | * @brief Set the TX power | 550 | * lbs_set_tx_power - Set the TX power |
549 | * | 551 | * |
550 | * @param priv A pointer to struct lbs_private structure | 552 | * @priv: A pointer to &struct lbs_private structure |
551 | * @param dbm The desired power level in dBm | 553 | * @dbm: The desired power level in dBm |
552 | * | 554 | * |
553 | * @return 0 on success, error on failure | 555 | * returns: 0 on success, error on failure |
554 | */ | 556 | */ |
555 | int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) | 557 | int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) |
556 | { | 558 | { |
@@ -573,12 +575,13 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) | |||
573 | } | 575 | } |
574 | 576 | ||
575 | /** | 577 | /** |
576 | * @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW) | 578 | * lbs_set_monitor_mode - Enable or disable monitor mode |
579 | * (only implemented on OLPC usb8388 FW) | ||
577 | * | 580 | * |
578 | * @param priv A pointer to struct lbs_private structure | 581 | * @priv: A pointer to &struct lbs_private structure |
579 | * @param enable 1 to enable monitor mode, 0 to disable | 582 | * @enable: 1 to enable monitor mode, 0 to disable |
580 | * | 583 | * |
581 | * @return 0 on success, error on failure | 584 | * returns: 0 on success, error on failure |
582 | */ | 585 | */ |
583 | int lbs_set_monitor_mode(struct lbs_private *priv, int enable) | 586 | int lbs_set_monitor_mode(struct lbs_private *priv, int enable) |
584 | { | 587 | { |
@@ -604,11 +607,11 @@ int lbs_set_monitor_mode(struct lbs_private *priv, int enable) | |||
604 | } | 607 | } |
605 | 608 | ||
606 | /** | 609 | /** |
607 | * @brief Get the radio channel | 610 | * lbs_get_channel - Get the radio channel |
608 | * | 611 | * |
609 | * @param priv A pointer to struct lbs_private structure | 612 | * @priv: A pointer to &struct lbs_private structure |
610 | * | 613 | * |
611 | * @return The channel on success, error on failure | 614 | * returns: The channel on success, error on failure |
612 | */ | 615 | */ |
613 | static int lbs_get_channel(struct lbs_private *priv) | 616 | static int lbs_get_channel(struct lbs_private *priv) |
614 | { | 617 | { |
@@ -650,12 +653,12 @@ int lbs_update_channel(struct lbs_private *priv) | |||
650 | } | 653 | } |
651 | 654 | ||
652 | /** | 655 | /** |
653 | * @brief Set the radio channel | 656 | * lbs_set_channel - Set the radio channel |
654 | * | 657 | * |
655 | * @param priv A pointer to struct lbs_private structure | 658 | * @priv: A pointer to &struct lbs_private structure |
656 | * @param channel The desired channel, or 0 to clear a locked channel | 659 | * @channel: The desired channel, or 0 to clear a locked channel |
657 | * | 660 | * |
658 | * @return 0 on success, error on failure | 661 | * returns: 0 on success, error on failure |
659 | */ | 662 | */ |
660 | int lbs_set_channel(struct lbs_private *priv, u8 channel) | 663 | int lbs_set_channel(struct lbs_private *priv, u8 channel) |
661 | { | 664 | { |
@@ -686,12 +689,13 @@ out: | |||
686 | } | 689 | } |
687 | 690 | ||
688 | /** | 691 | /** |
689 | * @brief Get current RSSI and noise floor | 692 | * lbs_get_rssi - Get current RSSI and noise floor |
690 | * | 693 | * |
691 | * @param priv A pointer to struct lbs_private structure | 694 | * @priv: A pointer to &struct lbs_private structure |
692 | * @param rssi On successful return, signal level in mBm | 695 | * @rssi: On successful return, signal level in mBm |
696 | * @nf: On successful return, Noise floor | ||
693 | * | 697 | * |
694 | * @return The channel on success, error on failure | 698 | * returns: The channel on success, error on failure |
695 | */ | 699 | */ |
696 | int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) | 700 | int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) |
697 | { | 701 | { |
@@ -719,13 +723,14 @@ int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) | |||
719 | } | 723 | } |
720 | 724 | ||
721 | /** | 725 | /** |
722 | * @brief Send regulatory and 802.11d domain information to the firmware | 726 | * lbs_set_11d_domain_info - Send regulatory and 802.11d domain information |
727 | * to the firmware | ||
723 | * | 728 | * |
724 | * @param priv pointer to struct lbs_private | 729 | * @priv: pointer to &struct lbs_private |
725 | * @param request cfg80211 regulatory request structure | 730 | * @request: cfg80211 regulatory request structure |
726 | * @param bands the device's supported bands and channels | 731 | * @bands: the device's supported bands and channels |
727 | * | 732 | * |
728 | * @return 0 on success, error code on failure | 733 | * returns: 0 on success, error code on failure |
729 | */ | 734 | */ |
730 | int lbs_set_11d_domain_info(struct lbs_private *priv, | 735 | int lbs_set_11d_domain_info(struct lbs_private *priv, |
731 | struct regulatory_request *request, | 736 | struct regulatory_request *request, |
@@ -842,15 +847,15 @@ int lbs_set_11d_domain_info(struct lbs_private *priv, | |||
842 | } | 847 | } |
843 | 848 | ||
844 | /** | 849 | /** |
845 | * @brief Read a MAC, Baseband, or RF register | 850 | * lbs_get_reg - Read a MAC, Baseband, or RF register |
846 | * | 851 | * |
847 | * @param priv pointer to struct lbs_private | 852 | * @priv: pointer to &struct lbs_private |
848 | * @param cmd register command, one of CMD_MAC_REG_ACCESS, | 853 | * @reg: register command, one of CMD_MAC_REG_ACCESS, |
849 | * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS | 854 | * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS |
850 | * @param offset byte offset of the register to get | 855 | * @offset: byte offset of the register to get |
851 | * @param value on success, the value of the register at 'offset' | 856 | * @value: on success, the value of the register at 'offset' |
852 | * | 857 | * |
853 | * @return 0 on success, error code on failure | 858 | * returns: 0 on success, error code on failure |
854 | */ | 859 | */ |
855 | int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) | 860 | int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) |
856 | { | 861 | { |
@@ -886,15 +891,15 @@ out: | |||
886 | } | 891 | } |
887 | 892 | ||
888 | /** | 893 | /** |
889 | * @brief Write a MAC, Baseband, or RF register | 894 | * lbs_set_reg - Write a MAC, Baseband, or RF register |
890 | * | 895 | * |
891 | * @param priv pointer to struct lbs_private | 896 | * @priv: pointer to &struct lbs_private |
892 | * @param cmd register command, one of CMD_MAC_REG_ACCESS, | 897 | * @reg: register command, one of CMD_MAC_REG_ACCESS, |
893 | * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS | 898 | * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS |
894 | * @param offset byte offset of the register to set | 899 | * @offset: byte offset of the register to set |
895 | * @param value the value to write to the register at 'offset' | 900 | * @value: the value to write to the register at 'offset' |
896 | * | 901 | * |
897 | * @return 0 on success, error code on failure | 902 | * returns: 0 on success, error code on failure |
898 | */ | 903 | */ |
899 | int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value) | 904 | int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value) |
900 | { | 905 | { |
@@ -1023,7 +1028,7 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
1023 | lbs_deb_leave(LBS_DEB_HOST); | 1028 | lbs_deb_leave(LBS_DEB_HOST); |
1024 | } | 1029 | } |
1025 | 1030 | ||
1026 | /** | 1031 | /* |
1027 | * This function inserts command node to cmdfreeq | 1032 | * This function inserts command node to cmdfreeq |
1028 | * after cleans it. Requires priv->driver_lock held. | 1033 | * after cleans it. Requires priv->driver_lock held. |
1029 | */ | 1034 | */ |
@@ -1125,11 +1130,12 @@ void lbs_set_mac_control(struct lbs_private *priv) | |||
1125 | } | 1130 | } |
1126 | 1131 | ||
1127 | /** | 1132 | /** |
1128 | * @brief This function allocates the command buffer and link | 1133 | * lbs_allocate_cmd_buffer - allocates the command buffer and links |
1129 | * it to command free queue. | 1134 | * it to command free queue |
1135 | * | ||
1136 | * @priv: A pointer to &struct lbs_private structure | ||
1130 | * | 1137 | * |
1131 | * @param priv A pointer to struct lbs_private structure | 1138 | * returns: 0 for success or -1 on error |
1132 | * @return 0 or -1 | ||
1133 | */ | 1139 | */ |
1134 | int lbs_allocate_cmd_buffer(struct lbs_private *priv) | 1140 | int lbs_allocate_cmd_buffer(struct lbs_private *priv) |
1135 | { | 1141 | { |
@@ -1171,10 +1177,11 @@ done: | |||
1171 | } | 1177 | } |
1172 | 1178 | ||
1173 | /** | 1179 | /** |
1174 | * @brief This function frees the command buffer. | 1180 | * lbs_free_cmd_buffer - free the command buffer |
1175 | * | 1181 | * |
1176 | * @param priv A pointer to struct lbs_private structure | 1182 | * @priv: A pointer to &struct lbs_private structure |
1177 | * @return 0 or -1 | 1183 | * |
1184 | * returns: 0 for success | ||
1178 | */ | 1185 | */ |
1179 | int lbs_free_cmd_buffer(struct lbs_private *priv) | 1186 | int lbs_free_cmd_buffer(struct lbs_private *priv) |
1180 | { | 1187 | { |
@@ -1211,11 +1218,13 @@ done: | |||
1211 | } | 1218 | } |
1212 | 1219 | ||
1213 | /** | 1220 | /** |
1214 | * @brief This function gets a free command node if available in | 1221 | * lbs_get_free_cmd_node - gets a free command node if available in |
1215 | * command free queue. | 1222 | * command free queue |
1223 | * | ||
1224 | * @priv: A pointer to &struct lbs_private structure | ||
1216 | * | 1225 | * |
1217 | * @param priv A pointer to struct lbs_private structure | 1226 | * returns: A pointer to &cmd_ctrl_node structure on success |
1218 | * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL | 1227 | * or %NULL on error |
1219 | */ | 1228 | */ |
1220 | static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) | 1229 | static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) |
1221 | { | 1230 | { |
@@ -1245,12 +1254,12 @@ static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) | |||
1245 | } | 1254 | } |
1246 | 1255 | ||
1247 | /** | 1256 | /** |
1248 | * @brief This function executes next command in command | 1257 | * lbs_execute_next_command - execute next command in command |
1249 | * pending queue. It will put firmware back to PS mode | 1258 | * pending queue. Will put firmware back to PS mode if applicable. |
1250 | * if applicable. | ||
1251 | * | 1259 | * |
1252 | * @param priv A pointer to struct lbs_private structure | 1260 | * @priv: A pointer to &struct lbs_private structure |
1253 | * @return 0 or -1 | 1261 | * |
1262 | * returns: 0 on success or -1 on error | ||
1254 | */ | 1263 | */ |
1255 | int lbs_execute_next_command(struct lbs_private *priv) | 1264 | int lbs_execute_next_command(struct lbs_private *priv) |
1256 | { | 1265 | { |
@@ -1454,12 +1463,12 @@ out: | |||
1454 | } | 1463 | } |
1455 | 1464 | ||
1456 | /** | 1465 | /** |
1457 | * @brief This function checks condition and prepares to | 1466 | * lbs_ps_confirm_sleep - checks condition and prepares to |
1458 | * send sleep confirm command to firmware if ok. | 1467 | * send sleep confirm command to firmware if ok |
1468 | * | ||
1469 | * @priv: A pointer to &struct lbs_private structure | ||
1459 | * | 1470 | * |
1460 | * @param priv A pointer to struct lbs_private structure | 1471 | * returns: n/a |
1461 | * @param psmode Power Saving mode | ||
1462 | * @return n/a | ||
1463 | */ | 1472 | */ |
1464 | void lbs_ps_confirm_sleep(struct lbs_private *priv) | 1473 | void lbs_ps_confirm_sleep(struct lbs_private *priv) |
1465 | { | 1474 | { |
@@ -1499,16 +1508,16 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) | |||
1499 | 1508 | ||
1500 | 1509 | ||
1501 | /** | 1510 | /** |
1502 | * @brief Configures the transmission power control functionality. | 1511 | * lbs_set_tpc_cfg - Configures the transmission power control functionality |
1503 | * | 1512 | * |
1504 | * @param priv A pointer to struct lbs_private structure | 1513 | * @priv: A pointer to &struct lbs_private structure |
1505 | * @param enable Transmission power control enable | 1514 | * @enable: Transmission power control enable |
1506 | * @param p0 Power level when link quality is good (dBm). | 1515 | * @p0: Power level when link quality is good (dBm). |
1507 | * @param p1 Power level when link quality is fair (dBm). | 1516 | * @p1: Power level when link quality is fair (dBm). |
1508 | * @param p2 Power level when link quality is poor (dBm). | 1517 | * @p2: Power level when link quality is poor (dBm). |
1509 | * @param usesnr Use Signal to Noise Ratio in TPC | 1518 | * @usesnr: Use Signal to Noise Ratio in TPC |
1510 | * | 1519 | * |
1511 | * @return 0 on success | 1520 | * returns: 0 on success |
1512 | */ | 1521 | */ |
1513 | int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, | 1522 | int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, |
1514 | int8_t p2, int usesnr) | 1523 | int8_t p2, int usesnr) |
@@ -1531,15 +1540,15 @@ int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, | |||
1531 | } | 1540 | } |
1532 | 1541 | ||
1533 | /** | 1542 | /** |
1534 | * @brief Configures the power adaptation settings. | 1543 | * lbs_set_power_adapt_cfg - Configures the power adaptation settings |
1535 | * | 1544 | * |
1536 | * @param priv A pointer to struct lbs_private structure | 1545 | * @priv: A pointer to &struct lbs_private structure |
1537 | * @param enable Power adaptation enable | 1546 | * @enable: Power adaptation enable |
1538 | * @param p0 Power level for 1, 2, 5.5 and 11 Mbps (dBm). | 1547 | * @p0: Power level for 1, 2, 5.5 and 11 Mbps (dBm). |
1539 | * @param p1 Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm). | 1548 | * @p1: Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm). |
1540 | * @param p2 Power level for 48 and 54 Mbps (dBm). | 1549 | * @p2: Power level for 48 and 54 Mbps (dBm). |
1541 | * | 1550 | * |
1542 | * @return 0 on Success | 1551 | * returns: 0 on Success |
1543 | */ | 1552 | */ |
1544 | 1553 | ||
1545 | int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, | 1554 | int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, |
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 5e95da9dcc2e..03e528994a9e 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /* |
2 | * This file contains the handling of command | 2 | * This file contains the handling of command |
3 | * responses as well as events generated by firmware. | 3 | * responses as well as events generated by firmware. |
4 | */ | 4 | */ |
5 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
6 | #include <linux/delay.h> | 6 | #include <linux/delay.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
@@ -12,12 +12,13 @@ | |||
12 | #include "cmd.h" | 12 | #include "cmd.h" |
13 | 13 | ||
14 | /** | 14 | /** |
15 | * @brief This function handles disconnect event. it | 15 | * lbs_mac_event_disconnected - handles disconnect event. It |
16 | * reports disconnect to upper layer, clean tx/rx packets, | 16 | * reports disconnect to upper layer, clean tx/rx packets, |
17 | * reset link state etc. | 17 | * reset link state etc. |
18 | * | ||
19 | * @priv: A pointer to struct lbs_private structure | ||
18 | * | 20 | * |
19 | * @param priv A pointer to struct lbs_private structure | 21 | * returns: n/a |
20 | * @return n/a | ||
21 | */ | 22 | */ |
22 | void lbs_mac_event_disconnected(struct lbs_private *priv) | 23 | void lbs_mac_event_disconnected(struct lbs_private *priv) |
23 | { | 24 | { |
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index fbf3b0332bb7..851fe7bd4ba4 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c | |||
@@ -849,15 +849,14 @@ static struct debug_data items[] = { | |||
849 | static int num_of_items = ARRAY_SIZE(items); | 849 | static int num_of_items = ARRAY_SIZE(items); |
850 | 850 | ||
851 | /** | 851 | /** |
852 | * @brief proc read function | 852 | * lbs_debugfs_read - proc read function |
853 | * | 853 | * |
854 | * @param page pointer to buffer | 854 | * @file: file to read |
855 | * @param s read data starting position | 855 | * @userbuf: pointer to buffer |
856 | * @param off offset | 856 | * @count: number of bytes to read |
857 | * @param cnt counter | 857 | * @ppos: read data starting position |
858 | * @param eof end of file flag | 858 | * |
859 | * @param data data to output | 859 | * returns: amount of data read or negative error code |
860 | * @return number of output data | ||
861 | */ | 860 | */ |
862 | static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf, | 861 | static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf, |
863 | size_t count, loff_t *ppos) | 862 | size_t count, loff_t *ppos) |
@@ -897,13 +896,14 @@ static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf, | |||
897 | } | 896 | } |
898 | 897 | ||
899 | /** | 898 | /** |
900 | * @brief proc write function | 899 | * lbs_debugfs_write - proc write function |
900 | * | ||
901 | * @f: file pointer | ||
902 | * @buf: pointer to data buffer | ||
903 | * @cnt: data number to write | ||
904 | * @ppos: file position | ||
901 | * | 905 | * |
902 | * @param f file pointer | 906 | * returns: amount of data written |
903 | * @param buf pointer to data buffer | ||
904 | * @param cnt data number to write | ||
905 | * @param data data to write | ||
906 | * @return number of data | ||
907 | */ | 907 | */ |
908 | static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, | 908 | static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, |
909 | size_t cnt, loff_t *ppos) | 909 | size_t cnt, loff_t *ppos) |
@@ -966,11 +966,11 @@ static const struct file_operations lbs_debug_fops = { | |||
966 | }; | 966 | }; |
967 | 967 | ||
968 | /** | 968 | /** |
969 | * @brief create debug proc file | 969 | * lbs_debug_init - create debug proc file |
970 | * | ||
971 | * @priv: pointer to &struct lbs_private | ||
970 | * | 972 | * |
971 | * @param priv pointer struct lbs_private | 973 | * returns: N/A |
972 | * @param dev pointer net_device | ||
973 | * @return N/A | ||
974 | */ | 974 | */ |
975 | static void lbs_debug_init(struct lbs_private *priv) | 975 | static void lbs_debug_init(struct lbs_private *priv) |
976 | { | 976 | { |
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 2ae752d10065..da0b05bb89fe 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h | |||
@@ -1,8 +1,8 @@ | |||
1 | 1 | ||
2 | /** | 2 | /* |
3 | * This file contains declaration referring to | 3 | * This file contains declaration referring to |
4 | * functions defined in other source files | 4 | * functions defined in other source files |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef _LBS_DECL_H_ | 7 | #ifndef _LBS_DECL_H_ |
8 | #define _LBS_DECL_H_ | 8 | #define _LBS_DECL_H_ |
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index d00c728cec47..92b5b1f8fd75 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /* |
2 | * This header file contains global constant/enum definitions, | 2 | * This header file contains global constant/enum definitions, |
3 | * global variable declaration. | 3 | * global variable declaration. |
4 | */ | 4 | */ |
5 | #ifndef _LBS_DEFS_H_ | 5 | #ifndef _LBS_DEFS_H_ |
6 | #define _LBS_DEFS_H_ | 6 | #define _LBS_DEFS_H_ |
7 | 7 | ||
@@ -123,19 +123,19 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
123 | 123 | ||
124 | 124 | ||
125 | 125 | ||
126 | /** Buffer Constants */ | 126 | /* Buffer Constants */ |
127 | 127 | ||
128 | /* The size of SQ memory PPA, DPA are 8 DWORDs, that keep the physical | 128 | /* The size of SQ memory PPA, DPA are 8 DWORDs, that keep the physical |
129 | * addresses of TxPD buffers. Station has only 8 TxPD available, Whereas | 129 | * addresses of TxPD buffers. Station has only 8 TxPD available, Whereas |
130 | * driver has more local TxPDs. Each TxPD on the host memory is associated | 130 | * driver has more local TxPDs. Each TxPD on the host memory is associated |
131 | * with a Tx control node. The driver maintains 8 RxPD descriptors for | 131 | * with a Tx control node. The driver maintains 8 RxPD descriptors for |
132 | * station firmware to store Rx packet information. | 132 | * station firmware to store Rx packet information. |
133 | * | 133 | * |
134 | * Current version of MAC has a 32x6 multicast address buffer. | 134 | * Current version of MAC has a 32x6 multicast address buffer. |
135 | * | 135 | * |
136 | * 802.11b can have up to 14 channels, the driver keeps the | 136 | * 802.11b can have up to 14 channels, the driver keeps the |
137 | * BSSID(MAC address) of each APs or Ad hoc stations it has sensed. | 137 | * BSSID(MAC address) of each APs or Ad hoc stations it has sensed. |
138 | */ | 138 | */ |
139 | 139 | ||
140 | #define MRVDRV_MAX_MULTICAST_LIST_SIZE 32 | 140 | #define MRVDRV_MAX_MULTICAST_LIST_SIZE 32 |
141 | #define LBS_NUM_CMD_BUFFERS 10 | 141 | #define LBS_NUM_CMD_BUFFERS 10 |
@@ -166,7 +166,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
166 | #define WOL_RESULT_NOSPC_ERR 1 | 166 | #define WOL_RESULT_NOSPC_ERR 1 |
167 | #define WOL_RESULT_EEXIST_ERR 2 | 167 | #define WOL_RESULT_EEXIST_ERR 2 |
168 | 168 | ||
169 | /** Misc constants */ | 169 | /* Misc constants */ |
170 | /* This section defines 802.11 specific contants */ | 170 | /* This section defines 802.11 specific contants */ |
171 | 171 | ||
172 | #define MRVDRV_MAX_BSS_DESCRIPTS 16 | 172 | #define MRVDRV_MAX_BSS_DESCRIPTS 16 |
@@ -183,7 +183,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
183 | 183 | ||
184 | #define MARVELL_MESH_IE_LENGTH 9 | 184 | #define MARVELL_MESH_IE_LENGTH 9 |
185 | 185 | ||
186 | /* Values used to populate the struct mrvl_mesh_ie. The only time you need this | 186 | /* |
187 | * Values used to populate the struct mrvl_mesh_ie. The only time you need this | ||
187 | * is when enabling the mesh using CMD_MESH_CONFIG. | 188 | * is when enabling the mesh using CMD_MESH_CONFIG. |
188 | */ | 189 | */ |
189 | #define MARVELL_MESH_IE_TYPE 4 | 190 | #define MARVELL_MESH_IE_TYPE 4 |
@@ -193,7 +194,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
193 | #define MARVELL_MESH_METRIC_ID 0 | 194 | #define MARVELL_MESH_METRIC_ID 0 |
194 | #define MARVELL_MESH_CAPABILITY 0 | 195 | #define MARVELL_MESH_CAPABILITY 0 |
195 | 196 | ||
196 | /** INT status Bit Definition*/ | 197 | /* INT status Bit Definition */ |
197 | #define MRVDRV_TX_DNLD_RDY 0x0001 | 198 | #define MRVDRV_TX_DNLD_RDY 0x0001 |
198 | #define MRVDRV_RX_UPLD_RDY 0x0002 | 199 | #define MRVDRV_RX_UPLD_RDY 0x0002 |
199 | #define MRVDRV_CMD_DNLD_RDY 0x0004 | 200 | #define MRVDRV_CMD_DNLD_RDY 0x0004 |
@@ -208,59 +209,63 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
208 | #define TPC_DEFAULT_P1 10 | 209 | #define TPC_DEFAULT_P1 10 |
209 | #define TPC_DEFAULT_P2 13 | 210 | #define TPC_DEFAULT_P2 13 |
210 | 211 | ||
211 | /** TxPD status */ | 212 | /* TxPD status */ |
212 | 213 | ||
213 | /* Station firmware use TxPD status field to report final Tx transmit | 214 | /* |
214 | * result, Bit masks are used to present combined situations. | 215 | * Station firmware use TxPD status field to report final Tx transmit |
215 | */ | 216 | * result, Bit masks are used to present combined situations. |
217 | */ | ||
216 | 218 | ||
217 | #define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01 | 219 | #define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01 |
218 | #define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08 | 220 | #define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08 |
219 | 221 | ||
220 | /** Tx mesh flag */ | 222 | /* Tx mesh flag */ |
221 | /* Currently we are using normal WDS flag as mesh flag. | 223 | /* |
224 | * Currently we are using normal WDS flag as mesh flag. | ||
222 | * TODO: change to proper mesh flag when MAC understands it. | 225 | * TODO: change to proper mesh flag when MAC understands it. |
223 | */ | 226 | */ |
224 | #define TxPD_CONTROL_WDS_FRAME (1<<17) | 227 | #define TxPD_CONTROL_WDS_FRAME (1<<17) |
225 | #define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME | 228 | #define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME |
226 | 229 | ||
227 | /** Mesh interface ID */ | 230 | /* Mesh interface ID */ |
228 | #define MESH_IFACE_ID 0x0001 | 231 | #define MESH_IFACE_ID 0x0001 |
229 | /** Mesh id should be in bits 14-13-12 */ | 232 | /* Mesh id should be in bits 14-13-12 */ |
230 | #define MESH_IFACE_BIT_OFFSET 0x000c | 233 | #define MESH_IFACE_BIT_OFFSET 0x000c |
231 | /** Mesh enable bit in FW capability */ | 234 | /* Mesh enable bit in FW capability */ |
232 | #define MESH_CAPINFO_ENABLE_MASK (1<<16) | 235 | #define MESH_CAPINFO_ENABLE_MASK (1<<16) |
233 | 236 | ||
234 | /** FW definition from Marvell v4 */ | 237 | /* FW definition from Marvell v4 */ |
235 | #define MRVL_FW_V4 (0x04) | 238 | #define MRVL_FW_V4 (0x04) |
236 | /** FW definition from Marvell v5 */ | 239 | /* FW definition from Marvell v5 */ |
237 | #define MRVL_FW_V5 (0x05) | 240 | #define MRVL_FW_V5 (0x05) |
238 | /** FW definition from Marvell v10 */ | 241 | /* FW definition from Marvell v10 */ |
239 | #define MRVL_FW_V10 (0x0a) | 242 | #define MRVL_FW_V10 (0x0a) |
240 | /** FW major revision definition */ | 243 | /* FW major revision definition */ |
241 | #define MRVL_FW_MAJOR_REV(x) ((x)>>24) | 244 | #define MRVL_FW_MAJOR_REV(x) ((x)>>24) |
242 | 245 | ||
243 | /** RxPD status */ | 246 | /* RxPD status */ |
244 | 247 | ||
245 | #define MRVDRV_RXPD_STATUS_OK 0x0001 | 248 | #define MRVDRV_RXPD_STATUS_OK 0x0001 |
246 | 249 | ||
247 | /** RxPD status - Received packet types */ | 250 | /* RxPD status - Received packet types */ |
248 | /** Rx mesh flag */ | 251 | /* Rx mesh flag */ |
249 | /* Currently we are using normal WDS flag as mesh flag. | 252 | /* |
253 | * Currently we are using normal WDS flag as mesh flag. | ||
250 | * TODO: change to proper mesh flag when MAC understands it. | 254 | * TODO: change to proper mesh flag when MAC understands it. |
251 | */ | 255 | */ |
252 | #define RxPD_CONTROL_WDS_FRAME (0x40) | 256 | #define RxPD_CONTROL_WDS_FRAME (0x40) |
253 | #define RxPD_MESH_FRAME RxPD_CONTROL_WDS_FRAME | 257 | #define RxPD_MESH_FRAME RxPD_CONTROL_WDS_FRAME |
254 | 258 | ||
255 | /** RSSI-related defines */ | 259 | /* RSSI-related defines */ |
256 | /* RSSI constants are used to implement 802.11 RSSI threshold | 260 | /* |
257 | * indication. if the Rx packet signal got too weak for 5 consecutive | 261 | * RSSI constants are used to implement 802.11 RSSI threshold |
258 | * times, miniport driver (driver) will report this event to wrapper | 262 | * indication. if the Rx packet signal got too weak for 5 consecutive |
259 | */ | 263 | * times, miniport driver (driver) will report this event to wrapper |
264 | */ | ||
260 | 265 | ||
261 | #define MRVDRV_NF_DEFAULT_SCAN_VALUE (-96) | 266 | #define MRVDRV_NF_DEFAULT_SCAN_VALUE (-96) |
262 | 267 | ||
263 | /** RTS/FRAG related defines */ | 268 | /* RTS/FRAG related defines */ |
264 | #define MRVDRV_RTS_MIN_VALUE 0 | 269 | #define MRVDRV_RTS_MIN_VALUE 0 |
265 | #define MRVDRV_RTS_MAX_VALUE 2347 | 270 | #define MRVDRV_RTS_MAX_VALUE 2347 |
266 | #define MRVDRV_FRAG_MIN_VALUE 256 | 271 | #define MRVDRV_FRAG_MIN_VALUE 256 |
@@ -300,36 +305,36 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
300 | 305 | ||
301 | #define MAX_LEDS 8 | 306 | #define MAX_LEDS 8 |
302 | 307 | ||
303 | /** Global Variable Declaration */ | 308 | /* Global Variable Declaration */ |
304 | extern const char lbs_driver_version[]; | 309 | extern const char lbs_driver_version[]; |
305 | extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE]; | 310 | extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE]; |
306 | 311 | ||
307 | 312 | ||
308 | /** ENUM definition*/ | 313 | /* ENUM definition */ |
309 | /** SNRNF_TYPE */ | 314 | /* SNRNF_TYPE */ |
310 | enum SNRNF_TYPE { | 315 | enum SNRNF_TYPE { |
311 | TYPE_BEACON = 0, | 316 | TYPE_BEACON = 0, |
312 | TYPE_RXPD, | 317 | TYPE_RXPD, |
313 | MAX_TYPE_B | 318 | MAX_TYPE_B |
314 | }; | 319 | }; |
315 | 320 | ||
316 | /** SNRNF_DATA*/ | 321 | /* SNRNF_DATA */ |
317 | enum SNRNF_DATA { | 322 | enum SNRNF_DATA { |
318 | TYPE_NOAVG = 0, | 323 | TYPE_NOAVG = 0, |
319 | TYPE_AVG, | 324 | TYPE_AVG, |
320 | MAX_TYPE_AVG | 325 | MAX_TYPE_AVG |
321 | }; | 326 | }; |
322 | 327 | ||
323 | /** LBS_802_11_POWER_MODE */ | 328 | /* LBS_802_11_POWER_MODE */ |
324 | enum LBS_802_11_POWER_MODE { | 329 | enum LBS_802_11_POWER_MODE { |
325 | LBS802_11POWERMODECAM, | 330 | LBS802_11POWERMODECAM, |
326 | LBS802_11POWERMODEMAX_PSP, | 331 | LBS802_11POWERMODEMAX_PSP, |
327 | LBS802_11POWERMODEFAST_PSP, | 332 | LBS802_11POWERMODEFAST_PSP, |
328 | /*not a real mode, defined as an upper bound */ | 333 | /* not a real mode, defined as an upper bound */ |
329 | LBS802_11POWEMODEMAX | 334 | LBS802_11POWEMODEMAX |
330 | }; | 335 | }; |
331 | 336 | ||
332 | /** PS_STATE */ | 337 | /* PS_STATE */ |
333 | enum PS_STATE { | 338 | enum PS_STATE { |
334 | PS_STATE_FULL_POWER, | 339 | PS_STATE_FULL_POWER, |
335 | PS_STATE_AWAKE, | 340 | PS_STATE_AWAKE, |
@@ -337,7 +342,7 @@ enum PS_STATE { | |||
337 | PS_STATE_SLEEP | 342 | PS_STATE_SLEEP |
338 | }; | 343 | }; |
339 | 344 | ||
340 | /** DNLD_STATE */ | 345 | /* DNLD_STATE */ |
341 | enum DNLD_STATE { | 346 | enum DNLD_STATE { |
342 | DNLD_RES_RECEIVED, | 347 | DNLD_RES_RECEIVED, |
343 | DNLD_DATA_SENT, | 348 | DNLD_DATA_SENT, |
@@ -345,19 +350,19 @@ enum DNLD_STATE { | |||
345 | DNLD_BOOTCMD_SENT, | 350 | DNLD_BOOTCMD_SENT, |
346 | }; | 351 | }; |
347 | 352 | ||
348 | /** LBS_MEDIA_STATE */ | 353 | /* LBS_MEDIA_STATE */ |
349 | enum LBS_MEDIA_STATE { | 354 | enum LBS_MEDIA_STATE { |
350 | LBS_CONNECTED, | 355 | LBS_CONNECTED, |
351 | LBS_DISCONNECTED | 356 | LBS_DISCONNECTED |
352 | }; | 357 | }; |
353 | 358 | ||
354 | /** LBS_802_11_PRIVACY_FILTER */ | 359 | /* LBS_802_11_PRIVACY_FILTER */ |
355 | enum LBS_802_11_PRIVACY_FILTER { | 360 | enum LBS_802_11_PRIVACY_FILTER { |
356 | LBS802_11PRIVFILTERACCEPTALL, | 361 | LBS802_11PRIVFILTERACCEPTALL, |
357 | LBS802_11PRIVFILTER8021XWEP | 362 | LBS802_11PRIVFILTER8021XWEP |
358 | }; | 363 | }; |
359 | 364 | ||
360 | /** mv_ms_type */ | 365 | /* mv_ms_type */ |
361 | enum mv_ms_type { | 366 | enum mv_ms_type { |
362 | MVMS_DAT = 0, | 367 | MVMS_DAT = 0, |
363 | MVMS_CMD = 1, | 368 | MVMS_CMD = 1, |
@@ -365,14 +370,14 @@ enum mv_ms_type { | |||
365 | MVMS_EVENT | 370 | MVMS_EVENT |
366 | }; | 371 | }; |
367 | 372 | ||
368 | /** KEY_TYPE_ID */ | 373 | /* KEY_TYPE_ID */ |
369 | enum KEY_TYPE_ID { | 374 | enum KEY_TYPE_ID { |
370 | KEY_TYPE_ID_WEP = 0, | 375 | KEY_TYPE_ID_WEP = 0, |
371 | KEY_TYPE_ID_TKIP, | 376 | KEY_TYPE_ID_TKIP, |
372 | KEY_TYPE_ID_AES | 377 | KEY_TYPE_ID_AES |
373 | }; | 378 | }; |
374 | 379 | ||
375 | /** KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */ | 380 | /* KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */ |
376 | enum KEY_INFO_WPA { | 381 | enum KEY_INFO_WPA { |
377 | KEY_INFO_WPA_MCAST = 0x01, | 382 | KEY_INFO_WPA_MCAST = 0x01, |
378 | KEY_INFO_WPA_UNICAST = 0x02, | 383 | KEY_INFO_WPA_UNICAST = 0x02, |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index bc461eb39660..76d018beebf4 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -1,8 +1,8 @@ | |||
1 | /** | 1 | /* |
2 | * This file contains definitions and data structures specific | 2 | * This file contains definitions and data structures specific |
3 | * to Marvell 802.11 NIC. It contains the Device Information | 3 | * to Marvell 802.11 NIC. It contains the Device Information |
4 | * structure struct lbs_private.. | 4 | * structure struct lbs_private.. |
5 | */ | 5 | */ |
6 | #ifndef _LBS_DEV_H_ | 6 | #ifndef _LBS_DEV_H_ |
7 | #define _LBS_DEV_H_ | 7 | #define _LBS_DEV_H_ |
8 | 8 | ||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/kfifo.h> | 13 | #include <linux/kfifo.h> |
14 | 14 | ||
15 | /** sleep_params */ | 15 | /* sleep_params */ |
16 | struct sleep_params { | 16 | struct sleep_params { |
17 | uint16_t sp_error; | 17 | uint16_t sp_error; |
18 | uint16_t sp_offset; | 18 | uint16_t sp_offset; |
@@ -23,7 +23,7 @@ struct sleep_params { | |||
23 | }; | 23 | }; |
24 | 24 | ||
25 | 25 | ||
26 | /** Private structure for the MV device */ | 26 | /* Private structure for the MV device */ |
27 | struct lbs_private { | 27 | struct lbs_private { |
28 | 28 | ||
29 | /* Basic networking */ | 29 | /* Basic networking */ |
@@ -125,12 +125,12 @@ struct lbs_private { | |||
125 | /* Events sent from hardware to driver */ | 125 | /* Events sent from hardware to driver */ |
126 | struct kfifo event_fifo; | 126 | struct kfifo event_fifo; |
127 | 127 | ||
128 | /** thread to service interrupts */ | 128 | /* thread to service interrupts */ |
129 | struct task_struct *main_thread; | 129 | struct task_struct *main_thread; |
130 | wait_queue_head_t waitq; | 130 | wait_queue_head_t waitq; |
131 | struct workqueue_struct *work_thread; | 131 | struct workqueue_struct *work_thread; |
132 | 132 | ||
133 | /** Encryption stuff */ | 133 | /* Encryption stuff */ |
134 | u8 authtype_auto; | 134 | u8 authtype_auto; |
135 | u8 wep_tx_key; | 135 | u8 wep_tx_key; |
136 | u8 wep_key[4][WLAN_KEY_LEN_WEP104]; | 136 | u8 wep_key[4][WLAN_KEY_LEN_WEP104]; |
@@ -162,7 +162,7 @@ struct lbs_private { | |||
162 | s16 txpower_min; | 162 | s16 txpower_min; |
163 | s16 txpower_max; | 163 | s16 txpower_max; |
164 | 164 | ||
165 | /** Scanning */ | 165 | /* Scanning */ |
166 | struct delayed_work scan_work; | 166 | struct delayed_work scan_work; |
167 | int scan_channel; | 167 | int scan_channel; |
168 | /* Queue of things waiting for scan completion */ | 168 | /* Queue of things waiting for scan completion */ |
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 50193aac679e..29dbce4a9f86 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c | |||
@@ -20,7 +20,8 @@ static void lbs_ethtool_get_drvinfo(struct net_device *dev, | |||
20 | strcpy(info->version, lbs_driver_version); | 20 | strcpy(info->version, lbs_driver_version); |
21 | } | 21 | } |
22 | 22 | ||
23 | /* All 8388 parts have 16KiB EEPROM size at the time of writing. | 23 | /* |
24 | * All 8388 parts have 16KiB EEPROM size at the time of writing. | ||
24 | * In case that changes this needs fixing. | 25 | * In case that changes this needs fixing. |
25 | */ | 26 | */ |
26 | #define LBS_EEPROM_LEN 16384 | 27 | #define LBS_EEPROM_LEN 16384 |
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index 6cb6935ee4a3..2e2dbfa2ee50 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /* |
2 | * This file function prototypes, data structure | 2 | * This file function prototypes, data structure |
3 | * and definitions for all the host/station commands | 3 | * and definitions for all the host/station commands |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #ifndef _LBS_HOST_H_ | 6 | #ifndef _LBS_HOST_H_ |
7 | #define _LBS_HOST_H_ | 7 | #define _LBS_HOST_H_ |
@@ -13,9 +13,10 @@ | |||
13 | 13 | ||
14 | #define CMD_OPTION_WAITFORRSP 0x0002 | 14 | #define CMD_OPTION_WAITFORRSP 0x0002 |
15 | 15 | ||
16 | /** Host command IDs */ | 16 | /* Host command IDs */ |
17 | 17 | ||
18 | /* Return command are almost always the same as the host command, but with | 18 | /* |
19 | * Return command are almost always the same as the host command, but with | ||
19 | * bit 15 set high. There are a few exceptions, though... | 20 | * bit 15 set high. There are a few exceptions, though... |
20 | */ | 21 | */ |
21 | #define CMD_RET(cmd) (0x8000 | cmd) | 22 | #define CMD_RET(cmd) (0x8000 | cmd) |
@@ -251,7 +252,7 @@ enum cmd_mesh_config_types { | |||
251 | CMD_TYPE_MESH_GET_MESH_IE, /* GET_DEFAULTS is superset of GET_MESHIE */ | 252 | CMD_TYPE_MESH_GET_MESH_IE, /* GET_DEFAULTS is superset of GET_MESHIE */ |
252 | }; | 253 | }; |
253 | 254 | ||
254 | /** Card Event definition */ | 255 | /* Card Event definition */ |
255 | #define MACREG_INT_CODE_TX_PPA_FREE 0 | 256 | #define MACREG_INT_CODE_TX_PPA_FREE 0 |
256 | #define MACREG_INT_CODE_TX_DMA_DONE 1 | 257 | #define MACREG_INT_CODE_TX_DMA_DONE 1 |
257 | #define MACREG_INT_CODE_LINK_LOST_W_SCAN 2 | 258 | #define MACREG_INT_CODE_LINK_LOST_W_SCAN 2 |
@@ -624,12 +625,14 @@ struct cmd_ds_802_11_rf_channel { | |||
624 | struct cmd_ds_802_11_rssi { | 625 | struct cmd_ds_802_11_rssi { |
625 | struct cmd_header hdr; | 626 | struct cmd_header hdr; |
626 | 627 | ||
627 | /* request: number of beacons (N) to average the SNR and NF over | 628 | /* |
629 | * request: number of beacons (N) to average the SNR and NF over | ||
628 | * response: SNR of most recent beacon | 630 | * response: SNR of most recent beacon |
629 | */ | 631 | */ |
630 | __le16 n_or_snr; | 632 | __le16 n_or_snr; |
631 | 633 | ||
632 | /* The following fields are only set in the response. | 634 | /* |
635 | * The following fields are only set in the response. | ||
633 | * In the request these are reserved and should be set to 0. | 636 | * In the request these are reserved and should be set to 0. |
634 | */ | 637 | */ |
635 | __le16 nf; /* most recent beacon noise floor */ | 638 | __le16 nf; /* most recent beacon noise floor */ |
@@ -680,14 +683,16 @@ struct cmd_ds_802_11_ps_mode { | |||
680 | 683 | ||
681 | __le16 action; | 684 | __le16 action; |
682 | 685 | ||
683 | /* Interval for keepalive in PS mode: | 686 | /* |
687 | * Interval for keepalive in PS mode: | ||
684 | * 0x0000 = don't change | 688 | * 0x0000 = don't change |
685 | * 0x001E = firmware default | 689 | * 0x001E = firmware default |
686 | * 0xFFFF = disable | 690 | * 0xFFFF = disable |
687 | */ | 691 | */ |
688 | __le16 nullpktinterval; | 692 | __le16 nullpktinterval; |
689 | 693 | ||
690 | /* Number of DTIM intervals to wake up for: | 694 | /* |
695 | * Number of DTIM intervals to wake up for: | ||
691 | * 0 = don't change | 696 | * 0 = don't change |
692 | * 1 = firmware default | 697 | * 1 = firmware default |
693 | * 5 = max | 698 | * 5 = max |
@@ -697,7 +702,8 @@ struct cmd_ds_802_11_ps_mode { | |||
697 | __le16 reserved; | 702 | __le16 reserved; |
698 | __le16 locallisteninterval; | 703 | __le16 locallisteninterval; |
699 | 704 | ||
700 | /* AdHoc awake period (FW v9+ only): | 705 | /* |
706 | * AdHoc awake period (FW v9+ only): | ||
701 | * 0 = don't change | 707 | * 0 = don't change |
702 | * 1 = always awake (IEEE standard behavior) | 708 | * 1 = always awake (IEEE standard behavior) |
703 | * 2 - 31 = sleep for (n - 1) periods and awake for 1 period | 709 | * 2 - 31 = sleep for (n - 1) periods and awake for 1 period |
@@ -771,7 +777,8 @@ struct adhoc_bssdesc { | |||
771 | __le16 capability; | 777 | __le16 capability; |
772 | u8 rates[MAX_RATES]; | 778 | u8 rates[MAX_RATES]; |
773 | 779 | ||
774 | /* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the | 780 | /* |
781 | * DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the | ||
775 | * Adhoc join command and will cause a binary layout mismatch with | 782 | * Adhoc join command and will cause a binary layout mismatch with |
776 | * the firmware | 783 | * the firmware |
777 | */ | 784 | */ |
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 8712cb213f2f..4dfd48fe8b6e 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c | |||
@@ -312,7 +312,8 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r | |||
312 | #define CF8385_MANFID 0x02df | 312 | #define CF8385_MANFID 0x02df |
313 | #define CF8385_CARDID 0x8103 | 313 | #define CF8385_CARDID 0x8103 |
314 | 314 | ||
315 | /* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when | 315 | /* |
316 | * FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when | ||
316 | * that gets fixed. Currently there's no way to access it from the probe hook. | 317 | * that gets fixed. Currently there's no way to access it from the probe hook. |
317 | */ | 318 | */ |
318 | static inline u32 get_model(u16 manf_id, u16 card_id) | 319 | static inline u32 get_model(u16 manf_id, u16 card_id) |
@@ -621,8 +622,10 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw) | |||
621 | if (remain < count) | 622 | if (remain < count) |
622 | count = remain; | 623 | count = remain; |
623 | 624 | ||
624 | /* "write the number of bytes to be sent to the I/O Command | 625 | /* |
625 | * write length register" */ | 626 | * "write the number of bytes to be sent to the I/O Command |
627 | * write length register" | ||
628 | */ | ||
626 | if_cs_write16(card, IF_CS_CMD_LEN, count); | 629 | if_cs_write16(card, IF_CS_CMD_LEN, count); |
627 | 630 | ||
628 | /* "write this to I/O Command port register as 16 bit writes */ | 631 | /* "write this to I/O Command port register as 16 bit writes */ |
@@ -631,16 +634,22 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw) | |||
631 | &fw->data[sent], | 634 | &fw->data[sent], |
632 | count >> 1); | 635 | count >> 1); |
633 | 636 | ||
634 | /* "Assert the download over interrupt command in the Host | 637 | /* |
635 | * status register" */ | 638 | * "Assert the download over interrupt command in the Host |
639 | * status register" | ||
640 | */ | ||
636 | if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND); | 641 | if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND); |
637 | 642 | ||
638 | /* "Assert the download over interrupt command in the Card | 643 | /* |
639 | * interrupt case register" */ | 644 | * "Assert the download over interrupt command in the Card |
645 | * interrupt case register" | ||
646 | */ | ||
640 | if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND); | 647 | if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND); |
641 | 648 | ||
642 | /* "The host polls the Card Status register ... for 50 ms before | 649 | /* |
643 | declaring a failure */ | 650 | * "The host polls the Card Status register ... for 50 ms before |
651 | * declaring a failure" | ||
652 | */ | ||
644 | ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS, | 653 | ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS, |
645 | IF_CS_BIT_COMMAND); | 654 | IF_CS_BIT_COMMAND); |
646 | if (ret < 0) { | 655 | if (ret < 0) { |
@@ -841,7 +850,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
841 | 850 | ||
842 | /* | 851 | /* |
843 | * Most of the libertas cards can do unaligned register access, but some | 852 | * Most of the libertas cards can do unaligned register access, but some |
844 | * weird ones can not. That's especially true for the CF8305 card. | 853 | * weird ones cannot. That's especially true for the CF8305 card. |
845 | */ | 854 | */ |
846 | card->align_regs = 0; | 855 | card->align_regs = 0; |
847 | 856 | ||
@@ -913,8 +922,10 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
913 | goto out3; | 922 | goto out3; |
914 | } | 923 | } |
915 | 924 | ||
916 | /* Clear any interrupt cause that happened while sending | 925 | /* |
917 | * firmware/initializing card */ | 926 | * Clear any interrupt cause that happened while sending |
927 | * firmware/initializing card | ||
928 | */ | ||
918 | if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK); | 929 | if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK); |
919 | if_cs_enable_ints(card); | 930 | if_cs_enable_ints(card); |
920 | 931 | ||
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 078ef43d957d..67de5b3c68b2 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -143,8 +143,10 @@ static void spu_transaction_finish(struct if_spi_card *card) | |||
143 | card->prev_xfer_time = jiffies; | 143 | card->prev_xfer_time = jiffies; |
144 | } | 144 | } |
145 | 145 | ||
146 | /* Write out a byte buffer to an SPI register, | 146 | /* |
147 | * using a series of 16-bit transfers. */ | 147 | * Write out a byte buffer to an SPI register, |
148 | * using a series of 16-bit transfers. | ||
149 | */ | ||
148 | static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | 150 | static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) |
149 | { | 151 | { |
150 | int err = 0; | 152 | int err = 0; |
@@ -208,8 +210,10 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | |||
208 | struct spi_transfer dummy_trans; | 210 | struct spi_transfer dummy_trans; |
209 | struct spi_transfer data_trans; | 211 | struct spi_transfer data_trans; |
210 | 212 | ||
211 | /* You must take an even number of bytes from the SPU, even if you | 213 | /* |
212 | * don't care about the last one. */ | 214 | * You must take an even number of bytes from the SPU, even if you |
215 | * don't care about the last one. | ||
216 | */ | ||
213 | BUG_ON(len & 0x1); | 217 | BUG_ON(len & 0x1); |
214 | 218 | ||
215 | spu_transaction_init(card); | 219 | spu_transaction_init(card); |
@@ -258,8 +262,10 @@ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) | |||
258 | return ret; | 262 | return ret; |
259 | } | 263 | } |
260 | 264 | ||
261 | /* Read 32 bits from an SPI register. | 265 | /* |
262 | * The low 16 bits are read first. */ | 266 | * Read 32 bits from an SPI register. |
267 | * The low 16 bits are read first. | ||
268 | */ | ||
263 | static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) | 269 | static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) |
264 | { | 270 | { |
265 | __le32 buf; | 271 | __le32 buf; |
@@ -271,13 +277,15 @@ static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) | |||
271 | return err; | 277 | return err; |
272 | } | 278 | } |
273 | 279 | ||
274 | /* Keep reading 16 bits from an SPI register until you get the correct result. | 280 | /* |
281 | * Keep reading 16 bits from an SPI register until you get the correct result. | ||
275 | * | 282 | * |
276 | * If mask = 0, the correct result is any non-zero number. | 283 | * If mask = 0, the correct result is any non-zero number. |
277 | * If mask != 0, the correct result is any number where | 284 | * If mask != 0, the correct result is any number where |
278 | * number & target_mask == target | 285 | * number & target_mask == target |
279 | * | 286 | * |
280 | * Returns -ETIMEDOUT if a second passes without the correct result. */ | 287 | * Returns -ETIMEDOUT if a second passes without the correct result. |
288 | */ | ||
281 | static int spu_wait_for_u16(struct if_spi_card *card, u16 reg, | 289 | static int spu_wait_for_u16(struct if_spi_card *card, u16 reg, |
282 | u16 target_mask, u16 target) | 290 | u16 target_mask, u16 target) |
283 | { | 291 | { |
@@ -305,8 +313,10 @@ static int spu_wait_for_u16(struct if_spi_card *card, u16 reg, | |||
305 | } | 313 | } |
306 | } | 314 | } |
307 | 315 | ||
308 | /* Read 16 bits from an SPI register until you receive a specific value. | 316 | /* |
309 | * Returns -ETIMEDOUT if a 4 tries pass without success. */ | 317 | * Read 16 bits from an SPI register until you receive a specific value. |
318 | * Returns -ETIMEDOUT if a 4 tries pass without success. | ||
319 | */ | ||
310 | static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target) | 320 | static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target) |
311 | { | 321 | { |
312 | int err, try; | 322 | int err, try; |
@@ -328,8 +338,10 @@ static int spu_set_interrupt_mode(struct if_spi_card *card, | |||
328 | { | 338 | { |
329 | int err = 0; | 339 | int err = 0; |
330 | 340 | ||
331 | /* We can suppress a host interrupt by clearing the appropriate | 341 | /* |
332 | * bit in the "host interrupt status mask" register */ | 342 | * We can suppress a host interrupt by clearing the appropriate |
343 | * bit in the "host interrupt status mask" register | ||
344 | */ | ||
333 | if (suppress_host_int) { | 345 | if (suppress_host_int) { |
334 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0); | 346 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0); |
335 | if (err) | 347 | if (err) |
@@ -345,10 +357,12 @@ static int spu_set_interrupt_mode(struct if_spi_card *card, | |||
345 | return err; | 357 | return err; |
346 | } | 358 | } |
347 | 359 | ||
348 | /* If auto-interrupts are on, the completion of certain transactions | 360 | /* |
361 | * If auto-interrupts are on, the completion of certain transactions | ||
349 | * will trigger an interrupt automatically. If auto-interrupts | 362 | * will trigger an interrupt automatically. If auto-interrupts |
350 | * are off, we need to set the "Card Interrupt Cause" register to | 363 | * are off, we need to set the "Card Interrupt Cause" register to |
351 | * trigger a card interrupt. */ | 364 | * trigger a card interrupt. |
365 | */ | ||
352 | if (auto_int) { | 366 | if (auto_int) { |
353 | err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG, | 367 | err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG, |
354 | IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO | | 368 | IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO | |
@@ -402,8 +416,10 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes) | |||
402 | int err = 0; | 416 | int err = 0; |
403 | u32 delay; | 417 | u32 delay; |
404 | 418 | ||
405 | /* We have to start up in timed delay mode so that we can safely | 419 | /* |
406 | * read the Delay Read Register. */ | 420 | * We have to start up in timed delay mode so that we can safely |
421 | * read the Delay Read Register. | ||
422 | */ | ||
407 | card->use_dummy_writes = 0; | 423 | card->use_dummy_writes = 0; |
408 | err = spu_set_bus_mode(card, | 424 | err = spu_set_bus_mode(card, |
409 | IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING | | 425 | IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING | |
@@ -459,8 +475,10 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card, | |||
459 | 475 | ||
460 | /* Load helper firmware image */ | 476 | /* Load helper firmware image */ |
461 | while (bytes_remaining > 0) { | 477 | while (bytes_remaining > 0) { |
462 | /* Scratch pad 1 should contain the number of bytes we | 478 | /* |
463 | * want to download to the firmware */ | 479 | * Scratch pad 1 should contain the number of bytes we |
480 | * want to download to the firmware | ||
481 | */ | ||
464 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, | 482 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, |
465 | HELPER_FW_LOAD_CHUNK_SZ); | 483 | HELPER_FW_LOAD_CHUNK_SZ); |
466 | if (err) | 484 | if (err) |
@@ -472,8 +490,10 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card, | |||
472 | if (err) | 490 | if (err) |
473 | goto out; | 491 | goto out; |
474 | 492 | ||
475 | /* Feed the data into the command read/write port reg | 493 | /* |
476 | * in chunks of 64 bytes */ | 494 | * Feed the data into the command read/write port reg |
495 | * in chunks of 64 bytes | ||
496 | */ | ||
477 | memset(temp, 0, sizeof(temp)); | 497 | memset(temp, 0, sizeof(temp)); |
478 | memcpy(temp, fw, | 498 | memcpy(temp, fw, |
479 | min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ)); | 499 | min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ)); |
@@ -495,9 +515,11 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card, | |||
495 | fw += HELPER_FW_LOAD_CHUNK_SZ; | 515 | fw += HELPER_FW_LOAD_CHUNK_SZ; |
496 | } | 516 | } |
497 | 517 | ||
498 | /* Once the helper / single stage firmware download is complete, | 518 | /* |
519 | * Once the helper / single stage firmware download is complete, | ||
499 | * write 0 to scratch pad 1 and interrupt the | 520 | * write 0 to scratch pad 1 and interrupt the |
500 | * bootloader. This completes the helper download. */ | 521 | * bootloader. This completes the helper download. |
522 | */ | ||
501 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK); | 523 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK); |
502 | if (err) | 524 | if (err) |
503 | goto out; | 525 | goto out; |
@@ -517,16 +539,20 @@ out: | |||
517 | return err; | 539 | return err; |
518 | } | 540 | } |
519 | 541 | ||
520 | /* Returns the length of the next packet the firmware expects us to send | 542 | /* |
521 | * Sets crc_err if the previous transfer had a CRC error. */ | 543 | * Returns the length of the next packet the firmware expects us to send. |
544 | * Sets crc_err if the previous transfer had a CRC error. | ||
545 | */ | ||
522 | static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, | 546 | static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, |
523 | int *crc_err) | 547 | int *crc_err) |
524 | { | 548 | { |
525 | u16 len; | 549 | u16 len; |
526 | int err = 0; | 550 | int err = 0; |
527 | 551 | ||
528 | /* wait until the host interrupt status register indicates | 552 | /* |
529 | * that we are ready to download */ | 553 | * wait until the host interrupt status register indicates |
554 | * that we are ready to download | ||
555 | */ | ||
530 | err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, | 556 | err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, |
531 | IF_SPI_HIST_CMD_DOWNLOAD_RDY, | 557 | IF_SPI_HIST_CMD_DOWNLOAD_RDY, |
532 | IF_SPI_HIST_CMD_DOWNLOAD_RDY); | 558 | IF_SPI_HIST_CMD_DOWNLOAD_RDY); |
@@ -587,8 +613,10 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card, | |||
587 | goto out; | 613 | goto out; |
588 | } | 614 | } |
589 | if (bytes < 0) { | 615 | if (bytes < 0) { |
590 | /* If there are no more bytes left, we would normally | 616 | /* |
591 | * expect to have terminated with len = 0 */ | 617 | * If there are no more bytes left, we would normally |
618 | * expect to have terminated with len = 0 | ||
619 | */ | ||
592 | lbs_pr_err("Firmware load wants more bytes " | 620 | lbs_pr_err("Firmware load wants more bytes " |
593 | "than we have to offer.\n"); | 621 | "than we have to offer.\n"); |
594 | break; | 622 | break; |
@@ -660,14 +688,18 @@ static int if_spi_c2h_cmd(struct if_spi_card *card) | |||
660 | u16 len; | 688 | u16 len; |
661 | u8 i; | 689 | u8 i; |
662 | 690 | ||
663 | /* We need a buffer big enough to handle whatever people send to | 691 | /* |
664 | * hw_host_to_card */ | 692 | * We need a buffer big enough to handle whatever people send to |
693 | * hw_host_to_card | ||
694 | */ | ||
665 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE); | 695 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE); |
666 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE); | 696 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE); |
667 | 697 | ||
668 | /* It's just annoying if the buffer size isn't a multiple of 4, because | 698 | /* |
669 | * then we might have len < IF_SPI_CMD_BUF_SIZE but | 699 | * It's just annoying if the buffer size isn't a multiple of 4, because |
670 | * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */ | 700 | * then we might have len < IF_SPI_CMD_BUF_SIZE but |
701 | * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE | ||
702 | */ | ||
671 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0); | 703 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0); |
672 | 704 | ||
673 | lbs_deb_enter(LBS_DEB_SPI); | 705 | lbs_deb_enter(LBS_DEB_SPI); |
@@ -838,8 +870,10 @@ static void if_spi_host_to_card_worker(struct work_struct *work) | |||
838 | 870 | ||
839 | lbs_deb_enter(LBS_DEB_SPI); | 871 | lbs_deb_enter(LBS_DEB_SPI); |
840 | 872 | ||
841 | /* Read the host interrupt status register to see what we | 873 | /* |
842 | * can do. */ | 874 | * Read the host interrupt status register to see what we |
875 | * can do. | ||
876 | */ | ||
843 | err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG, | 877 | err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG, |
844 | &hiStatus); | 878 | &hiStatus); |
845 | if (err) { | 879 | if (err) { |
@@ -858,12 +892,15 @@ static void if_spi_host_to_card_worker(struct work_struct *work) | |||
858 | goto err; | 892 | goto err; |
859 | } | 893 | } |
860 | 894 | ||
861 | /* workaround: in PS mode, the card does not set the Command | 895 | /* |
862 | * Download Ready bit, but it sets TX Download Ready. */ | 896 | * workaround: in PS mode, the card does not set the Command |
897 | * Download Ready bit, but it sets TX Download Ready. | ||
898 | */ | ||
863 | if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || | 899 | if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || |
864 | (card->priv->psstate != PS_STATE_FULL_POWER && | 900 | (card->priv->psstate != PS_STATE_FULL_POWER && |
865 | (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { | 901 | (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { |
866 | /* This means two things. First of all, | 902 | /* |
903 | * This means two things. First of all, | ||
867 | * if there was a previous command sent, the card has | 904 | * if there was a previous command sent, the card has |
868 | * successfully received it. | 905 | * successfully received it. |
869 | * Secondly, it is now ready to download another | 906 | * Secondly, it is now ready to download another |
@@ -871,8 +908,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work) | |||
871 | */ | 908 | */ |
872 | lbs_host_to_card_done(card->priv); | 909 | lbs_host_to_card_done(card->priv); |
873 | 910 | ||
874 | /* Do we have any command packets from the host to | 911 | /* Do we have any command packets from the host to send? */ |
875 | * send? */ | ||
876 | packet = NULL; | 912 | packet = NULL; |
877 | spin_lock_irqsave(&card->buffer_lock, flags); | 913 | spin_lock_irqsave(&card->buffer_lock, flags); |
878 | if (!list_empty(&card->cmd_packet_list)) { | 914 | if (!list_empty(&card->cmd_packet_list)) { |
@@ -886,8 +922,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work) | |||
886 | if_spi_h2c(card, packet, MVMS_CMD); | 922 | if_spi_h2c(card, packet, MVMS_CMD); |
887 | } | 923 | } |
888 | if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) { | 924 | if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) { |
889 | /* Do we have any data packets from the host to | 925 | /* Do we have any data packets from the host to send? */ |
890 | * send? */ | ||
891 | packet = NULL; | 926 | packet = NULL; |
892 | spin_lock_irqsave(&card->buffer_lock, flags); | 927 | spin_lock_irqsave(&card->buffer_lock, flags); |
893 | if (!list_empty(&card->data_packet_list)) { | 928 | if (!list_empty(&card->data_packet_list)) { |
@@ -914,7 +949,8 @@ err: | |||
914 | * Host to Card | 949 | * Host to Card |
915 | * | 950 | * |
916 | * Called from Libertas to transfer some data to the WLAN device | 951 | * Called from Libertas to transfer some data to the WLAN device |
917 | * We can't sleep here. */ | 952 | * We can't sleep here. |
953 | */ | ||
918 | static int if_spi_host_to_card(struct lbs_private *priv, | 954 | static int if_spi_host_to_card(struct lbs_private *priv, |
919 | u8 type, u8 *buf, u16 nb) | 955 | u8 type, u8 *buf, u16 nb) |
920 | { | 956 | { |
@@ -1125,8 +1161,10 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1125 | if (err) | 1161 | if (err) |
1126 | goto free_card; | 1162 | goto free_card; |
1127 | 1163 | ||
1128 | /* Register our card with libertas. | 1164 | /* |
1129 | * This will call alloc_etherdev */ | 1165 | * Register our card with libertas. |
1166 | * This will call alloc_etherdev. | ||
1167 | */ | ||
1130 | priv = lbs_add_card(card, &spi->dev); | 1168 | priv = lbs_add_card(card, &spi->dev); |
1131 | if (!priv) { | 1169 | if (!priv) { |
1132 | err = -ENOMEM; | 1170 | err = -ENOMEM; |
@@ -1153,9 +1191,11 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1153 | goto terminate_workqueue; | 1191 | goto terminate_workqueue; |
1154 | } | 1192 | } |
1155 | 1193 | ||
1156 | /* Start the card. | 1194 | /* |
1195 | * Start the card. | ||
1157 | * This will call register_netdev, and we'll start | 1196 | * This will call register_netdev, and we'll start |
1158 | * getting interrupts... */ | 1197 | * getting interrupts... |
1198 | */ | ||
1159 | err = lbs_start_card(priv); | 1199 | err = lbs_start_card(priv); |
1160 | if (err) | 1200 | if (err) |
1161 | goto release_irq; | 1201 | goto release_irq; |
diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h index d2ac1dcd7e2e..e450e31fd11d 100644 --- a/drivers/net/wireless/libertas/if_spi.h +++ b/drivers/net/wireless/libertas/if_spi.h | |||
@@ -86,34 +86,34 @@ | |||
86 | #define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff) | 86 | #define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff) |
87 | 87 | ||
88 | /***************** IF_SPI_HOST_INT_CTRL_REG *****************/ | 88 | /***************** IF_SPI_HOST_INT_CTRL_REG *****************/ |
89 | /** Host Interrupt Control bit : Wake up */ | 89 | /* Host Interrupt Control bit : Wake up */ |
90 | #define IF_SPI_HICT_WAKE_UP (1<<0) | 90 | #define IF_SPI_HICT_WAKE_UP (1<<0) |
91 | /** Host Interrupt Control bit : WLAN ready */ | 91 | /* Host Interrupt Control bit : WLAN ready */ |
92 | #define IF_SPI_HICT_WLAN_READY (1<<1) | 92 | #define IF_SPI_HICT_WLAN_READY (1<<1) |
93 | /*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY (1<<2) */ | 93 | /*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY (1<<2) */ |
94 | /*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY (1<<3) */ | 94 | /*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY (1<<3) */ |
95 | /*#define IF_SPI_HICT_IRQSRC_WLAN (1<<4) */ | 95 | /*#define IF_SPI_HICT_IRQSRC_WLAN (1<<4) */ |
96 | /** Host Interrupt Control bit : Tx auto download */ | 96 | /* Host Interrupt Control bit : Tx auto download */ |
97 | #define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO (1<<5) | 97 | #define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO (1<<5) |
98 | /** Host Interrupt Control bit : Rx auto upload */ | 98 | /* Host Interrupt Control bit : Rx auto upload */ |
99 | #define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO (1<<6) | 99 | #define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO (1<<6) |
100 | /** Host Interrupt Control bit : Command auto download */ | 100 | /* Host Interrupt Control bit : Command auto download */ |
101 | #define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO (1<<7) | 101 | #define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO (1<<7) |
102 | /** Host Interrupt Control bit : Command auto upload */ | 102 | /* Host Interrupt Control bit : Command auto upload */ |
103 | #define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO (1<<8) | 103 | #define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO (1<<8) |
104 | 104 | ||
105 | /***************** IF_SPI_CARD_INT_CAUSE_REG *****************/ | 105 | /***************** IF_SPI_CARD_INT_CAUSE_REG *****************/ |
106 | /** Card Interrupt Case bit : Tx download over */ | 106 | /* Card Interrupt Case bit : Tx download over */ |
107 | #define IF_SPI_CIC_TX_DOWNLOAD_OVER (1<<0) | 107 | #define IF_SPI_CIC_TX_DOWNLOAD_OVER (1<<0) |
108 | /** Card Interrupt Case bit : Rx upload over */ | 108 | /* Card Interrupt Case bit : Rx upload over */ |
109 | #define IF_SPI_CIC_RX_UPLOAD_OVER (1<<1) | 109 | #define IF_SPI_CIC_RX_UPLOAD_OVER (1<<1) |
110 | /** Card Interrupt Case bit : Command download over */ | 110 | /* Card Interrupt Case bit : Command download over */ |
111 | #define IF_SPI_CIC_CMD_DOWNLOAD_OVER (1<<2) | 111 | #define IF_SPI_CIC_CMD_DOWNLOAD_OVER (1<<2) |
112 | /** Card Interrupt Case bit : Host event */ | 112 | /* Card Interrupt Case bit : Host event */ |
113 | #define IF_SPI_CIC_HOST_EVENT (1<<3) | 113 | #define IF_SPI_CIC_HOST_EVENT (1<<3) |
114 | /** Card Interrupt Case bit : Command upload over */ | 114 | /* Card Interrupt Case bit : Command upload over */ |
115 | #define IF_SPI_CIC_CMD_UPLOAD_OVER (1<<4) | 115 | #define IF_SPI_CIC_CMD_UPLOAD_OVER (1<<4) |
116 | /** Card Interrupt Case bit : Power down */ | 116 | /* Card Interrupt Case bit : Power down */ |
117 | #define IF_SPI_CIC_POWER_DOWN (1<<5) | 117 | #define IF_SPI_CIC_POWER_DOWN (1<<5) |
118 | 118 | ||
119 | /***************** IF_SPI_CARD_INT_STATUS_REG *****************/ | 119 | /***************** IF_SPI_CARD_INT_STATUS_REG *****************/ |
@@ -138,51 +138,51 @@ | |||
138 | #define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW (1<<10) | 138 | #define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW (1<<10) |
139 | 139 | ||
140 | /***************** IF_SPI_HOST_INT_STATUS_REG *****************/ | 140 | /***************** IF_SPI_HOST_INT_STATUS_REG *****************/ |
141 | /** Host Interrupt Status bit : Tx download ready */ | 141 | /* Host Interrupt Status bit : Tx download ready */ |
142 | #define IF_SPI_HIST_TX_DOWNLOAD_RDY (1<<0) | 142 | #define IF_SPI_HIST_TX_DOWNLOAD_RDY (1<<0) |
143 | /** Host Interrupt Status bit : Rx upload ready */ | 143 | /* Host Interrupt Status bit : Rx upload ready */ |
144 | #define IF_SPI_HIST_RX_UPLOAD_RDY (1<<1) | 144 | #define IF_SPI_HIST_RX_UPLOAD_RDY (1<<1) |
145 | /** Host Interrupt Status bit : Command download ready */ | 145 | /* Host Interrupt Status bit : Command download ready */ |
146 | #define IF_SPI_HIST_CMD_DOWNLOAD_RDY (1<<2) | 146 | #define IF_SPI_HIST_CMD_DOWNLOAD_RDY (1<<2) |
147 | /** Host Interrupt Status bit : Card event */ | 147 | /* Host Interrupt Status bit : Card event */ |
148 | #define IF_SPI_HIST_CARD_EVENT (1<<3) | 148 | #define IF_SPI_HIST_CARD_EVENT (1<<3) |
149 | /** Host Interrupt Status bit : Command upload ready */ | 149 | /* Host Interrupt Status bit : Command upload ready */ |
150 | #define IF_SPI_HIST_CMD_UPLOAD_RDY (1<<4) | 150 | #define IF_SPI_HIST_CMD_UPLOAD_RDY (1<<4) |
151 | /** Host Interrupt Status bit : I/O write FIFO overflow */ | 151 | /* Host Interrupt Status bit : I/O write FIFO overflow */ |
152 | #define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW (1<<5) | 152 | #define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW (1<<5) |
153 | /** Host Interrupt Status bit : I/O read FIFO underflow */ | 153 | /* Host Interrupt Status bit : I/O read FIFO underflow */ |
154 | #define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW (1<<6) | 154 | #define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW (1<<6) |
155 | /** Host Interrupt Status bit : Data write FIFO overflow */ | 155 | /* Host Interrupt Status bit : Data write FIFO overflow */ |
156 | #define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW (1<<7) | 156 | #define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW (1<<7) |
157 | /** Host Interrupt Status bit : Data read FIFO underflow */ | 157 | /* Host Interrupt Status bit : Data read FIFO underflow */ |
158 | #define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW (1<<8) | 158 | #define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW (1<<8) |
159 | /** Host Interrupt Status bit : Command write FIFO overflow */ | 159 | /* Host Interrupt Status bit : Command write FIFO overflow */ |
160 | #define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW (1<<9) | 160 | #define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW (1<<9) |
161 | /** Host Interrupt Status bit : Command read FIFO underflow */ | 161 | /* Host Interrupt Status bit : Command read FIFO underflow */ |
162 | #define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW (1<<10) | 162 | #define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW (1<<10) |
163 | 163 | ||
164 | /***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/ | 164 | /***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/ |
165 | /** Host Interrupt Status Mask bit : Tx download ready */ | 165 | /* Host Interrupt Status Mask bit : Tx download ready */ |
166 | #define IF_SPI_HISM_TX_DOWNLOAD_RDY (1<<0) | 166 | #define IF_SPI_HISM_TX_DOWNLOAD_RDY (1<<0) |
167 | /** Host Interrupt Status Mask bit : Rx upload ready */ | 167 | /* Host Interrupt Status Mask bit : Rx upload ready */ |
168 | #define IF_SPI_HISM_RX_UPLOAD_RDY (1<<1) | 168 | #define IF_SPI_HISM_RX_UPLOAD_RDY (1<<1) |
169 | /** Host Interrupt Status Mask bit : Command download ready */ | 169 | /* Host Interrupt Status Mask bit : Command download ready */ |
170 | #define IF_SPI_HISM_CMD_DOWNLOAD_RDY (1<<2) | 170 | #define IF_SPI_HISM_CMD_DOWNLOAD_RDY (1<<2) |
171 | /** Host Interrupt Status Mask bit : Card event */ | 171 | /* Host Interrupt Status Mask bit : Card event */ |
172 | #define IF_SPI_HISM_CARDEVENT (1<<3) | 172 | #define IF_SPI_HISM_CARDEVENT (1<<3) |
173 | /** Host Interrupt Status Mask bit : Command upload ready */ | 173 | /* Host Interrupt Status Mask bit : Command upload ready */ |
174 | #define IF_SPI_HISM_CMD_UPLOAD_RDY (1<<4) | 174 | #define IF_SPI_HISM_CMD_UPLOAD_RDY (1<<4) |
175 | /** Host Interrupt Status Mask bit : I/O write FIFO overflow */ | 175 | /* Host Interrupt Status Mask bit : I/O write FIFO overflow */ |
176 | #define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW (1<<5) | 176 | #define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW (1<<5) |
177 | /** Host Interrupt Status Mask bit : I/O read FIFO underflow */ | 177 | /* Host Interrupt Status Mask bit : I/O read FIFO underflow */ |
178 | #define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW (1<<6) | 178 | #define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW (1<<6) |
179 | /** Host Interrupt Status Mask bit : Data write FIFO overflow */ | 179 | /* Host Interrupt Status Mask bit : Data write FIFO overflow */ |
180 | #define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW (1<<7) | 180 | #define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW (1<<7) |
181 | /** Host Interrupt Status Mask bit : Data write FIFO underflow */ | 181 | /* Host Interrupt Status Mask bit : Data write FIFO underflow */ |
182 | #define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW (1<<8) | 182 | #define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW (1<<8) |
183 | /** Host Interrupt Status Mask bit : Command write FIFO overflow */ | 183 | /* Host Interrupt Status Mask bit : Command write FIFO overflow */ |
184 | #define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW (1<<9) | 184 | #define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW (1<<9) |
185 | /** Host Interrupt Status Mask bit : Command write FIFO underflow */ | 185 | /* Host Interrupt Status Mask bit : Command write FIFO underflow */ |
186 | #define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW (1<<10) | 186 | #define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW (1<<10) |
187 | 187 | ||
188 | /***************** IF_SPI_SPU_BUS_MODE_REG *****************/ | 188 | /***************** IF_SPI_SPU_BUS_MODE_REG *****************/ |
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 6524c70363d9..e1e2128f4113 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /** | 1 | /* |
2 | * This file contains functions used in USB interface module. | 2 | * This file contains functions used in USB interface module. |
3 | */ | 3 | */ |
4 | #include <linux/delay.h> | 4 | #include <linux/delay.h> |
5 | #include <linux/moduleparam.h> | 5 | #include <linux/moduleparam.h> |
6 | #include <linux/firmware.h> | 6 | #include <linux/firmware.h> |
@@ -66,7 +66,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp); | |||
66 | 66 | ||
67 | /* sysfs hooks */ | 67 | /* sysfs hooks */ |
68 | 68 | ||
69 | /** | 69 | /* |
70 | * Set function to write firmware to device's persistent memory | 70 | * Set function to write firmware to device's persistent memory |
71 | */ | 71 | */ |
72 | static ssize_t if_usb_firmware_set(struct device *dev, | 72 | static ssize_t if_usb_firmware_set(struct device *dev, |
@@ -85,7 +85,7 @@ static ssize_t if_usb_firmware_set(struct device *dev, | |||
85 | return ret; | 85 | return ret; |
86 | } | 86 | } |
87 | 87 | ||
88 | /** | 88 | /* |
89 | * lbs_flash_fw attribute to be exported per ethX interface through sysfs | 89 | * lbs_flash_fw attribute to be exported per ethX interface through sysfs |
90 | * (/sys/class/net/ethX/lbs_flash_fw). Use this like so to write firmware to | 90 | * (/sys/class/net/ethX/lbs_flash_fw). Use this like so to write firmware to |
91 | * the device's persistent memory: | 91 | * the device's persistent memory: |
@@ -94,7 +94,14 @@ static ssize_t if_usb_firmware_set(struct device *dev, | |||
94 | static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set); | 94 | static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set); |
95 | 95 | ||
96 | /** | 96 | /** |
97 | * Set function to write firmware to device's persistent memory | 97 | * if_usb_boot2_set - write firmware to device's persistent memory |
98 | * | ||
99 | * @dev: target device | ||
100 | * @attr: device attributes | ||
101 | * @buf: firmware buffer to write | ||
102 | * @count: number of bytes to write | ||
103 | * | ||
104 | * returns: number of bytes written or negative error code | ||
98 | */ | 105 | */ |
99 | static ssize_t if_usb_boot2_set(struct device *dev, | 106 | static ssize_t if_usb_boot2_set(struct device *dev, |
100 | struct device_attribute *attr, const char *buf, size_t count) | 107 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -112,7 +119,7 @@ static ssize_t if_usb_boot2_set(struct device *dev, | |||
112 | return ret; | 119 | return ret; |
113 | } | 120 | } |
114 | 121 | ||
115 | /** | 122 | /* |
116 | * lbs_flash_boot2 attribute to be exported per ethX interface through sysfs | 123 | * lbs_flash_boot2 attribute to be exported per ethX interface through sysfs |
117 | * (/sys/class/net/ethX/lbs_flash_boot2). Use this like so to write firmware | 124 | * (/sys/class/net/ethX/lbs_flash_boot2). Use this like so to write firmware |
118 | * to the device's persistent memory: | 125 | * to the device's persistent memory: |
@@ -121,9 +128,10 @@ static ssize_t if_usb_boot2_set(struct device *dev, | |||
121 | static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set); | 128 | static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set); |
122 | 129 | ||
123 | /** | 130 | /** |
124 | * @brief call back function to handle the status of the URB | 131 | * if_usb_write_bulk_callback - callback function to handle the status |
125 | * @param urb pointer to urb structure | 132 | * of the URB |
126 | * @return N/A | 133 | * @urb: pointer to &urb structure |
134 | * returns: N/A | ||
127 | */ | 135 | */ |
128 | static void if_usb_write_bulk_callback(struct urb *urb) | 136 | static void if_usb_write_bulk_callback(struct urb *urb) |
129 | { | 137 | { |
@@ -150,9 +158,9 @@ static void if_usb_write_bulk_callback(struct urb *urb) | |||
150 | } | 158 | } |
151 | 159 | ||
152 | /** | 160 | /** |
153 | * @brief free tx/rx urb, skb and rx buffer | 161 | * if_usb_free - free tx/rx urb, skb and rx buffer |
154 | * @param cardp pointer if_usb_card | 162 | * @cardp: pointer to &if_usb_card |
155 | * @return N/A | 163 | * returns: N/A |
156 | */ | 164 | */ |
157 | static void if_usb_free(struct if_usb_card *cardp) | 165 | static void if_usb_free(struct if_usb_card *cardp) |
158 | { | 166 | { |
@@ -231,10 +239,10 @@ static void if_usb_reset_olpc_card(struct lbs_private *priv) | |||
231 | #endif | 239 | #endif |
232 | 240 | ||
233 | /** | 241 | /** |
234 | * @brief sets the configuration values | 242 | * if_usb_probe - sets the configuration values |
235 | * @param ifnum interface number | 243 | * @intf: &usb_interface pointer |
236 | * @param id pointer to usb_device_id | 244 | * @id: pointer to usb_device_id |
237 | * @return 0 on success, error code on failure | 245 | * returns: 0 on success, error code on failure |
238 | */ | 246 | */ |
239 | static int if_usb_probe(struct usb_interface *intf, | 247 | static int if_usb_probe(struct usb_interface *intf, |
240 | const struct usb_device_id *id) | 248 | const struct usb_device_id *id) |
@@ -366,9 +374,9 @@ error: | |||
366 | } | 374 | } |
367 | 375 | ||
368 | /** | 376 | /** |
369 | * @brief free resource and cleanup | 377 | * if_usb_disconnect - free resource and cleanup |
370 | * @param intf USB interface structure | 378 | * @intf: USB interface structure |
371 | * @return N/A | 379 | * returns: N/A |
372 | */ | 380 | */ |
373 | static void if_usb_disconnect(struct usb_interface *intf) | 381 | static void if_usb_disconnect(struct usb_interface *intf) |
374 | { | 382 | { |
@@ -398,9 +406,9 @@ static void if_usb_disconnect(struct usb_interface *intf) | |||
398 | } | 406 | } |
399 | 407 | ||
400 | /** | 408 | /** |
401 | * @brief This function download FW | 409 | * if_usb_send_fw_pkt - download FW |
402 | * @param priv pointer to struct lbs_private | 410 | * @cardp: pointer to &struct if_usb_card |
403 | * @return 0 | 411 | * returns: 0 |
404 | */ | 412 | */ |
405 | static int if_usb_send_fw_pkt(struct if_usb_card *cardp) | 413 | static int if_usb_send_fw_pkt(struct if_usb_card *cardp) |
406 | { | 414 | { |
@@ -486,11 +494,11 @@ static int if_usb_reset_device(struct if_usb_card *cardp) | |||
486 | } | 494 | } |
487 | 495 | ||
488 | /** | 496 | /** |
489 | * @brief This function transfer the data to the device. | 497 | * usb_tx_block - transfer the data to the device |
490 | * @param priv pointer to struct lbs_private | 498 | * @cardp: pointer to &struct if_usb_card |
491 | * @param payload pointer to payload data | 499 | * @payload: pointer to payload data |
492 | * @param nb data length | 500 | * @nb: data length |
493 | * @return 0 or -1 | 501 | * returns: 0 for success or negative error code |
494 | */ | 502 | */ |
495 | static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb) | 503 | static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb) |
496 | { | 504 | { |
@@ -727,11 +735,11 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, | |||
727 | } | 735 | } |
728 | 736 | ||
729 | /** | 737 | /** |
730 | * @brief This function reads of the packet into the upload buff, | 738 | * if_usb_receive - read the packet into the upload buffer, |
731 | * wake up the main thread and initialise the Rx callack. | 739 | * wake up the main thread and initialise the Rx callack |
732 | * | 740 | * |
733 | * @param urb pointer to struct urb | 741 | * @urb: pointer to &struct urb |
734 | * @return N/A | 742 | * returns: N/A |
735 | */ | 743 | */ |
736 | static void if_usb_receive(struct urb *urb) | 744 | static void if_usb_receive(struct urb *urb) |
737 | { | 745 | { |
@@ -802,12 +810,12 @@ rx_exit: | |||
802 | } | 810 | } |
803 | 811 | ||
804 | /** | 812 | /** |
805 | * @brief This function downloads data to FW | 813 | * if_usb_host_to_card - downloads data to FW |
806 | * @param priv pointer to struct lbs_private structure | 814 | * @priv: pointer to &struct lbs_private structure |
807 | * @param type type of data | 815 | * @type: type of data |
808 | * @param buf pointer to data buffer | 816 | * @payload: pointer to data buffer |
809 | * @param len number of bytes | 817 | * @nb: number of bytes |
810 | * @return 0 or -1 | 818 | * returns: 0 for success or negative error code |
811 | */ | 819 | */ |
812 | static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, | 820 | static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, |
813 | uint8_t *payload, uint16_t nb) | 821 | uint8_t *payload, uint16_t nb) |
@@ -831,10 +839,11 @@ static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, | |||
831 | } | 839 | } |
832 | 840 | ||
833 | /** | 841 | /** |
834 | * @brief This function issues Boot command to the Boot2 code | 842 | * if_usb_issue_boot_command - issues Boot command to the Boot2 code |
835 | * @param ivalue 1:Boot from FW by USB-Download | 843 | * @cardp: pointer to &if_usb_card |
836 | * 2:Boot from FW in EEPROM | 844 | * @ivalue: 1:Boot from FW by USB-Download |
837 | * @return 0 | 845 | * 2:Boot from FW in EEPROM |
846 | * returns: 0 for success or negative error code | ||
838 | */ | 847 | */ |
839 | static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue) | 848 | static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue) |
840 | { | 849 | { |
@@ -853,11 +862,11 @@ static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue) | |||
853 | 862 | ||
854 | 863 | ||
855 | /** | 864 | /** |
856 | * @brief This function checks the validity of Boot2/FW image. | 865 | * check_fwfile_format - check the validity of Boot2/FW image |
857 | * | 866 | * |
858 | * @param data pointer to image | 867 | * @data: pointer to image |
859 | * len image length | 868 | * @totlen: image length |
860 | * @return 0 or -1 | 869 | * returns: 0 (good) or 1 (failure) |
861 | */ | 870 | */ |
862 | static int check_fwfile_format(const uint8_t *data, uint32_t totlen) | 871 | static int check_fwfile_format(const uint8_t *data, uint32_t totlen) |
863 | { | 872 | { |
@@ -901,13 +910,13 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen) | |||
901 | 910 | ||
902 | 911 | ||
903 | /** | 912 | /** |
904 | * @brief This function programs the firmware subject to cmd | 913 | * if_usb_prog_firmware - programs the firmware subject to cmd |
905 | * | 914 | * |
906 | * @param cardp the if_usb_card descriptor | 915 | * @cardp: the if_usb_card descriptor |
907 | * fwname firmware or boot2 image file name | 916 | * @fwname: firmware or boot2 image file name |
908 | * cmd either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW, | 917 | * @cmd: either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW, |
909 | * or BOOT_CMD_UPDATE_BOOT2. | 918 | * or BOOT_CMD_UPDATE_BOOT2. |
910 | * @return 0 or error code | 919 | * returns: 0 or error code |
911 | */ | 920 | */ |
912 | static int if_usb_prog_firmware(struct if_usb_card *cardp, | 921 | static int if_usb_prog_firmware(struct if_usb_card *cardp, |
913 | const char *fwname, int cmd) | 922 | const char *fwname, int cmd) |
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h index d819e7e3c9aa..6e42eac331de 100644 --- a/drivers/net/wireless/libertas/if_usb.h +++ b/drivers/net/wireless/libertas/if_usb.h | |||
@@ -6,9 +6,9 @@ | |||
6 | 6 | ||
7 | struct lbs_private; | 7 | struct lbs_private; |
8 | 8 | ||
9 | /** | 9 | /* |
10 | * This file contains definition for USB interface. | 10 | * This file contains definition for USB interface. |
11 | */ | 11 | */ |
12 | #define CMD_TYPE_REQUEST 0xF00DFACE | 12 | #define CMD_TYPE_REQUEST 0xF00DFACE |
13 | #define CMD_TYPE_DATA 0xBEADC0DE | 13 | #define CMD_TYPE_DATA 0xBEADC0DE |
14 | #define CMD_TYPE_INDICATION 0xBEEFFACE | 14 | #define CMD_TYPE_INDICATION 0xBEEFFACE |
@@ -40,7 +40,7 @@ struct bootcmdresp | |||
40 | uint8_t pad[2]; | 40 | uint8_t pad[2]; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | /** USB card description structure*/ | 43 | /* USB card description structure*/ |
44 | struct if_usb_card { | 44 | struct if_usb_card { |
45 | struct usb_device *udev; | 45 | struct usb_device *udev; |
46 | uint32_t model; /* MODEL_* */ | 46 | uint32_t model; /* MODEL_* */ |
@@ -77,7 +77,7 @@ struct if_usb_card { | |||
77 | __le16 boot2_version; | 77 | __le16 boot2_version; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | /** fwheader */ | 80 | /* fwheader */ |
81 | struct fwheader { | 81 | struct fwheader { |
82 | __le32 dnldcmd; | 82 | __le32 dnldcmd; |
83 | __le32 baseaddr; | 83 | __le32 baseaddr; |
@@ -86,14 +86,14 @@ struct fwheader { | |||
86 | }; | 86 | }; |
87 | 87 | ||
88 | #define FW_MAX_DATA_BLK_SIZE 600 | 88 | #define FW_MAX_DATA_BLK_SIZE 600 |
89 | /** FWData */ | 89 | /* FWData */ |
90 | struct fwdata { | 90 | struct fwdata { |
91 | struct fwheader hdr; | 91 | struct fwheader hdr; |
92 | __le32 seqnum; | 92 | __le32 seqnum; |
93 | uint8_t data[0]; | 93 | uint8_t data[0]; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | /** fwsyncheader */ | 96 | /* fwsyncheader */ |
97 | struct fwsyncheader { | 97 | struct fwsyncheader { |
98 | __le32 cmd; | 98 | __le32 cmd; |
99 | __le32 seqnum; | 99 | __le32 seqnum; |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index ca8149cd5bd9..ed57cf863b69 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /** | 1 | /* |
2 | * This file contains the major functions in WLAN | 2 | * This file contains the major functions in WLAN |
3 | * driver. It includes init, exit, open, close and main | 3 | * driver. It includes init, exit, open, close and main |
4 | * thread etc.. | 4 | * thread etc.. |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/moduleparam.h> | 7 | #include <linux/moduleparam.h> |
8 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
@@ -35,18 +35,20 @@ EXPORT_SYMBOL_GPL(lbs_debug); | |||
35 | module_param_named(libertas_debug, lbs_debug, int, 0644); | 35 | module_param_named(libertas_debug, lbs_debug, int, 0644); |
36 | 36 | ||
37 | 37 | ||
38 | /* This global structure is used to send the confirm_sleep command as | 38 | /* |
39 | * fast as possible down to the firmware. */ | 39 | * This global structure is used to send the confirm_sleep command as |
40 | * fast as possible down to the firmware. | ||
41 | */ | ||
40 | struct cmd_confirm_sleep confirm_sleep; | 42 | struct cmd_confirm_sleep confirm_sleep; |
41 | 43 | ||
42 | 44 | ||
43 | /** | 45 | /* |
44 | * the table to keep region code | 46 | * the table to keep region code |
45 | */ | 47 | */ |
46 | u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] = | 48 | u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] = |
47 | { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; | 49 | { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; |
48 | 50 | ||
49 | /** | 51 | /* |
50 | * FW rate table. FW refers to rates by their index in this table, not by the | 52 | * FW rate table. FW refers to rates by their index in this table, not by the |
51 | * rate value itself. Values of 0x00 are | 53 | * rate value itself. Values of 0x00 are |
52 | * reserved positions. | 54 | * reserved positions. |
@@ -57,10 +59,10 @@ static u8 fw_data_rates[MAX_RATES] = | |||
57 | }; | 59 | }; |
58 | 60 | ||
59 | /** | 61 | /** |
60 | * @brief use index to get the data rate | 62 | * lbs_fw_index_to_data_rate - use index to get the data rate |
61 | * | 63 | * |
62 | * @param idx The index of data rate | 64 | * @idx: The index of data rate |
63 | * @return data rate or 0 | 65 | * returns: data rate or 0 |
64 | */ | 66 | */ |
65 | u32 lbs_fw_index_to_data_rate(u8 idx) | 67 | u32 lbs_fw_index_to_data_rate(u8 idx) |
66 | { | 68 | { |
@@ -70,10 +72,10 @@ u32 lbs_fw_index_to_data_rate(u8 idx) | |||
70 | } | 72 | } |
71 | 73 | ||
72 | /** | 74 | /** |
73 | * @brief use rate to get the index | 75 | * lbs_data_rate_to_fw_index - use rate to get the index |
74 | * | 76 | * |
75 | * @param rate data rate | 77 | * @rate: data rate |
76 | * @return index or 0 | 78 | * returns: index or 0 |
77 | */ | 79 | */ |
78 | u8 lbs_data_rate_to_fw_index(u32 rate) | 80 | u8 lbs_data_rate_to_fw_index(u32 rate) |
79 | { | 81 | { |
@@ -91,10 +93,10 @@ u8 lbs_data_rate_to_fw_index(u32 rate) | |||
91 | 93 | ||
92 | 94 | ||
93 | /** | 95 | /** |
94 | * @brief This function opens the ethX interface | 96 | * lbs_dev_open - open the ethX interface |
95 | * | 97 | * |
96 | * @param dev A pointer to net_device structure | 98 | * @dev: A pointer to &net_device structure |
97 | * @return 0 or -EBUSY if monitor mode active | 99 | * returns: 0 or -EBUSY if monitor mode active |
98 | */ | 100 | */ |
99 | static int lbs_dev_open(struct net_device *dev) | 101 | static int lbs_dev_open(struct net_device *dev) |
100 | { | 102 | { |
@@ -120,10 +122,10 @@ static int lbs_dev_open(struct net_device *dev) | |||
120 | } | 122 | } |
121 | 123 | ||
122 | /** | 124 | /** |
123 | * @brief This function closes the ethX interface | 125 | * lbs_eth_stop - close the ethX interface |
124 | * | 126 | * |
125 | * @param dev A pointer to net_device structure | 127 | * @dev: A pointer to &net_device structure |
126 | * @return 0 | 128 | * returns: 0 |
127 | */ | 129 | */ |
128 | static int lbs_eth_stop(struct net_device *dev) | 130 | static int lbs_eth_stop(struct net_device *dev) |
129 | { | 131 | { |
@@ -336,12 +338,12 @@ void lbs_set_multicast_list(struct net_device *dev) | |||
336 | } | 338 | } |
337 | 339 | ||
338 | /** | 340 | /** |
339 | * @brief This function handles the major jobs in the LBS driver. | 341 | * lbs_thread - handles the major jobs in the LBS driver. |
340 | * It handles all events generated by firmware, RX data received | 342 | * It handles all events generated by firmware, RX data received |
341 | * from firmware and TX data sent from kernel. | 343 | * from firmware and TX data sent from kernel. |
342 | * | 344 | * |
343 | * @param data A pointer to lbs_thread structure | 345 | * @data: A pointer to &lbs_thread structure |
344 | * @return 0 | 346 | * returns: 0 |
345 | */ | 347 | */ |
346 | static int lbs_thread(void *data) | 348 | static int lbs_thread(void *data) |
347 | { | 349 | { |
@@ -540,11 +542,11 @@ static int lbs_thread(void *data) | |||
540 | } | 542 | } |
541 | 543 | ||
542 | /** | 544 | /** |
543 | * @brief This function gets the HW spec from the firmware and sets | 545 | * lbs_setup_firmware - gets the HW spec from the firmware and sets |
544 | * some basic parameters. | 546 | * some basic parameters |
545 | * | 547 | * |
546 | * @param priv A pointer to struct lbs_private structure | 548 | * @priv: A pointer to &struct lbs_private structure |
547 | * @return 0 or -1 | 549 | * returns: 0 or -1 |
548 | */ | 550 | */ |
549 | static int lbs_setup_firmware(struct lbs_private *priv) | 551 | static int lbs_setup_firmware(struct lbs_private *priv) |
550 | { | 552 | { |
@@ -630,8 +632,10 @@ int lbs_resume(struct lbs_private *priv) | |||
630 | EXPORT_SYMBOL_GPL(lbs_resume); | 632 | EXPORT_SYMBOL_GPL(lbs_resume); |
631 | 633 | ||
632 | /** | 634 | /** |
633 | * This function handles the timeout of command sending. | 635 | * lbs_cmd_timeout_handler - handles the timeout of command sending. |
634 | * It will re-send the same command again. | 636 | * It will re-send the same command again. |
637 | * | ||
638 | * @data: &struct lbs_private pointer | ||
635 | */ | 639 | */ |
636 | static void lbs_cmd_timeout_handler(unsigned long data) | 640 | static void lbs_cmd_timeout_handler(unsigned long data) |
637 | { | 641 | { |
@@ -655,8 +659,10 @@ out: | |||
655 | } | 659 | } |
656 | 660 | ||
657 | /** | 661 | /** |
658 | * This function put the device back to deep sleep mode when timer expires | 662 | * auto_deepsleep_timer_fn - put the device back to deep sleep mode when |
659 | * and no activity (command, event, data etc.) is detected. | 663 | * timer expires and no activity (command, event, data etc.) is detected. |
664 | * @data: &struct lbs_private pointer | ||
665 | * returns: N/A | ||
660 | */ | 666 | */ |
661 | static void auto_deepsleep_timer_fn(unsigned long data) | 667 | static void auto_deepsleep_timer_fn(unsigned long data) |
662 | { | 668 | { |
@@ -792,11 +798,12 @@ static const struct net_device_ops lbs_netdev_ops = { | |||
792 | }; | 798 | }; |
793 | 799 | ||
794 | /** | 800 | /** |
795 | * @brief This function adds the card. it will probe the | 801 | * lbs_add_card - adds the card. It will probe the |
796 | * card, allocate the lbs_priv and initialize the device. | 802 | * card, allocate the lbs_priv and initialize the device. |
797 | * | 803 | * |
798 | * @param card A pointer to card | 804 | * @card: A pointer to card |
799 | * @return A pointer to struct lbs_private structure | 805 | * @dmdev: A pointer to &struct device |
806 | * returns: A pointer to &struct lbs_private structure | ||
800 | */ | 807 | */ |
801 | struct lbs_private *lbs_add_card(void *card, struct device *dmdev) | 808 | struct lbs_private *lbs_add_card(void *card, struct device *dmdev) |
802 | { | 809 | { |
@@ -1057,19 +1064,19 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx) | |||
1057 | EXPORT_SYMBOL_GPL(lbs_notify_command_response); | 1064 | EXPORT_SYMBOL_GPL(lbs_notify_command_response); |
1058 | 1065 | ||
1059 | /** | 1066 | /** |
1060 | * @brief Retrieves two-stage firmware | 1067 | * lbs_get_firmware - Retrieves two-stage firmware |
1061 | * | 1068 | * |
1062 | * @param dev A pointer to device structure | 1069 | * @dev: A pointer to &device structure |
1063 | * @param user_helper User-defined helper firmware file | 1070 | * @user_helper: User-defined helper firmware file |
1064 | * @param user_mainfw User-defined main firmware file | 1071 | * @user_mainfw: User-defined main firmware file |
1065 | * @param card_model Bus-specific card model ID used to filter firmware table | 1072 | * @card_model: Bus-specific card model ID used to filter firmware table |
1066 | * elements | 1073 | * elements |
1067 | * @param fw_table Table of firmware file names and device model numbers | 1074 | * @fw_table: Table of firmware file names and device model numbers |
1068 | * terminated by an entry with a NULL helper name | 1075 | * terminated by an entry with a NULL helper name |
1069 | * @param helper On success, the helper firmware; caller must free | 1076 | * @helper: On success, the helper firmware; caller must free |
1070 | * @param mainfw On success, the main firmware; caller must free | 1077 | * @mainfw: On success, the main firmware; caller must free |
1071 | * | 1078 | * |
1072 | * @return 0 on success, non-zero on failure | 1079 | * returns: 0 on success, non-zero on failure |
1073 | */ | 1080 | */ |
1074 | int lbs_get_firmware(struct device *dev, const char *user_helper, | 1081 | int lbs_get_firmware(struct device *dev, const char *user_helper, |
1075 | const char *user_mainfw, u32 card_model, | 1082 | const char *user_mainfw, u32 card_model, |
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 9d097b9c8005..a0804d12bf20 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c | |||
@@ -16,12 +16,15 @@ | |||
16 | * Mesh sysfs support | 16 | * Mesh sysfs support |
17 | */ | 17 | */ |
18 | 18 | ||
19 | /** | 19 | /* |
20 | * Attributes exported through sysfs | 20 | * Attributes exported through sysfs |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * @brief Get function for sysfs attribute anycast_mask | 24 | * lbs_anycast_get - Get function for sysfs attribute anycast_mask |
25 | * @dev: the &struct device | ||
26 | * @attr: device attributes | ||
27 | * @buf: buffer where data will be returned | ||
25 | */ | 28 | */ |
26 | static ssize_t lbs_anycast_get(struct device *dev, | 29 | static ssize_t lbs_anycast_get(struct device *dev, |
27 | struct device_attribute *attr, char * buf) | 30 | struct device_attribute *attr, char * buf) |
@@ -40,7 +43,11 @@ static ssize_t lbs_anycast_get(struct device *dev, | |||
40 | } | 43 | } |
41 | 44 | ||
42 | /** | 45 | /** |
43 | * @brief Set function for sysfs attribute anycast_mask | 46 | * lbs_anycast_set - Set function for sysfs attribute anycast_mask |
47 | * @dev: the &struct device | ||
48 | * @attr: device attributes | ||
49 | * @buf: buffer that contains new attribute value | ||
50 | * @count: size of buffer | ||
44 | */ | 51 | */ |
45 | static ssize_t lbs_anycast_set(struct device *dev, | 52 | static ssize_t lbs_anycast_set(struct device *dev, |
46 | struct device_attribute *attr, const char * buf, size_t count) | 53 | struct device_attribute *attr, const char * buf, size_t count) |
@@ -62,7 +69,10 @@ static ssize_t lbs_anycast_set(struct device *dev, | |||
62 | } | 69 | } |
63 | 70 | ||
64 | /** | 71 | /** |
65 | * @brief Get function for sysfs attribute prb_rsp_limit | 72 | * lbs_prb_rsp_limit_get - Get function for sysfs attribute prb_rsp_limit |
73 | * @dev: the &struct device | ||
74 | * @attr: device attributes | ||
75 | * @buf: buffer where data will be returned | ||
66 | */ | 76 | */ |
67 | static ssize_t lbs_prb_rsp_limit_get(struct device *dev, | 77 | static ssize_t lbs_prb_rsp_limit_get(struct device *dev, |
68 | struct device_attribute *attr, char *buf) | 78 | struct device_attribute *attr, char *buf) |
@@ -85,7 +95,11 @@ static ssize_t lbs_prb_rsp_limit_get(struct device *dev, | |||
85 | } | 95 | } |
86 | 96 | ||
87 | /** | 97 | /** |
88 | * @brief Set function for sysfs attribute prb_rsp_limit | 98 | * lbs_prb_rsp_limit_set - Set function for sysfs attribute prb_rsp_limit |
99 | * @dev: the &struct device | ||
100 | * @attr: device attributes | ||
101 | * @buf: buffer that contains new attribute value | ||
102 | * @count: size of buffer | ||
89 | */ | 103 | */ |
90 | static ssize_t lbs_prb_rsp_limit_set(struct device *dev, | 104 | static ssize_t lbs_prb_rsp_limit_set(struct device *dev, |
91 | struct device_attribute *attr, const char *buf, size_t count) | 105 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -114,7 +128,10 @@ static ssize_t lbs_prb_rsp_limit_set(struct device *dev, | |||
114 | } | 128 | } |
115 | 129 | ||
116 | /** | 130 | /** |
117 | * Get function for sysfs attribute mesh | 131 | * lbs_mesh_get - Get function for sysfs attribute mesh |
132 | * @dev: the &struct device | ||
133 | * @attr: device attributes | ||
134 | * @buf: buffer where data will be returned | ||
118 | */ | 135 | */ |
119 | static ssize_t lbs_mesh_get(struct device *dev, | 136 | static ssize_t lbs_mesh_get(struct device *dev, |
120 | struct device_attribute *attr, char * buf) | 137 | struct device_attribute *attr, char * buf) |
@@ -124,7 +141,11 @@ static ssize_t lbs_mesh_get(struct device *dev, | |||
124 | } | 141 | } |
125 | 142 | ||
126 | /** | 143 | /** |
127 | * Set function for sysfs attribute mesh | 144 | * lbs_mesh_set - Set function for sysfs attribute mesh |
145 | * @dev: the &struct device | ||
146 | * @attr: device attributes | ||
147 | * @buf: buffer that contains new attribute value | ||
148 | * @count: size of buffer | ||
128 | */ | 149 | */ |
129 | static ssize_t lbs_mesh_set(struct device *dev, | 150 | static ssize_t lbs_mesh_set(struct device *dev, |
130 | struct device_attribute *attr, const char * buf, size_t count) | 151 | struct device_attribute *attr, const char * buf, size_t count) |
@@ -151,19 +172,19 @@ static ssize_t lbs_mesh_set(struct device *dev, | |||
151 | return count; | 172 | return count; |
152 | } | 173 | } |
153 | 174 | ||
154 | /** | 175 | /* |
155 | * lbs_mesh attribute to be exported per ethX interface | 176 | * lbs_mesh attribute to be exported per ethX interface |
156 | * through sysfs (/sys/class/net/ethX/lbs_mesh) | 177 | * through sysfs (/sys/class/net/ethX/lbs_mesh) |
157 | */ | 178 | */ |
158 | static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set); | 179 | static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set); |
159 | 180 | ||
160 | /** | 181 | /* |
161 | * anycast_mask attribute to be exported per mshX interface | 182 | * anycast_mask attribute to be exported per mshX interface |
162 | * through sysfs (/sys/class/net/mshX/anycast_mask) | 183 | * through sysfs (/sys/class/net/mshX/anycast_mask) |
163 | */ | 184 | */ |
164 | static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set); | 185 | static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set); |
165 | 186 | ||
166 | /** | 187 | /* |
167 | * prb_rsp_limit attribute to be exported per mshX interface | 188 | * prb_rsp_limit attribute to be exported per mshX interface |
168 | * through sysfs (/sys/class/net/mshX/prb_rsp_limit) | 189 | * through sysfs (/sys/class/net/mshX/prb_rsp_limit) |
169 | */ | 190 | */ |
@@ -274,10 +295,10 @@ int lbs_deinit_mesh(struct lbs_private *priv) | |||
274 | 295 | ||
275 | 296 | ||
276 | /** | 297 | /** |
277 | * @brief This function closes the mshX interface | 298 | * lbs_mesh_stop - close the mshX interface |
278 | * | 299 | * |
279 | * @param dev A pointer to net_device structure | 300 | * @dev: A pointer to &net_device structure |
280 | * @return 0 | 301 | * returns: 0 |
281 | */ | 302 | */ |
282 | static int lbs_mesh_stop(struct net_device *dev) | 303 | static int lbs_mesh_stop(struct net_device *dev) |
283 | { | 304 | { |
@@ -301,10 +322,10 @@ static int lbs_mesh_stop(struct net_device *dev) | |||
301 | } | 322 | } |
302 | 323 | ||
303 | /** | 324 | /** |
304 | * @brief This function opens the mshX interface | 325 | * lbs_mesh_dev_open - open the mshX interface |
305 | * | 326 | * |
306 | * @param dev A pointer to net_device structure | 327 | * @dev: A pointer to &net_device structure |
307 | * @return 0 or -EBUSY if monitor mode active | 328 | * returns: 0 or -EBUSY if monitor mode active |
308 | */ | 329 | */ |
309 | static int lbs_mesh_dev_open(struct net_device *dev) | 330 | static int lbs_mesh_dev_open(struct net_device *dev) |
310 | { | 331 | { |
@@ -342,10 +363,10 @@ static const struct net_device_ops mesh_netdev_ops = { | |||
342 | }; | 363 | }; |
343 | 364 | ||
344 | /** | 365 | /** |
345 | * @brief This function adds mshX interface | 366 | * lbs_add_mesh - add mshX interface |
346 | * | 367 | * |
347 | * @param priv A pointer to the struct lbs_private structure | 368 | * @priv: A pointer to the &struct lbs_private structure |
348 | * @return 0 if successful, -X otherwise | 369 | * returns: 0 if successful, -X otherwise |
349 | */ | 370 | */ |
350 | int lbs_add_mesh(struct lbs_private *priv) | 371 | int lbs_add_mesh(struct lbs_private *priv) |
351 | { | 372 | { |
@@ -456,13 +477,13 @@ void lbs_mesh_set_txpd(struct lbs_private *priv, | |||
456 | */ | 477 | */ |
457 | 478 | ||
458 | /** | 479 | /** |
459 | * @brief Add or delete Mesh Blinding Table entries | 480 | * lbs_mesh_bt_add_del - Add or delete Mesh Blinding Table entries |
460 | * | 481 | * |
461 | * @param priv A pointer to struct lbs_private structure | 482 | * @priv: A pointer to &struct lbs_private structure |
462 | * @param add TRUE to add the entry, FALSE to delete it | 483 | * @add: TRUE to add the entry, FALSE to delete it |
463 | * @param addr1 Destination address to blind or unblind | 484 | * @addr1: Destination address to blind or unblind |
464 | * | 485 | * |
465 | * @return 0 on success, error on failure | 486 | * returns: 0 on success, error on failure |
466 | */ | 487 | */ |
467 | int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1) | 488 | int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1) |
468 | { | 489 | { |
@@ -493,11 +514,11 @@ int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1) | |||
493 | } | 514 | } |
494 | 515 | ||
495 | /** | 516 | /** |
496 | * @brief Reset/clear the mesh blinding table | 517 | * lbs_mesh_bt_reset - Reset/clear the mesh blinding table |
497 | * | 518 | * |
498 | * @param priv A pointer to struct lbs_private structure | 519 | * @priv: A pointer to &struct lbs_private structure |
499 | * | 520 | * |
500 | * @return 0 on success, error on failure | 521 | * returns: 0 on success, error on failure |
501 | */ | 522 | */ |
502 | int lbs_mesh_bt_reset(struct lbs_private *priv) | 523 | int lbs_mesh_bt_reset(struct lbs_private *priv) |
503 | { | 524 | { |
@@ -517,17 +538,18 @@ int lbs_mesh_bt_reset(struct lbs_private *priv) | |||
517 | } | 538 | } |
518 | 539 | ||
519 | /** | 540 | /** |
520 | * @brief Gets the inverted status of the mesh blinding table | 541 | * lbs_mesh_bt_get_inverted - Gets the inverted status of the mesh |
542 | * blinding table | ||
521 | * | 543 | * |
522 | * Normally the firmware "blinds" or ignores traffic from mesh nodes in the | 544 | * Normally the firmware "blinds" or ignores traffic from mesh nodes in the |
523 | * table, but an inverted table allows *only* traffic from nodes listed in | 545 | * table, but an inverted table allows *only* traffic from nodes listed in |
524 | * the table. | 546 | * the table. |
525 | * | 547 | * |
526 | * @param priv A pointer to struct lbs_private structure | 548 | * @priv: A pointer to &struct lbs_private structure |
527 | * @param invert On success, TRUE if the blinding table is inverted, | 549 | * @inverted: On success, TRUE if the blinding table is inverted, |
528 | * FALSE if it is not inverted | 550 | * FALSE if it is not inverted |
529 | * | 551 | * |
530 | * @return 0 on success, error on failure | 552 | * returns: 0 on success, error on failure |
531 | */ | 553 | */ |
532 | int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) | 554 | int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) |
533 | { | 555 | { |
@@ -551,18 +573,19 @@ int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) | |||
551 | } | 573 | } |
552 | 574 | ||
553 | /** | 575 | /** |
554 | * @brief Sets the inverted status of the mesh blinding table | 576 | * lbs_mesh_bt_set_inverted - Sets the inverted status of the mesh |
577 | * blinding table | ||
555 | * | 578 | * |
556 | * Normally the firmware "blinds" or ignores traffic from mesh nodes in the | 579 | * Normally the firmware "blinds" or ignores traffic from mesh nodes in the |
557 | * table, but an inverted table allows *only* traffic from nodes listed in | 580 | * table, but an inverted table allows *only* traffic from nodes listed in |
558 | * the table. | 581 | * the table. |
559 | * | 582 | * |
560 | * @param priv A pointer to struct lbs_private structure | 583 | * @priv: A pointer to &struct lbs_private structure |
561 | * @param invert TRUE to invert the blinding table (only traffic from | 584 | * @inverted: TRUE to invert the blinding table (only traffic from |
562 | * listed nodes allowed), FALSE to return it | 585 | * listed nodes allowed), FALSE to return it |
563 | * to normal state (listed nodes ignored) | 586 | * to normal state (listed nodes ignored) |
564 | * | 587 | * |
565 | * @return 0 on success, error on failure | 588 | * returns: 0 on success, error on failure |
566 | */ | 589 | */ |
567 | int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) | 590 | int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) |
568 | { | 591 | { |
@@ -583,13 +606,13 @@ int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) | |||
583 | } | 606 | } |
584 | 607 | ||
585 | /** | 608 | /** |
586 | * @brief List an entry in the mesh blinding table | 609 | * lbs_mesh_bt_get_entry - List an entry in the mesh blinding table |
587 | * | 610 | * |
588 | * @param priv A pointer to struct lbs_private structure | 611 | * @priv: A pointer to &struct lbs_private structure |
589 | * @param id The ID of the entry to list | 612 | * @id: The ID of the entry to list |
590 | * @param addr1 MAC address associated with the table entry | 613 | * @addr1: MAC address associated with the table entry |
591 | * | 614 | * |
592 | * @return 0 on success, error on failure | 615 | * returns: 0 on success, error on failure |
593 | */ | 616 | */ |
594 | int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) | 617 | int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) |
595 | { | 618 | { |
@@ -614,14 +637,14 @@ int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) | |||
614 | } | 637 | } |
615 | 638 | ||
616 | /** | 639 | /** |
617 | * @brief Access the mesh forwarding table | 640 | * lbs_cmd_fwt_access - Access the mesh forwarding table |
618 | * | 641 | * |
619 | * @param priv A pointer to struct lbs_private structure | 642 | * @priv: A pointer to &struct lbs_private structure |
620 | * @param cmd_action The forwarding table action to perform | 643 | * @cmd_action: The forwarding table action to perform |
621 | * @param cmd The pre-filled FWT_ACCESS command | 644 | * @cmd: The pre-filled FWT_ACCESS command |
622 | * | 645 | * |
623 | * @return 0 on success and 'cmd' will be filled with the | 646 | * returns: 0 on success and 'cmd' will be filled with the |
624 | * firmware's response | 647 | * firmware's response |
625 | */ | 648 | */ |
626 | int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, | 649 | int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, |
627 | struct cmd_ds_fwt_access *cmd) | 650 | struct cmd_ds_fwt_access *cmd) |
@@ -774,7 +797,10 @@ static int mesh_get_default_parameters(struct device *dev, | |||
774 | } | 797 | } |
775 | 798 | ||
776 | /** | 799 | /** |
777 | * @brief Get function for sysfs attribute bootflag | 800 | * bootflag_get - Get function for sysfs attribute bootflag |
801 | * @dev: the &struct device | ||
802 | * @attr: device attributes | ||
803 | * @buf: buffer where data will be returned | ||
778 | */ | 804 | */ |
779 | static ssize_t bootflag_get(struct device *dev, | 805 | static ssize_t bootflag_get(struct device *dev, |
780 | struct device_attribute *attr, char *buf) | 806 | struct device_attribute *attr, char *buf) |
@@ -791,7 +817,11 @@ static ssize_t bootflag_get(struct device *dev, | |||
791 | } | 817 | } |
792 | 818 | ||
793 | /** | 819 | /** |
794 | * @brief Set function for sysfs attribute bootflag | 820 | * bootflag_set - Set function for sysfs attribute bootflag |
821 | * @dev: the &struct device | ||
822 | * @attr: device attributes | ||
823 | * @buf: buffer that contains new attribute value | ||
824 | * @count: size of buffer | ||
795 | */ | 825 | */ |
796 | static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr, | 826 | static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr, |
797 | const char *buf, size_t count) | 827 | const char *buf, size_t count) |
@@ -817,7 +847,10 @@ static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr, | |||
817 | } | 847 | } |
818 | 848 | ||
819 | /** | 849 | /** |
820 | * @brief Get function for sysfs attribute boottime | 850 | * boottime_get - Get function for sysfs attribute boottime |
851 | * @dev: the &struct device | ||
852 | * @attr: device attributes | ||
853 | * @buf: buffer where data will be returned | ||
821 | */ | 854 | */ |
822 | static ssize_t boottime_get(struct device *dev, | 855 | static ssize_t boottime_get(struct device *dev, |
823 | struct device_attribute *attr, char *buf) | 856 | struct device_attribute *attr, char *buf) |
@@ -834,7 +867,11 @@ static ssize_t boottime_get(struct device *dev, | |||
834 | } | 867 | } |
835 | 868 | ||
836 | /** | 869 | /** |
837 | * @brief Set function for sysfs attribute boottime | 870 | * boottime_set - Set function for sysfs attribute boottime |
871 | * @dev: the &struct device | ||
872 | * @attr: device attributes | ||
873 | * @buf: buffer that contains new attribute value | ||
874 | * @count: size of buffer | ||
838 | */ | 875 | */ |
839 | static ssize_t boottime_set(struct device *dev, | 876 | static ssize_t boottime_set(struct device *dev, |
840 | struct device_attribute *attr, const char *buf, size_t count) | 877 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -869,7 +906,10 @@ static ssize_t boottime_set(struct device *dev, | |||
869 | } | 906 | } |
870 | 907 | ||
871 | /** | 908 | /** |
872 | * @brief Get function for sysfs attribute channel | 909 | * channel_get - Get function for sysfs attribute channel |
910 | * @dev: the &struct device | ||
911 | * @attr: device attributes | ||
912 | * @buf: buffer where data will be returned | ||
873 | */ | 913 | */ |
874 | static ssize_t channel_get(struct device *dev, | 914 | static ssize_t channel_get(struct device *dev, |
875 | struct device_attribute *attr, char *buf) | 915 | struct device_attribute *attr, char *buf) |
@@ -886,7 +926,11 @@ static ssize_t channel_get(struct device *dev, | |||
886 | } | 926 | } |
887 | 927 | ||
888 | /** | 928 | /** |
889 | * @brief Set function for sysfs attribute channel | 929 | * channel_set - Set function for sysfs attribute channel |
930 | * @dev: the &struct device | ||
931 | * @attr: device attributes | ||
932 | * @buf: buffer that contains new attribute value | ||
933 | * @count: size of buffer | ||
890 | */ | 934 | */ |
891 | static ssize_t channel_set(struct device *dev, struct device_attribute *attr, | 935 | static ssize_t channel_set(struct device *dev, struct device_attribute *attr, |
892 | const char *buf, size_t count) | 936 | const char *buf, size_t count) |
@@ -912,7 +956,10 @@ static ssize_t channel_set(struct device *dev, struct device_attribute *attr, | |||
912 | } | 956 | } |
913 | 957 | ||
914 | /** | 958 | /** |
915 | * @brief Get function for sysfs attribute mesh_id | 959 | * mesh_id_get - Get function for sysfs attribute mesh_id |
960 | * @dev: the &struct device | ||
961 | * @attr: device attributes | ||
962 | * @buf: buffer where data will be returned | ||
916 | */ | 963 | */ |
917 | static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr, | 964 | static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr, |
918 | char *buf) | 965 | char *buf) |
@@ -938,7 +985,11 @@ static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr, | |||
938 | } | 985 | } |
939 | 986 | ||
940 | /** | 987 | /** |
941 | * @brief Set function for sysfs attribute mesh_id | 988 | * mesh_id_set - Set function for sysfs attribute mesh_id |
989 | * @dev: the &struct device | ||
990 | * @attr: device attributes | ||
991 | * @buf: buffer that contains new attribute value | ||
992 | * @count: size of buffer | ||
942 | */ | 993 | */ |
943 | static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr, | 994 | static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr, |
944 | const char *buf, size_t count) | 995 | const char *buf, size_t count) |
@@ -980,7 +1031,10 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr, | |||
980 | } | 1031 | } |
981 | 1032 | ||
982 | /** | 1033 | /** |
983 | * @brief Get function for sysfs attribute protocol_id | 1034 | * protocol_id_get - Get function for sysfs attribute protocol_id |
1035 | * @dev: the &struct device | ||
1036 | * @attr: device attributes | ||
1037 | * @buf: buffer where data will be returned | ||
984 | */ | 1038 | */ |
985 | static ssize_t protocol_id_get(struct device *dev, | 1039 | static ssize_t protocol_id_get(struct device *dev, |
986 | struct device_attribute *attr, char *buf) | 1040 | struct device_attribute *attr, char *buf) |
@@ -997,7 +1051,11 @@ static ssize_t protocol_id_get(struct device *dev, | |||
997 | } | 1051 | } |
998 | 1052 | ||
999 | /** | 1053 | /** |
1000 | * @brief Set function for sysfs attribute protocol_id | 1054 | * protocol_id_set - Set function for sysfs attribute protocol_id |
1055 | * @dev: the &struct device | ||
1056 | * @attr: device attributes | ||
1057 | * @buf: buffer that contains new attribute value | ||
1058 | * @count: size of buffer | ||
1001 | */ | 1059 | */ |
1002 | static ssize_t protocol_id_set(struct device *dev, | 1060 | static ssize_t protocol_id_set(struct device *dev, |
1003 | struct device_attribute *attr, const char *buf, size_t count) | 1061 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -1034,7 +1092,10 @@ static ssize_t protocol_id_set(struct device *dev, | |||
1034 | } | 1092 | } |
1035 | 1093 | ||
1036 | /** | 1094 | /** |
1037 | * @brief Get function for sysfs attribute metric_id | 1095 | * metric_id_get - Get function for sysfs attribute metric_id |
1096 | * @dev: the &struct device | ||
1097 | * @attr: device attributes | ||
1098 | * @buf: buffer where data will be returned | ||
1038 | */ | 1099 | */ |
1039 | static ssize_t metric_id_get(struct device *dev, | 1100 | static ssize_t metric_id_get(struct device *dev, |
1040 | struct device_attribute *attr, char *buf) | 1101 | struct device_attribute *attr, char *buf) |
@@ -1051,7 +1112,11 @@ static ssize_t metric_id_get(struct device *dev, | |||
1051 | } | 1112 | } |
1052 | 1113 | ||
1053 | /** | 1114 | /** |
1054 | * @brief Set function for sysfs attribute metric_id | 1115 | * metric_id_set - Set function for sysfs attribute metric_id |
1116 | * @dev: the &struct device | ||
1117 | * @attr: device attributes | ||
1118 | * @buf: buffer that contains new attribute value | ||
1119 | * @count: size of buffer | ||
1055 | */ | 1120 | */ |
1056 | static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr, | 1121 | static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr, |
1057 | const char *buf, size_t count) | 1122 | const char *buf, size_t count) |
@@ -1088,7 +1153,10 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr, | |||
1088 | } | 1153 | } |
1089 | 1154 | ||
1090 | /** | 1155 | /** |
1091 | * @brief Get function for sysfs attribute capability | 1156 | * capability_get - Get function for sysfs attribute capability |
1157 | * @dev: the &struct device | ||
1158 | * @attr: device attributes | ||
1159 | * @buf: buffer where data will be returned | ||
1092 | */ | 1160 | */ |
1093 | static ssize_t capability_get(struct device *dev, | 1161 | static ssize_t capability_get(struct device *dev, |
1094 | struct device_attribute *attr, char *buf) | 1162 | struct device_attribute *attr, char *buf) |
@@ -1105,7 +1173,11 @@ static ssize_t capability_get(struct device *dev, | |||
1105 | } | 1173 | } |
1106 | 1174 | ||
1107 | /** | 1175 | /** |
1108 | * @brief Set function for sysfs attribute capability | 1176 | * capability_set - Set function for sysfs attribute capability |
1177 | * @dev: the &struct device | ||
1178 | * @attr: device attributes | ||
1179 | * @buf: buffer that contains new attribute value | ||
1180 | * @count: size of buffer | ||
1109 | */ | 1181 | */ |
1110 | static ssize_t capability_set(struct device *dev, struct device_attribute *attr, | 1182 | static ssize_t capability_set(struct device *dev, struct device_attribute *attr, |
1111 | const char *buf, size_t count) | 1183 | const char *buf, size_t count) |
diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h index afb2e8dead3f..ee95c73ed5f4 100644 --- a/drivers/net/wireless/libertas/mesh.h +++ b/drivers/net/wireless/libertas/mesh.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /** | 1 | /* |
2 | * Contains all definitions needed for the Libertas' MESH implementation. | 2 | * Contains all definitions needed for the Libertas' MESH implementation. |
3 | */ | 3 | */ |
4 | #ifndef _LBS_MESH_H_ | 4 | #ifndef _LBS_MESH_H_ |
5 | #define _LBS_MESH_H_ | 5 | #define _LBS_MESH_H_ |
6 | 6 | ||
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index a2b1df21d286..a3f4b55aa41f 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /** | 1 | /* |
2 | * This file contains the handling of RX in wlan driver. | 2 | * This file contains the handling of RX in wlan driver. |
3 | */ | 3 | */ |
4 | #include <linux/etherdevice.h> | 4 | #include <linux/etherdevice.h> |
5 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
@@ -40,12 +40,12 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, | |||
40 | struct sk_buff *skb); | 40 | struct sk_buff *skb); |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * @brief This function processes received packet and forwards it | 43 | * lbs_process_rxed_packet - processes received packet and forwards it |
44 | * to kernel/upper layer | 44 | * to kernel/upper layer |
45 | * | 45 | * |
46 | * @param priv A pointer to struct lbs_private | 46 | * @priv: A pointer to &struct lbs_private |
47 | * @param skb A pointer to skb which includes the received packet | 47 | * @skb: A pointer to skb which includes the received packet |
48 | * @return 0 or -1 | 48 | * returns: 0 or -1 |
49 | */ | 49 | */ |
50 | int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | 50 | int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) |
51 | { | 51 | { |
@@ -156,11 +156,11 @@ done: | |||
156 | EXPORT_SYMBOL_GPL(lbs_process_rxed_packet); | 156 | EXPORT_SYMBOL_GPL(lbs_process_rxed_packet); |
157 | 157 | ||
158 | /** | 158 | /** |
159 | * @brief This function converts Tx/Rx rates from the Marvell WLAN format | 159 | * convert_mv_rate_to_radiotap - converts Tx/Rx rates from Marvell WLAN format |
160 | * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) | 160 | * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) |
161 | * | 161 | * |
162 | * @param rate Input rate | 162 | * @rate: Input rate |
163 | * @return Output Rate (0 if invalid) | 163 | * returns: Output Rate (0 if invalid) |
164 | */ | 164 | */ |
165 | static u8 convert_mv_rate_to_radiotap(u8 rate) | 165 | static u8 convert_mv_rate_to_radiotap(u8 rate) |
166 | { | 166 | { |
@@ -196,12 +196,12 @@ static u8 convert_mv_rate_to_radiotap(u8 rate) | |||
196 | } | 196 | } |
197 | 197 | ||
198 | /** | 198 | /** |
199 | * @brief This function processes a received 802.11 packet and forwards it | 199 | * process_rxed_802_11_packet - processes a received 802.11 packet and forwards |
200 | * to kernel/upper layer | 200 | * it to kernel/upper layer |
201 | * | 201 | * |
202 | * @param priv A pointer to struct lbs_private | 202 | * @priv: A pointer to &struct lbs_private |
203 | * @param skb A pointer to skb which includes the received packet | 203 | * @skb: A pointer to skb which includes the received packet |
204 | * @return 0 or -1 | 204 | * returns: 0 or -1 |
205 | */ | 205 | */ |
206 | static int process_rxed_802_11_packet(struct lbs_private *priv, | 206 | static int process_rxed_802_11_packet(struct lbs_private *priv, |
207 | struct sk_buff *skb) | 207 | struct sk_buff *skb) |
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index 8000ca6165d0..bbb95f88dc01 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /** | 1 | /* |
2 | * This file contains the handling of TX in wlan driver. | 2 | * This file contains the handling of TX in wlan driver. |
3 | */ | 3 | */ |
4 | #include <linux/netdevice.h> | 4 | #include <linux/netdevice.h> |
5 | #include <linux/etherdevice.h> | 5 | #include <linux/etherdevice.h> |
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
@@ -13,11 +13,11 @@ | |||
13 | #include "dev.h" | 13 | #include "dev.h" |
14 | 14 | ||
15 | /** | 15 | /** |
16 | * @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE | 16 | * convert_radiotap_rate_to_mv - converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE |
17 | * units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1) | 17 | * units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1) |
18 | * | 18 | * |
19 | * @param rate Input rate | 19 | * @rate: Input rate |
20 | * @return Output Rate (0 if invalid) | 20 | * returns: Output Rate (0 if invalid) |
21 | */ | 21 | */ |
22 | static u32 convert_radiotap_rate_to_mv(u8 rate) | 22 | static u32 convert_radiotap_rate_to_mv(u8 rate) |
23 | { | 23 | { |
@@ -51,12 +51,12 @@ static u32 convert_radiotap_rate_to_mv(u8 rate) | |||
51 | } | 51 | } |
52 | 52 | ||
53 | /** | 53 | /** |
54 | * @brief This function checks the conditions and sends packet to IF | 54 | * lbs_hard_start_xmit - checks the conditions and sends packet to IF |
55 | * layer if everything is ok. | 55 | * layer if everything is ok |
56 | * | 56 | * |
57 | * @param priv A pointer to struct lbs_private structure | 57 | * @skb: A pointer to skb which includes TX packet |
58 | * @param skb A pointer to skb which includes TX packet | 58 | * @dev: A pointer to the &struct net_device |
59 | * @return 0 or -1 | 59 | * returns: 0 or -1 |
60 | */ | 60 | */ |
61 | netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | 61 | netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) |
62 | { | 62 | { |
@@ -168,13 +168,13 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
168 | } | 168 | } |
169 | 169 | ||
170 | /** | 170 | /** |
171 | * @brief This function sends to the host the last transmitted packet, | 171 | * lbs_send_tx_feedback - sends to the host the last transmitted packet, |
172 | * filling the radiotap headers with transmission information. | 172 | * filling the radiotap headers with transmission information. |
173 | * | 173 | * |
174 | * @param priv A pointer to struct lbs_private structure | 174 | * @priv: A pointer to &struct lbs_private structure |
175 | * @param status A 32 bit value containing transmission status. | 175 | * @try_count: A 32-bit value containing transmission retry status. |
176 | * | 176 | * |
177 | * @returns void | 177 | * returns: void |
178 | */ | 178 | */ |
179 | void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count) | 179 | void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count) |
180 | { | 180 | { |
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h index 462fbb4cb743..cf1d9b047ee6 100644 --- a/drivers/net/wireless/libertas/types.h +++ b/drivers/net/wireless/libertas/types.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /** | 1 | /* |
2 | * This header file contains definition for global types | 2 | * This header file contains definition for global types |
3 | */ | 3 | */ |
4 | #ifndef _LBS_TYPES_H_ | 4 | #ifndef _LBS_TYPES_H_ |
5 | #define _LBS_TYPES_H_ | 5 | #define _LBS_TYPES_H_ |
6 | 6 | ||
@@ -54,7 +54,7 @@ union ieee_phy_param_set { | |||
54 | struct ieee_ie_ds_param_set ds; | 54 | struct ieee_ie_ds_param_set ds; |
55 | } __packed; | 55 | } __packed; |
56 | 56 | ||
57 | /** TLV type ID definition */ | 57 | /* TLV type ID definition */ |
58 | #define PROPRIETARY_TLV_BASE_ID 0x0100 | 58 | #define PROPRIETARY_TLV_BASE_ID 0x0100 |
59 | 59 | ||
60 | /* Terminating TLV type */ | 60 | /* Terminating TLV type */ |
@@ -96,7 +96,7 @@ union ieee_phy_param_set { | |||
96 | #define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37) | 96 | #define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37) |
97 | #define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291) | 97 | #define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291) |
98 | 98 | ||
99 | /** TLV related data structures*/ | 99 | /* TLV related data structures */ |
100 | struct mrvl_ie_header { | 100 | struct mrvl_ie_header { |
101 | __le16 type; | 101 | __le16 type; |
102 | __le16 len; | 102 | __le16 len; |
@@ -177,7 +177,7 @@ struct mrvl_ie_auth_type { | |||
177 | __le16 auth; | 177 | __le16 auth; |
178 | } __packed; | 178 | } __packed; |
179 | 179 | ||
180 | /** Local Power capability */ | 180 | /* Local Power capability */ |
181 | struct mrvl_ie_power_capability { | 181 | struct mrvl_ie_power_capability { |
182 | struct mrvl_ie_header header; | 182 | struct mrvl_ie_header header; |
183 | s8 minpower; | 183 | s8 minpower; |
@@ -235,9 +235,11 @@ struct mrvl_ie_ledbhv { | |||
235 | struct led_bhv ledbhv[1]; | 235 | struct led_bhv ledbhv[1]; |
236 | } __packed; | 236 | } __packed; |
237 | 237 | ||
238 | /* Meant to be packed as the value member of a struct ieee80211_info_element. | 238 | /* |
239 | * Meant to be packed as the value member of a struct ieee80211_info_element. | ||
239 | * Note that the len member of the ieee80211_info_element varies depending on | 240 | * Note that the len member of the ieee80211_info_element varies depending on |
240 | * the mesh_id_len */ | 241 | * the mesh_id_len |
242 | */ | ||
241 | struct mrvl_meshie_val { | 243 | struct mrvl_meshie_val { |
242 | uint8_t oui[3]; | 244 | uint8_t oui[3]; |
243 | uint8_t type; | 245 | uint8_t type; |
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index e22d761f2ef2..1d294cfa6c9b 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c | |||
@@ -29,95 +29,38 @@ | |||
29 | * Fills HT capability information field, AMPDU Parameters field, HT extended | 29 | * Fills HT capability information field, AMPDU Parameters field, HT extended |
30 | * capability field, and supported MCS set fields. | 30 | * capability field, and supported MCS set fields. |
31 | * | 31 | * |
32 | * Only the following HT capability information fields are used, all other | 32 | * HT capability information field, AMPDU Parameters field, supported MCS set |
33 | * fields are always turned off. | 33 | * fields are retrieved from cfg80211 stack |
34 | * | 34 | * |
35 | * Bit 1 : Supported channel width (0: 20MHz, 1: Both 20 and 40 MHz) | 35 | * RD responder bit to set to clear in the extended capability header. |
36 | * Bit 4 : Greenfield support (0: Not supported, 1: Supported) | ||
37 | * Bit 5 : Short GI for 20 MHz support (0: Not supported, 1: Supported) | ||
38 | * Bit 6 : Short GI for 40 MHz support (0: Not supported, 1: Supported) | ||
39 | * Bit 7 : Tx STBC (0: Not supported, 1: Supported) | ||
40 | * Bit 8-9 : Rx STBC (0: Not supported, X: Support for up to X spatial streams) | ||
41 | * Bit 10 : Delayed BA support (0: Not supported, 1: Supported) | ||
42 | * Bit 11 : Maximum AMSDU length (0: 3839 octets, 1: 7935 octets) | ||
43 | * Bit 14 : 40-Mhz intolerant support (0: Not supported, 1: Supported) | ||
44 | * | ||
45 | * In addition, the following AMPDU Parameters are set - | ||
46 | * - Maximum AMPDU length exponent (set to 3) | ||
47 | * - Minimum AMPDU start spacing (set to 0 - No restrictions) | ||
48 | * | ||
49 | * MCS is set for 1x1, with MSC32 for infra mode or ad-hoc mode with 40 MHz | ||
50 | * support. | ||
51 | * | ||
52 | * RD responder bit to set to clear in the extended capability header. | ||
53 | */ | 36 | */ |
54 | void | 37 | void |
55 | mwifiex_fill_cap_info(struct mwifiex_private *priv, | 38 | mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, |
56 | struct mwifiex_ie_types_htcap *ht_cap) | 39 | struct mwifiex_ie_types_htcap *ht_cap) |
57 | { | 40 | { |
58 | struct mwifiex_adapter *adapter = priv->adapter; | ||
59 | u8 *mcs; | ||
60 | int rx_mcs_supp; | ||
61 | uint16_t ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info); | ||
62 | uint16_t ht_ext_cap = le16_to_cpu(ht_cap->ht_cap.extended_ht_cap_info); | 41 | uint16_t ht_ext_cap = le16_to_cpu(ht_cap->ht_cap.extended_ht_cap_info); |
42 | struct ieee80211_supported_band *sband = | ||
43 | priv->wdev->wiphy->bands[radio_type]; | ||
63 | 44 | ||
64 | /* Convert dev_cap to IEEE80211_HT_CAP */ | 45 | ht_cap->ht_cap.ampdu_params_info = |
65 | if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) | 46 | (sband->ht_cap.ampdu_factor & |
66 | ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 47 | IEEE80211_HT_AMPDU_PARM_FACTOR)| |
67 | else | 48 | ((sband->ht_cap.ampdu_density << |
68 | ht_cap_info &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 49 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) & |
69 | 50 | IEEE80211_HT_AMPDU_PARM_DENSITY); | |
70 | if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap)) | ||
71 | ht_cap_info |= IEEE80211_HT_CAP_SGI_20; | ||
72 | else | ||
73 | ht_cap_info &= ~IEEE80211_HT_CAP_SGI_20; | ||
74 | |||
75 | if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap)) | ||
76 | ht_cap_info |= IEEE80211_HT_CAP_SGI_40; | ||
77 | else | ||
78 | ht_cap_info &= ~IEEE80211_HT_CAP_SGI_40; | ||
79 | |||
80 | if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap)) | ||
81 | ht_cap_info |= IEEE80211_HT_CAP_TX_STBC; | ||
82 | else | ||
83 | ht_cap_info &= ~IEEE80211_HT_CAP_TX_STBC; | ||
84 | |||
85 | if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap)) | ||
86 | ht_cap_info |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; | ||
87 | else | ||
88 | ht_cap_info &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT); | ||
89 | |||
90 | if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap)) | ||
91 | ht_cap_info |= IEEE80211_HT_CAP_GRN_FLD; | ||
92 | else | ||
93 | ht_cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; | ||
94 | |||
95 | ht_cap_info &= ~IEEE80211_HT_CAP_MAX_AMSDU; | ||
96 | ht_cap_info |= IEEE80211_HT_CAP_SM_PS; | ||
97 | 51 | ||
98 | ht_cap->ht_cap.ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_FACTOR; | 52 | memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs, |
99 | ht_cap->ht_cap.ampdu_params_info &= ~IEEE80211_HT_AMPDU_PARM_DENSITY; | 53 | sizeof(sband->ht_cap.mcs)); |
100 | |||
101 | rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support); | ||
102 | |||
103 | mcs = (u8 *)&ht_cap->ht_cap.mcs; | ||
104 | |||
105 | /* Set MCS for 1x1 */ | ||
106 | memset(mcs, 0xff, rx_mcs_supp); | ||
107 | |||
108 | /* Clear all the other values */ | ||
109 | memset(&mcs[rx_mcs_supp], 0, | ||
110 | sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); | ||
111 | 54 | ||
112 | if (priv->bss_mode == NL80211_IFTYPE_STATION || | 55 | if (priv->bss_mode == NL80211_IFTYPE_STATION || |
113 | (ht_cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | 56 | (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) |
114 | /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ | 57 | /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ |
115 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); | 58 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); |
116 | 59 | ||
117 | /* Clear RD responder bit */ | 60 | /* Clear RD responder bit */ |
118 | ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER; | 61 | ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER; |
119 | 62 | ||
120 | ht_cap->ht_cap.cap_info = cpu_to_le16(ht_cap_info); | 63 | ht_cap->ht_cap.cap_info = cpu_to_le16(sband->ht_cap.cap); |
121 | ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap); | 64 | ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap); |
122 | } | 65 | } |
123 | 66 | ||
@@ -391,10 +334,15 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
391 | struct mwifiex_ie_types_2040bssco *bss_co_2040; | 334 | struct mwifiex_ie_types_2040bssco *bss_co_2040; |
392 | struct mwifiex_ie_types_extcap *ext_cap; | 335 | struct mwifiex_ie_types_extcap *ext_cap; |
393 | int ret_len = 0; | 336 | int ret_len = 0; |
337 | struct ieee80211_supported_band *sband; | ||
338 | u8 radio_type; | ||
394 | 339 | ||
395 | if (!buffer || !*buffer) | 340 | if (!buffer || !*buffer) |
396 | return ret_len; | 341 | return ret_len; |
397 | 342 | ||
343 | radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); | ||
344 | sband = priv->wdev->wiphy->bands[radio_type]; | ||
345 | |||
398 | if (bss_desc->bcn_ht_cap) { | 346 | if (bss_desc->bcn_ht_cap) { |
399 | ht_cap = (struct mwifiex_ie_types_htcap *) *buffer; | 347 | ht_cap = (struct mwifiex_ie_types_htcap *) *buffer; |
400 | memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); | 348 | memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); |
@@ -406,7 +354,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
406 | sizeof(struct ieee_types_header), | 354 | sizeof(struct ieee_types_header), |
407 | le16_to_cpu(ht_cap->header.len)); | 355 | le16_to_cpu(ht_cap->header.len)); |
408 | 356 | ||
409 | mwifiex_fill_cap_info(priv, ht_cap); | 357 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); |
410 | 358 | ||
411 | *buffer += sizeof(struct mwifiex_ie_types_htcap); | 359 | *buffer += sizeof(struct mwifiex_ie_types_htcap); |
412 | ret_len += sizeof(struct mwifiex_ie_types_htcap); | 360 | ret_len += sizeof(struct mwifiex_ie_types_htcap); |
@@ -428,8 +376,8 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
428 | sizeof(struct ieee_types_header), | 376 | sizeof(struct ieee_types_header), |
429 | le16_to_cpu(ht_info->header.len)); | 377 | le16_to_cpu(ht_info->header.len)); |
430 | 378 | ||
431 | if (!ISSUPP_CHANWIDTH40 | 379 | if (!(sband->ht_cap.cap & |
432 | (priv->adapter->hw_dot_11n_dev_cap)) | 380 | IEEE80211_HT_CAP_SUP_WIDTH_20_40)) |
433 | ht_info->ht_info.ht_param &= | 381 | ht_info->ht_info.ht_param &= |
434 | ~(IEEE80211_HT_PARAM_CHAN_WIDTH_ANY | | 382 | ~(IEEE80211_HT_PARAM_CHAN_WIDTH_ANY | |
435 | IEEE80211_HT_PARAM_CHA_SEC_OFFSET); | 383 | IEEE80211_HT_PARAM_CHA_SEC_OFFSET); |
@@ -451,7 +399,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
451 | chan_list->chan_scan_param[0].radio_type = | 399 | chan_list->chan_scan_param[0].radio_type = |
452 | mwifiex_band_to_radio_type((u8) bss_desc->bss_band); | 400 | mwifiex_band_to_radio_type((u8) bss_desc->bss_band); |
453 | 401 | ||
454 | if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) | 402 | if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) |
455 | && (bss_desc->bcn_ht_info->ht_param & | 403 | && (bss_desc->bcn_ht_info->ht_param & |
456 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) | 404 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) |
457 | SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. | 405 | SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. |
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 02602ff30cbf..a4390a1a2a9f 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h | |||
@@ -38,7 +38,7 @@ int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
38 | u8 **buffer); | 38 | u8 **buffer); |
39 | void mwifiex_cfg_tx_buf(struct mwifiex_private *priv, | 39 | void mwifiex_cfg_tx_buf(struct mwifiex_private *priv, |
40 | struct mwifiex_bssdescriptor *bss_desc); | 40 | struct mwifiex_bssdescriptor *bss_desc); |
41 | void mwifiex_fill_cap_info(struct mwifiex_private *, | 41 | void mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type, |
42 | struct mwifiex_ie_types_htcap *); | 42 | struct mwifiex_ie_types_htcap *); |
43 | int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv, | 43 | int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv, |
44 | u16 action, int *htcap_cfg); | 44 | u16 action, int *htcap_cfg); |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index b99ae2677d78..98009e2194c5 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -1150,9 +1150,9 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1150 | * | 1150 | * |
1151 | * The following default values are set - | 1151 | * The following default values are set - |
1152 | * - HT Supported = True | 1152 | * - HT Supported = True |
1153 | * - Maximum AMPDU length factor = 0x3 | 1153 | * - Maximum AMPDU length factor = IEEE80211_HT_MAX_AMPDU_64K |
1154 | * - Minimum AMPDU spacing = 0x6 | 1154 | * - Minimum AMPDU spacing = IEEE80211_HT_MPDU_DENSITY_NONE |
1155 | * - HT Capabilities map = IEEE80211_HT_CAP_SUP_WIDTH_20_40 (0x0002) | 1155 | * - HT Capabilities supported by firmware |
1156 | * - MCS information, Rx mask = 0xff | 1156 | * - MCS information, Rx mask = 0xff |
1157 | * - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01) | 1157 | * - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01) |
1158 | */ | 1158 | */ |
@@ -1166,13 +1166,41 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, | |||
1166 | struct mwifiex_adapter *adapter = priv->adapter; | 1166 | struct mwifiex_adapter *adapter = priv->adapter; |
1167 | 1167 | ||
1168 | ht_info->ht_supported = true; | 1168 | ht_info->ht_supported = true; |
1169 | ht_info->ampdu_factor = 0x3; | 1169 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; |
1170 | ht_info->ampdu_density = 0x6; | 1170 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; |
1171 | 1171 | ||
1172 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | 1172 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); |
1173 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
1174 | 1173 | ||
1175 | rx_mcs_supp = GET_RXMCSSUPP(priv->adapter->hw_dev_mcs_support); | 1174 | /* Fill HT capability information */ |
1175 | if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) | ||
1176 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
1177 | else | ||
1178 | ht_info->cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
1179 | |||
1180 | if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap)) | ||
1181 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | ||
1182 | else | ||
1183 | ht_info->cap &= ~IEEE80211_HT_CAP_SGI_20; | ||
1184 | |||
1185 | if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap)) | ||
1186 | ht_info->cap |= IEEE80211_HT_CAP_SGI_40; | ||
1187 | else | ||
1188 | ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
1189 | |||
1190 | if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap)) | ||
1191 | ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; | ||
1192 | else | ||
1193 | ht_info->cap &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT); | ||
1194 | |||
1195 | if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap)) | ||
1196 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; | ||
1197 | else | ||
1198 | ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC; | ||
1199 | |||
1200 | ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; | ||
1201 | ht_info->cap |= IEEE80211_HT_CAP_SM_PS; | ||
1202 | |||
1203 | rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support); | ||
1176 | /* Set MCS for 1x1 */ | 1204 | /* Set MCS for 1x1 */ |
1177 | memset(mcs, 0xff, rx_mcs_supp); | 1205 | memset(mcs, 0xff, rx_mcs_supp); |
1178 | /* Clear all the other values */ | 1206 | /* Clear all the other values */ |
@@ -1235,20 +1263,23 @@ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac, | |||
1235 | wdev->wiphy->max_scan_ssids = 10; | 1263 | wdev->wiphy->max_scan_ssids = 10; |
1236 | wdev->wiphy->interface_modes = | 1264 | wdev->wiphy->interface_modes = |
1237 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); | 1265 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); |
1266 | |||
1238 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; | 1267 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; |
1239 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; | 1268 | mwifiex_setup_ht_caps( |
1269 | &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); | ||
1270 | |||
1271 | if (priv->adapter->config_bands & BAND_A) { | ||
1272 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; | ||
1273 | mwifiex_setup_ht_caps( | ||
1274 | &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); | ||
1275 | } else { | ||
1276 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; | ||
1277 | } | ||
1240 | 1278 | ||
1241 | /* Initialize cipher suits */ | 1279 | /* Initialize cipher suits */ |
1242 | wdev->wiphy->cipher_suites = mwifiex_cipher_suites; | 1280 | wdev->wiphy->cipher_suites = mwifiex_cipher_suites; |
1243 | wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); | 1281 | wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); |
1244 | 1282 | ||
1245 | /* Initialize parameters for 2GHz band */ | ||
1246 | |||
1247 | mwifiex_setup_ht_caps(&wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, | ||
1248 | priv); | ||
1249 | mwifiex_setup_ht_caps(&wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, | ||
1250 | priv); | ||
1251 | |||
1252 | memcpy(wdev->wiphy->perm_addr, mac, 6); | 1283 | memcpy(wdev->wiphy->perm_addr, mac, 6); |
1253 | wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 1284 | wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
1254 | 1285 | ||
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 23d2d0b9a527..85fca5eb4195 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -100,7 +100,7 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer, | |||
100 | struct mwifiex_bssdescriptor *bss_desc) | 100 | struct mwifiex_bssdescriptor *bss_desc) |
101 | { | 101 | { |
102 | struct mwifiex_ie_types_tsf_timestamp tsf_tlv; | 102 | struct mwifiex_ie_types_tsf_timestamp tsf_tlv; |
103 | long long tsf_val; | 103 | __le64 tsf_val; |
104 | 104 | ||
105 | /* Null Checks */ | 105 | /* Null Checks */ |
106 | if (buffer == NULL) | 106 | if (buffer == NULL) |
@@ -116,6 +116,8 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer, | |||
116 | memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header)); | 116 | memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header)); |
117 | *buffer += sizeof(tsf_tlv.header); | 117 | *buffer += sizeof(tsf_tlv.header); |
118 | 118 | ||
119 | /* TSF at the time when beacon/probe_response was received */ | ||
120 | tsf_val = cpu_to_le64(bss_desc->network_tsf); | ||
119 | memcpy(*buffer, &tsf_val, sizeof(tsf_val)); | 121 | memcpy(*buffer, &tsf_val, sizeof(tsf_val)); |
120 | *buffer += sizeof(tsf_val); | 122 | *buffer += sizeof(tsf_val); |
121 | 123 | ||
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 1b503038270e..5043fcd22565 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -280,7 +280,7 @@ struct mwifiex_bssdescriptor { | |||
280 | * BAND_A(0X04): 'a' band | 280 | * BAND_A(0X04): 'a' band |
281 | */ | 281 | */ |
282 | u16 bss_band; | 282 | u16 bss_band; |
283 | long long network_tsf; | 283 | u64 network_tsf; |
284 | u8 time_stamp[8]; | 284 | u8 time_stamp[8]; |
285 | union ieee_types_phy_param_set phy_param_set; | 285 | union ieee_types_phy_param_set phy_param_set; |
286 | union ieee_types_ss_param_set ss_param_set; | 286 | union ieee_types_ss_param_set ss_param_set; |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 68d905d58606..31a529578805 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -1007,7 +1007,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
1007 | ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); | 1007 | ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); |
1008 | ht_cap->header.len = | 1008 | ht_cap->header.len = |
1009 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); | 1009 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); |
1010 | mwifiex_fill_cap_info(priv, ht_cap); | 1010 | radio_type = |
1011 | mwifiex_band_to_radio_type(priv->adapter->config_bands); | ||
1012 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); | ||
1011 | tlv_pos += sizeof(struct mwifiex_ie_types_htcap); | 1013 | tlv_pos += sizeof(struct mwifiex_ie_types_htcap); |
1012 | } | 1014 | } |
1013 | 1015 | ||
@@ -2988,32 +2990,28 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) | |||
2988 | struct mwifiex_bssdescriptor *curr_bss = | 2990 | struct mwifiex_bssdescriptor *curr_bss = |
2989 | &priv->curr_bss_params.bss_descriptor; | 2991 | &priv->curr_bss_params.bss_descriptor; |
2990 | 2992 | ||
2991 | /* save the beacon buffer if it is not saved or updated */ | 2993 | if (!curr_bss->beacon_buf_size) |
2992 | if ((priv->curr_bcn_buf == NULL) || | 2994 | return; |
2993 | (priv->curr_bcn_size != curr_bss->beacon_buf_size) || | ||
2994 | (memcmp(priv->curr_bcn_buf, curr_bss->beacon_buf, | ||
2995 | curr_bss->beacon_buf_size))) { | ||
2996 | |||
2997 | kfree(priv->curr_bcn_buf); | ||
2998 | priv->curr_bcn_buf = NULL; | ||
2999 | 2995 | ||
2996 | /* allocate beacon buffer at 1st time; or if it's size has changed */ | ||
2997 | if (!priv->curr_bcn_buf || | ||
2998 | priv->curr_bcn_size != curr_bss->beacon_buf_size) { | ||
3000 | priv->curr_bcn_size = curr_bss->beacon_buf_size; | 2999 | priv->curr_bcn_size = curr_bss->beacon_buf_size; |
3001 | if (!priv->curr_bcn_size) | ||
3002 | return; | ||
3003 | 3000 | ||
3001 | kfree(priv->curr_bcn_buf); | ||
3004 | priv->curr_bcn_buf = kzalloc(curr_bss->beacon_buf_size, | 3002 | priv->curr_bcn_buf = kzalloc(curr_bss->beacon_buf_size, |
3005 | GFP_KERNEL); | 3003 | GFP_KERNEL); |
3006 | if (!priv->curr_bcn_buf) { | 3004 | if (!priv->curr_bcn_buf) { |
3007 | dev_err(priv->adapter->dev, | 3005 | dev_err(priv->adapter->dev, |
3008 | "failed to alloc curr_bcn_buf\n"); | 3006 | "failed to alloc curr_bcn_buf\n"); |
3009 | } else { | 3007 | return; |
3010 | memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, | ||
3011 | curr_bss->beacon_buf_size); | ||
3012 | dev_dbg(priv->adapter->dev, | ||
3013 | "info: current beacon saved %d\n", | ||
3014 | priv->curr_bcn_size); | ||
3015 | } | 3008 | } |
3016 | } | 3009 | } |
3010 | |||
3011 | memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, | ||
3012 | curr_bss->beacon_buf_size); | ||
3013 | dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", | ||
3014 | priv->curr_bcn_size); | ||
3017 | } | 3015 | } |
3018 | 3016 | ||
3019 | /* | 3017 | /* |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 28ebaec80be6..9f5ecef297e5 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -74,6 +74,14 @@ MODULE_PARM_DESC(ap_mode_default, | |||
74 | #define MWL8K_A2H_INT_RX_READY (1 << 1) | 74 | #define MWL8K_A2H_INT_RX_READY (1 << 1) |
75 | #define MWL8K_A2H_INT_TX_DONE (1 << 0) | 75 | #define MWL8K_A2H_INT_TX_DONE (1 << 0) |
76 | 76 | ||
77 | /* HW micro second timer register | ||
78 | * located at offset 0xA600. This | ||
79 | * will be used to timestamp tx | ||
80 | * packets. | ||
81 | */ | ||
82 | |||
83 | #define MWL8K_HW_TIMER_REGISTER 0x0000a600 | ||
84 | |||
77 | #define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \ | 85 | #define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \ |
78 | MWL8K_A2H_INT_CHNL_SWITCHED | \ | 86 | MWL8K_A2H_INT_CHNL_SWITCHED | \ |
79 | MWL8K_A2H_INT_QUEUE_EMPTY | \ | 87 | MWL8K_A2H_INT_QUEUE_EMPTY | \ |
@@ -773,8 +781,10 @@ static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos) | |||
773 | skb_pull(skb, sizeof(*tr) - hdrlen); | 781 | skb_pull(skb, sizeof(*tr) - hdrlen); |
774 | } | 782 | } |
775 | 783 | ||
784 | #define REDUCED_TX_HEADROOM 8 | ||
785 | |||
776 | static void | 786 | static void |
777 | mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad) | 787 | mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb, int tail_pad) |
778 | { | 788 | { |
779 | struct ieee80211_hdr *wh; | 789 | struct ieee80211_hdr *wh; |
780 | int hdrlen; | 790 | int hdrlen; |
@@ -790,6 +800,22 @@ mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad) | |||
790 | wh = (struct ieee80211_hdr *)skb->data; | 800 | wh = (struct ieee80211_hdr *)skb->data; |
791 | 801 | ||
792 | hdrlen = ieee80211_hdrlen(wh->frame_control); | 802 | hdrlen = ieee80211_hdrlen(wh->frame_control); |
803 | |||
804 | /* | ||
805 | * Check if skb_resize is required because of | ||
806 | * tx_headroom adjustment. | ||
807 | */ | ||
808 | if (priv->ap_fw && (hdrlen < (sizeof(struct ieee80211_cts) | ||
809 | + REDUCED_TX_HEADROOM))) { | ||
810 | if (pskb_expand_head(skb, REDUCED_TX_HEADROOM, 0, GFP_ATOMIC)) { | ||
811 | |||
812 | wiphy_err(priv->hw->wiphy, | ||
813 | "Failed to reallocate TX buffer\n"); | ||
814 | return; | ||
815 | } | ||
816 | skb->truesize += REDUCED_TX_HEADROOM; | ||
817 | } | ||
818 | |||
793 | reqd_hdrlen = sizeof(*tr); | 819 | reqd_hdrlen = sizeof(*tr); |
794 | 820 | ||
795 | if (hdrlen != reqd_hdrlen) | 821 | if (hdrlen != reqd_hdrlen) |
@@ -812,7 +838,8 @@ mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad) | |||
812 | tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad); | 838 | tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad); |
813 | } | 839 | } |
814 | 840 | ||
815 | static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb) | 841 | static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv, |
842 | struct sk_buff *skb) | ||
816 | { | 843 | { |
817 | struct ieee80211_hdr *wh; | 844 | struct ieee80211_hdr *wh; |
818 | struct ieee80211_tx_info *tx_info; | 845 | struct ieee80211_tx_info *tx_info; |
@@ -853,7 +880,7 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb) | |||
853 | break; | 880 | break; |
854 | } | 881 | } |
855 | } | 882 | } |
856 | mwl8k_add_dma_header(skb, data_pad); | 883 | mwl8k_add_dma_header(priv, skb, data_pad); |
857 | } | 884 | } |
858 | 885 | ||
859 | /* | 886 | /* |
@@ -1554,24 +1581,11 @@ static int mwl8k_tid_queue_mapping(u8 tid) | |||
1554 | 1581 | ||
1555 | /* The firmware will fill in the rate information | 1582 | /* The firmware will fill in the rate information |
1556 | * for each packet that gets queued in the hardware | 1583 | * for each packet that gets queued in the hardware |
1557 | * in this structure | 1584 | * and these macros will interpret that info. |
1558 | */ | 1585 | */ |
1559 | 1586 | ||
1560 | struct rateinfo { | 1587 | #define RI_FORMAT(a) (a & 0x0001) |
1561 | __le16 format:1; | 1588 | #define RI_RATE_ID_MCS(a) ((a & 0x01f8) >> 3) |
1562 | __le16 short_gi:1; | ||
1563 | __le16 band_width:1; | ||
1564 | __le16 rate_id_mcs:6; | ||
1565 | __le16 adv_coding:2; | ||
1566 | __le16 antenna:2; | ||
1567 | __le16 act_sub_chan:2; | ||
1568 | __le16 preamble_type:1; | ||
1569 | __le16 power_id:4; | ||
1570 | __le16 antenna2:1; | ||
1571 | __le16 reserved:1; | ||
1572 | __le16 tx_bf_frame:1; | ||
1573 | __le16 green_field:1; | ||
1574 | } __packed; | ||
1575 | 1589 | ||
1576 | static int | 1590 | static int |
1577 | mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) | 1591 | mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) |
@@ -1592,7 +1606,6 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) | |||
1592 | struct ieee80211_sta *sta; | 1606 | struct ieee80211_sta *sta; |
1593 | struct mwl8k_sta *sta_info = NULL; | 1607 | struct mwl8k_sta *sta_info = NULL; |
1594 | u16 rate_info; | 1608 | u16 rate_info; |
1595 | struct rateinfo *rate; | ||
1596 | struct ieee80211_hdr *wh; | 1609 | struct ieee80211_hdr *wh; |
1597 | 1610 | ||
1598 | tx = txq->head; | 1611 | tx = txq->head; |
@@ -1635,14 +1648,13 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) | |||
1635 | sta_info = MWL8K_STA(sta); | 1648 | sta_info = MWL8K_STA(sta); |
1636 | BUG_ON(sta_info == NULL); | 1649 | BUG_ON(sta_info == NULL); |
1637 | rate_info = le16_to_cpu(tx_desc->rate_info); | 1650 | rate_info = le16_to_cpu(tx_desc->rate_info); |
1638 | rate = (struct rateinfo *)&rate_info; | ||
1639 | /* If rate is < 6.5 Mpbs for an ht station | 1651 | /* If rate is < 6.5 Mpbs for an ht station |
1640 | * do not form an ampdu. If the station is a | 1652 | * do not form an ampdu. If the station is a |
1641 | * legacy station (format = 0), do not form an | 1653 | * legacy station (format = 0), do not form an |
1642 | * ampdu | 1654 | * ampdu |
1643 | */ | 1655 | */ |
1644 | if (rate->rate_id_mcs < 1 || | 1656 | if (RI_RATE_ID_MCS(rate_info) < 1 || |
1645 | rate->format == 0) { | 1657 | RI_FORMAT(rate_info) == 0) { |
1646 | sta_info->is_ampdu_allowed = false; | 1658 | sta_info->is_ampdu_allowed = false; |
1647 | } else { | 1659 | } else { |
1648 | sta_info->is_ampdu_allowed = true; | 1660 | sta_info->is_ampdu_allowed = true; |
@@ -1666,10 +1678,6 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) | |||
1666 | processed++; | 1678 | processed++; |
1667 | } | 1679 | } |
1668 | 1680 | ||
1669 | if (index < MWL8K_TX_WMM_QUEUES && processed && priv->radio_on && | ||
1670 | !mutex_is_locked(&priv->fw_mutex)) | ||
1671 | ieee80211_wake_queue(hw, index); | ||
1672 | |||
1673 | return processed; | 1681 | return processed; |
1674 | } | 1682 | } |
1675 | 1683 | ||
@@ -1814,6 +1822,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
1814 | u8 tid = 0; | 1822 | u8 tid = 0; |
1815 | struct mwl8k_ampdu_stream *stream = NULL; | 1823 | struct mwl8k_ampdu_stream *stream = NULL; |
1816 | bool start_ba_session = false; | 1824 | bool start_ba_session = false; |
1825 | bool mgmtframe = false; | ||
1817 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; | 1826 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; |
1818 | 1827 | ||
1819 | wh = (struct ieee80211_hdr *)skb->data; | 1828 | wh = (struct ieee80211_hdr *)skb->data; |
@@ -1822,10 +1831,13 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
1822 | else | 1831 | else |
1823 | qos = 0; | 1832 | qos = 0; |
1824 | 1833 | ||
1834 | if (ieee80211_is_mgmt(wh->frame_control)) | ||
1835 | mgmtframe = true; | ||
1836 | |||
1825 | if (priv->ap_fw) | 1837 | if (priv->ap_fw) |
1826 | mwl8k_encapsulate_tx_frame(skb); | 1838 | mwl8k_encapsulate_tx_frame(priv, skb); |
1827 | else | 1839 | else |
1828 | mwl8k_add_dma_header(skb, 0); | 1840 | mwl8k_add_dma_header(priv, skb, 0); |
1829 | 1841 | ||
1830 | wh = &((struct mwl8k_dma_data *)skb->data)->wh; | 1842 | wh = &((struct mwl8k_dma_data *)skb->data)->wh; |
1831 | 1843 | ||
@@ -1951,14 +1963,26 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
1951 | 1963 | ||
1952 | txq = priv->txq + index; | 1964 | txq = priv->txq + index; |
1953 | 1965 | ||
1954 | if (index >= MWL8K_TX_WMM_QUEUES && txq->len >= MWL8K_TX_DESCS) { | 1966 | /* Mgmt frames that go out frequently are probe |
1955 | /* This is the case in which the tx packet is destined for an | 1967 | * responses. Other mgmt frames got out relatively |
1956 | * AMPDU queue and that AMPDU queue is full. Because we don't | 1968 | * infrequently. Hence reserve 2 buffers so that |
1957 | * start and stop the AMPDU queues, we must drop these packets. | 1969 | * other mgmt frames do not get dropped due to an |
1958 | */ | 1970 | * already queued probe response in one of the |
1959 | dev_kfree_skb(skb); | 1971 | * reserved buffers. |
1960 | spin_unlock_bh(&priv->tx_lock); | 1972 | */ |
1961 | return; | 1973 | |
1974 | if (txq->len >= MWL8K_TX_DESCS - 2) { | ||
1975 | if (mgmtframe == false || | ||
1976 | txq->len == MWL8K_TX_DESCS) { | ||
1977 | if (start_ba_session) { | ||
1978 | spin_lock(&priv->stream_lock); | ||
1979 | mwl8k_remove_stream(hw, stream); | ||
1980 | spin_unlock(&priv->stream_lock); | ||
1981 | } | ||
1982 | spin_unlock_bh(&priv->tx_lock); | ||
1983 | dev_kfree_skb(skb); | ||
1984 | return; | ||
1985 | } | ||
1962 | } | 1986 | } |
1963 | 1987 | ||
1964 | BUG_ON(txq->skb[txq->tail] != NULL); | 1988 | BUG_ON(txq->skb[txq->tail] != NULL); |
@@ -1975,6 +1999,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
1975 | tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id; | 1999 | tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id; |
1976 | else | 2000 | else |
1977 | tx->peer_id = 0; | 2001 | tx->peer_id = 0; |
2002 | |||
2003 | if (priv->ap_fw) | ||
2004 | tx->timestamp = cpu_to_le32(ioread32(priv->regs + | ||
2005 | MWL8K_HW_TIMER_REGISTER)); | ||
2006 | |||
1978 | wmb(); | 2007 | wmb(); |
1979 | tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); | 2008 | tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); |
1980 | 2009 | ||
@@ -1985,9 +2014,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) | |||
1985 | if (txq->tail == MWL8K_TX_DESCS) | 2014 | if (txq->tail == MWL8K_TX_DESCS) |
1986 | txq->tail = 0; | 2015 | txq->tail = 0; |
1987 | 2016 | ||
1988 | if (txq->head == txq->tail && index < MWL8K_TX_WMM_QUEUES) | ||
1989 | ieee80211_stop_queue(hw, index); | ||
1990 | |||
1991 | mwl8k_tx_start(priv); | 2017 | mwl8k_tx_start(priv); |
1992 | 2018 | ||
1993 | spin_unlock_bh(&priv->tx_lock); | 2019 | spin_unlock_bh(&priv->tx_lock); |
@@ -2482,7 +2508,8 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw) | |||
2482 | 2508 | ||
2483 | cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | | 2509 | cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | |
2484 | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP | | 2510 | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP | |
2485 | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON); | 2511 | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON | |
2512 | MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY); | ||
2486 | cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); | 2513 | cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); |
2487 | cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); | 2514 | cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); |
2488 | 2515 | ||
@@ -5466,6 +5493,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) | |||
5466 | hw->extra_tx_headroom = | 5493 | hw->extra_tx_headroom = |
5467 | sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); | 5494 | sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); |
5468 | 5495 | ||
5496 | hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0; | ||
5497 | |||
5469 | hw->channel_change_time = 10; | 5498 | hw->channel_change_time = 10; |
5470 | 5499 | ||
5471 | hw->queues = MWL8K_TX_WMM_QUEUES; | 5500 | hw->queues = MWL8K_TX_WMM_QUEUES; |
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 13d750da9301..54cc0bba66b9 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c | |||
@@ -491,7 +491,7 @@ static int p54_parse_rssical(struct ieee80211_hw *dev, | |||
491 | struct pda_rssi_cal_entry *cal = (void *) &data[offset]; | 491 | struct pda_rssi_cal_entry *cal = (void *) &data[offset]; |
492 | 492 | ||
493 | for (i = 0; i < entries; i++) { | 493 | for (i = 0; i < entries; i++) { |
494 | u16 freq; | 494 | u16 freq = 0; |
495 | switch (i) { | 495 | switch (i) { |
496 | case IEEE80211_BAND_2GHZ: | 496 | case IEEE80211_BAND_2GHZ: |
497 | freq = 2437; | 497 | freq = 2437; |
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 2fab7d20ffc2..b6a061cbbdec 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c | |||
@@ -727,3 +727,34 @@ int p54_fetch_statistics(struct p54_common *priv) | |||
727 | p54_tx(priv, skb); | 727 | p54_tx(priv, skb); |
728 | return 0; | 728 | return 0; |
729 | } | 729 | } |
730 | |||
731 | int p54_set_groupfilter(struct p54_common *priv) | ||
732 | { | ||
733 | struct p54_group_address_table *grp; | ||
734 | struct sk_buff *skb; | ||
735 | bool on = false; | ||
736 | |||
737 | skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*grp), | ||
738 | P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE, GFP_KERNEL); | ||
739 | if (!skb) | ||
740 | return -ENOMEM; | ||
741 | |||
742 | grp = (struct p54_group_address_table *)skb_put(skb, sizeof(*grp)); | ||
743 | |||
744 | on = !(priv->filter_flags & FIF_ALLMULTI) && | ||
745 | (priv->mc_maclist_num > 0 && | ||
746 | priv->mc_maclist_num <= MC_FILTER_ADDRESS_NUM); | ||
747 | |||
748 | if (on) { | ||
749 | grp->filter_enable = cpu_to_le16(1); | ||
750 | grp->num_address = cpu_to_le16(priv->mc_maclist_num); | ||
751 | memcpy(grp->mac_list, priv->mc_maclist, sizeof(grp->mac_list)); | ||
752 | } else { | ||
753 | grp->filter_enable = cpu_to_le16(0); | ||
754 | grp->num_address = cpu_to_le16(0); | ||
755 | memset(grp->mac_list, 0, sizeof(grp->mac_list)); | ||
756 | } | ||
757 | |||
758 | p54_tx(priv, skb); | ||
759 | return 0; | ||
760 | } | ||
diff --git a/drivers/net/wireless/p54/lmac.h b/drivers/net/wireless/p54/lmac.h index eb581abc1079..3d8d622bec55 100644 --- a/drivers/net/wireless/p54/lmac.h +++ b/drivers/net/wireless/p54/lmac.h | |||
@@ -540,6 +540,7 @@ int p54_update_beacon_tim(struct p54_common *priv, u16 aid, bool set); | |||
540 | int p54_setup_mac(struct p54_common *priv); | 540 | int p54_setup_mac(struct p54_common *priv); |
541 | int p54_set_ps(struct p54_common *priv); | 541 | int p54_set_ps(struct p54_common *priv); |
542 | int p54_fetch_statistics(struct p54_common *priv); | 542 | int p54_fetch_statistics(struct p54_common *priv); |
543 | int p54_set_groupfilter(struct p54_common *priv); | ||
543 | 544 | ||
544 | /* e/v DCF setup */ | 545 | /* e/v DCF setup */ |
545 | int p54_set_edcf(struct p54_common *priv); | 546 | int p54_set_edcf(struct p54_common *priv); |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index a946991989c6..a5a6d9e647bb 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -308,6 +308,31 @@ out: | |||
308 | return ret; | 308 | return ret; |
309 | } | 309 | } |
310 | 310 | ||
311 | static u64 p54_prepare_multicast(struct ieee80211_hw *dev, | ||
312 | struct netdev_hw_addr_list *mc_list) | ||
313 | { | ||
314 | struct p54_common *priv = dev->priv; | ||
315 | struct netdev_hw_addr *ha; | ||
316 | int i; | ||
317 | |||
318 | BUILD_BUG_ON(ARRAY_SIZE(priv->mc_maclist) != | ||
319 | ARRAY_SIZE(((struct p54_group_address_table *)NULL)->mac_list)); | ||
320 | /* | ||
321 | * The first entry is reserved for the global broadcast MAC. | ||
322 | * Otherwise the firmware will drop it and ARP will no longer work. | ||
323 | */ | ||
324 | i = 1; | ||
325 | priv->mc_maclist_num = netdev_hw_addr_list_count(mc_list) + i; | ||
326 | netdev_hw_addr_list_for_each(ha, mc_list) { | ||
327 | memcpy(&priv->mc_maclist[i], ha->addr, ETH_ALEN); | ||
328 | i++; | ||
329 | if (i >= ARRAY_SIZE(priv->mc_maclist)) | ||
330 | break; | ||
331 | } | ||
332 | |||
333 | return 1; /* update */ | ||
334 | } | ||
335 | |||
311 | static void p54_configure_filter(struct ieee80211_hw *dev, | 336 | static void p54_configure_filter(struct ieee80211_hw *dev, |
312 | unsigned int changed_flags, | 337 | unsigned int changed_flags, |
313 | unsigned int *total_flags, | 338 | unsigned int *total_flags, |
@@ -316,12 +341,16 @@ static void p54_configure_filter(struct ieee80211_hw *dev, | |||
316 | struct p54_common *priv = dev->priv; | 341 | struct p54_common *priv = dev->priv; |
317 | 342 | ||
318 | *total_flags &= FIF_PROMISC_IN_BSS | | 343 | *total_flags &= FIF_PROMISC_IN_BSS | |
344 | FIF_ALLMULTI | | ||
319 | FIF_OTHER_BSS; | 345 | FIF_OTHER_BSS; |
320 | 346 | ||
321 | priv->filter_flags = *total_flags; | 347 | priv->filter_flags = *total_flags; |
322 | 348 | ||
323 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) | 349 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) |
324 | p54_setup_mac(priv); | 350 | p54_setup_mac(priv); |
351 | |||
352 | if (changed_flags & FIF_ALLMULTI || multicast) | ||
353 | p54_set_groupfilter(priv); | ||
325 | } | 354 | } |
326 | 355 | ||
327 | static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue, | 356 | static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue, |
@@ -591,6 +620,7 @@ static const struct ieee80211_ops p54_ops = { | |||
591 | .config = p54_config, | 620 | .config = p54_config, |
592 | .flush = p54_flush, | 621 | .flush = p54_flush, |
593 | .bss_info_changed = p54_bss_info_changed, | 622 | .bss_info_changed = p54_bss_info_changed, |
623 | .prepare_multicast = p54_prepare_multicast, | ||
594 | .configure_filter = p54_configure_filter, | 624 | .configure_filter = p54_configure_filter, |
595 | .conf_tx = p54_conf_tx, | 625 | .conf_tx = p54_conf_tx, |
596 | .get_stats = p54_get_stats, | 626 | .get_stats = p54_get_stats, |
@@ -660,6 +690,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
660 | init_completion(&priv->beacon_comp); | 690 | init_completion(&priv->beacon_comp); |
661 | INIT_DELAYED_WORK(&priv->work, p54_work); | 691 | INIT_DELAYED_WORK(&priv->work, p54_work); |
662 | 692 | ||
693 | memset(&priv->mc_maclist[0], ~0, ETH_ALEN); | ||
663 | return dev; | 694 | return dev; |
664 | } | 695 | } |
665 | EXPORT_SYMBOL_GPL(p54_init_common); | 696 | EXPORT_SYMBOL_GPL(p54_init_common); |
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 50730fc23fe5..799d05e12595 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h | |||
@@ -211,8 +211,10 @@ struct p54_common { | |||
211 | /* BBP/MAC state */ | 211 | /* BBP/MAC state */ |
212 | u8 mac_addr[ETH_ALEN]; | 212 | u8 mac_addr[ETH_ALEN]; |
213 | u8 bssid[ETH_ALEN]; | 213 | u8 bssid[ETH_ALEN]; |
214 | u8 mc_maclist[4][ETH_ALEN]; | ||
214 | u16 wakeup_timer; | 215 | u16 wakeup_timer; |
215 | unsigned int filter_flags; | 216 | unsigned int filter_flags; |
217 | int mc_maclist_num; | ||
216 | int mode; | 218 | int mode; |
217 | u32 tsf_low32, tsf_high32; | 219 | u32 tsf_low32, tsf_high32; |
218 | u32 basic_rate_mask; | 220 | u32 basic_rate_mask; |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index b21f81231a09..15237c275486 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1797,6 +1797,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1797 | __set_bit(REQUIRE_COPY_IV, &rt2x00dev->cap_flags); | 1797 | __set_bit(REQUIRE_COPY_IV, &rt2x00dev->cap_flags); |
1798 | } | 1798 | } |
1799 | __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags); | 1799 | __set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags); |
1800 | __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags); | ||
1800 | 1801 | ||
1801 | /* | 1802 | /* |
1802 | * Set the rssi offset. | 1803 | * Set the rssi offset. |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 5cd096e2ae36..790afd3ed946 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1640,7 +1640,6 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, | |||
1640 | struct channel_info *info) | 1640 | struct channel_info *info) |
1641 | { | 1641 | { |
1642 | u8 rfcsr; | 1642 | u8 rfcsr; |
1643 | u16 eeprom; | ||
1644 | 1643 | ||
1645 | rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); | 1644 | rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); |
1646 | rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); | 1645 | rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); |
@@ -1670,11 +1669,10 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, | |||
1670 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); | 1669 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); |
1671 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | 1670 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); |
1672 | 1671 | ||
1673 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
1674 | if (rf->channel <= 14) { | 1672 | if (rf->channel <= 14) { |
1675 | int idx = rf->channel-1; | 1673 | int idx = rf->channel-1; |
1676 | 1674 | ||
1677 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { | 1675 | if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { |
1678 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { | 1676 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { |
1679 | /* r55/r59 value array of channel 1~14 */ | 1677 | /* r55/r59 value array of channel 1~14 */ |
1680 | static const char r55_bt_rev[] = {0x83, 0x83, | 1678 | static const char r55_bt_rev[] = {0x83, 0x83, |
@@ -2917,8 +2915,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2917 | ant = (div_mode == 3) ? 1 : 0; | 2915 | ant = (div_mode == 3) ? 1 : 0; |
2918 | 2916 | ||
2919 | /* check if this is a Bluetooth combo card */ | 2917 | /* check if this is a Bluetooth combo card */ |
2920 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | 2918 | if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { |
2921 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { | ||
2922 | u32 reg; | 2919 | u32 reg; |
2923 | 2920 | ||
2924 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | 2921 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); |
@@ -3727,16 +3724,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3727 | } | 3724 | } |
3728 | 3725 | ||
3729 | /* | 3726 | /* |
3730 | * Read frequency offset and RF programming sequence. | 3727 | * Determine external LNA informations. |
3731 | */ | ||
3732 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
3733 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | ||
3734 | |||
3735 | /* | ||
3736 | * Read external LNA informations. | ||
3737 | */ | 3728 | */ |
3738 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
3739 | |||
3740 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G)) | 3729 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G)) |
3741 | __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); | 3730 | __set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); |
3742 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G)) | 3731 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G)) |
@@ -3749,6 +3738,18 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3749 | __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); | 3738 | __set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags); |
3750 | 3739 | ||
3751 | /* | 3740 | /* |
3741 | * Detect if this device has Bluetooth co-existence. | ||
3742 | */ | ||
3743 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) | ||
3744 | __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags); | ||
3745 | |||
3746 | /* | ||
3747 | * Read frequency offset and RF programming sequence. | ||
3748 | */ | ||
3749 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
3750 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | ||
3751 | |||
3752 | /* | ||
3752 | * Store led settings, for correct led behaviour. | 3753 | * Store led settings, for correct led behaviour. |
3753 | */ | 3754 | */ |
3754 | #ifdef CONFIG_RT2X00_LIB_LEDS | 3755 | #ifdef CONFIG_RT2X00_LIB_LEDS |
@@ -3756,7 +3757,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3756 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); | 3757 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); |
3757 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); | 3758 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); |
3758 | 3759 | ||
3759 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg); | 3760 | rt2x00dev->led_mcu_reg = eeprom; |
3760 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 3761 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
3761 | 3762 | ||
3762 | /* | 3763 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 08d3947fcb26..cc4a54f571b8 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -302,8 +302,8 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, | |||
302 | /* | 302 | /* |
303 | * Write firmware to device. | 303 | * Write firmware to device. |
304 | */ | 304 | */ |
305 | rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | 305 | rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, |
306 | data, len); | 306 | data, len); |
307 | 307 | ||
308 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); | 308 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); |
309 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); | 309 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 0d4e8fa3e1f8..0eb44cf2f44a 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -114,12 +114,12 @@ static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) | |||
114 | return false; | 114 | return false; |
115 | } | 115 | } |
116 | 116 | ||
117 | static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, | 117 | static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, |
118 | int urb_status, u32 tx_status) | 118 | int urb_status, u32 tx_status) |
119 | { | 119 | { |
120 | if (urb_status) { | 120 | if (urb_status) { |
121 | WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); | 121 | WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); |
122 | return; | 122 | return false; |
123 | } | 123 | } |
124 | 124 | ||
125 | /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ | 125 | /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ |
@@ -129,13 +129,14 @@ static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, | |||
129 | "drop tx status report.\n"); | 129 | "drop tx status report.\n"); |
130 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | 130 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); |
131 | } else | 131 | } else |
132 | rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, | 132 | return true; |
133 | rt2800usb_tx_sta_fifo_read_completed); | ||
134 | } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { | 133 | } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { |
135 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | 134 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); |
136 | } else if (rt2800usb_txstatus_pending(rt2x00dev)) { | 135 | } else if (rt2800usb_txstatus_pending(rt2x00dev)) { |
137 | mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(20)); | 136 | mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); |
138 | } | 137 | } |
138 | |||
139 | return false; | ||
139 | } | 140 | } |
140 | 141 | ||
141 | static void rt2800usb_tx_dma_done(struct queue_entry *entry) | 142 | static void rt2800usb_tx_dma_done(struct queue_entry *entry) |
@@ -493,7 +494,7 @@ static void rt2800usb_work_txdone(struct work_struct *work) | |||
493 | * also delayed -> use a timer to retrieve it. | 494 | * also delayed -> use a timer to retrieve it. |
494 | */ | 495 | */ |
495 | if (rt2800usb_txstatus_pending(rt2x00dev)) | 496 | if (rt2800usb_txstatus_pending(rt2x00dev)) |
496 | mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(20)); | 497 | mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); |
497 | } | 498 | } |
498 | 499 | ||
499 | /* | 500 | /* |
@@ -633,6 +634,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
633 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); | 634 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); |
634 | __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags); | 635 | __set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags); |
635 | __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); | 636 | __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); |
637 | __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags); | ||
636 | 638 | ||
637 | setup_timer(&rt2x00dev->txstatus_timer, | 639 | setup_timer(&rt2x00dev->txstatus_timer, |
638 | rt2800usb_tx_sta_fifo_timeout, | 640 | rt2800usb_tx_sta_fifo_timeout, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 9d1a158e2c33..c446db69bd3c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -662,6 +662,7 @@ enum rt2x00_state_flags { | |||
662 | * Driver configuration | 662 | * Driver configuration |
663 | */ | 663 | */ |
664 | CONFIG_CHANNEL_HT40, | 664 | CONFIG_CHANNEL_HT40, |
665 | CONFIG_POWERSAVING, | ||
665 | }; | 666 | }; |
666 | 667 | ||
667 | /* | 668 | /* |
@@ -681,6 +682,7 @@ enum rt2x00_capability_flags { | |||
681 | REQUIRE_TASKLET_CONTEXT, | 682 | REQUIRE_TASKLET_CONTEXT, |
682 | REQUIRE_SW_SEQNO, | 683 | REQUIRE_SW_SEQNO, |
683 | REQUIRE_HT_TX_DESC, | 684 | REQUIRE_HT_TX_DESC, |
685 | REQUIRE_PS_AUTOWAKE, | ||
684 | 686 | ||
685 | /* | 687 | /* |
686 | * Capabilities | 688 | * Capabilities |
@@ -697,6 +699,7 @@ enum rt2x00_capability_flags { | |||
697 | CAPABILITY_EXTERNAL_LNA_A, | 699 | CAPABILITY_EXTERNAL_LNA_A, |
698 | CAPABILITY_EXTERNAL_LNA_BG, | 700 | CAPABILITY_EXTERNAL_LNA_BG, |
699 | CAPABILITY_DOUBLE_ANTENNA, | 701 | CAPABILITY_DOUBLE_ANTENNA, |
702 | CAPABILITY_BT_COEXIST, | ||
700 | }; | 703 | }; |
701 | 704 | ||
702 | /* | 705 | /* |
@@ -874,10 +877,20 @@ struct rt2x00_dev { | |||
874 | u8 calibration[2]; | 877 | u8 calibration[2]; |
875 | 878 | ||
876 | /* | 879 | /* |
880 | * Association id. | ||
881 | */ | ||
882 | u16 aid; | ||
883 | |||
884 | /* | ||
877 | * Beacon interval. | 885 | * Beacon interval. |
878 | */ | 886 | */ |
879 | u16 beacon_int; | 887 | u16 beacon_int; |
880 | 888 | ||
889 | /** | ||
890 | * Timestamp of last received beacon | ||
891 | */ | ||
892 | unsigned long last_beacon; | ||
893 | |||
881 | /* | 894 | /* |
882 | * Low level statistics which will have | 895 | * Low level statistics which will have |
883 | * to be kept up to date while device is running. | 896 | * to be kept up to date while device is running. |
@@ -906,6 +919,11 @@ struct rt2x00_dev { | |||
906 | struct work_struct txdone_work; | 919 | struct work_struct txdone_work; |
907 | 920 | ||
908 | /* | 921 | /* |
922 | * Powersaving work | ||
923 | */ | ||
924 | struct delayed_work autowakeup_work; | ||
925 | |||
926 | /* | ||
909 | * Data queue arrays for RX, TX, Beacon and ATIM. | 927 | * Data queue arrays for RX, TX, Beacon and ATIM. |
910 | */ | 928 | */ |
911 | unsigned int data_queues; | 929 | unsigned int data_queues; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index f78726404592..555180d8f4aa 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -100,6 +100,10 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
100 | erp.basic_rates = bss_conf->basic_rates; | 100 | erp.basic_rates = bss_conf->basic_rates; |
101 | erp.beacon_int = bss_conf->beacon_int; | 101 | erp.beacon_int = bss_conf->beacon_int; |
102 | 102 | ||
103 | /* Update the AID, this is needed for dynamic PS support */ | ||
104 | rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0; | ||
105 | rt2x00dev->last_beacon = bss_conf->timestamp; | ||
106 | |||
103 | /* Update global beacon interval time, this is needed for PS support */ | 107 | /* Update global beacon interval time, this is needed for PS support */ |
104 | rt2x00dev->beacon_int = bss_conf->beacon_int; | 108 | rt2x00dev->beacon_int = bss_conf->beacon_int; |
105 | 109 | ||
@@ -204,6 +208,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
204 | { | 208 | { |
205 | struct rt2x00lib_conf libconf; | 209 | struct rt2x00lib_conf libconf; |
206 | u16 hw_value; | 210 | u16 hw_value; |
211 | u16 autowake_timeout; | ||
212 | u16 beacon_int; | ||
213 | u16 beacon_diff; | ||
207 | 214 | ||
208 | memset(&libconf, 0, sizeof(libconf)); | 215 | memset(&libconf, 0, sizeof(libconf)); |
209 | 216 | ||
@@ -227,6 +234,10 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
227 | sizeof(libconf.channel)); | 234 | sizeof(libconf.channel)); |
228 | } | 235 | } |
229 | 236 | ||
237 | if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && | ||
238 | (ieee80211_flags & IEEE80211_CONF_CHANGE_PS)) | ||
239 | cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); | ||
240 | |||
230 | /* | 241 | /* |
231 | * Start configuration. | 242 | * Start configuration. |
232 | */ | 243 | */ |
@@ -239,6 +250,26 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
239 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) | 250 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) |
240 | rt2x00link_reset_tuner(rt2x00dev, false); | 251 | rt2x00link_reset_tuner(rt2x00dev, false); |
241 | 252 | ||
253 | if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && | ||
254 | (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) && | ||
255 | (conf->flags & IEEE80211_CONF_PS)) { | ||
256 | beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon; | ||
257 | beacon_int = msecs_to_jiffies(rt2x00dev->beacon_int); | ||
258 | |||
259 | if (beacon_diff > beacon_int) | ||
260 | beacon_diff = 0; | ||
261 | |||
262 | autowake_timeout = (conf->max_sleep_period * beacon_int) - beacon_diff; | ||
263 | queue_delayed_work(rt2x00dev->workqueue, | ||
264 | &rt2x00dev->autowakeup_work, | ||
265 | autowake_timeout - 15); | ||
266 | } | ||
267 | |||
268 | if (conf->flags & IEEE80211_CONF_PS) | ||
269 | set_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); | ||
270 | else | ||
271 | clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); | ||
272 | |||
242 | rt2x00dev->curr_band = conf->channel->band; | 273 | rt2x00dev->curr_band = conf->channel->band; |
243 | rt2x00dev->curr_freq = conf->channel->center_freq; | 274 | rt2x00dev->curr_freq = conf->channel->center_freq; |
244 | rt2x00dev->tx_power = conf->power_level; | 275 | rt2x00dev->tx_power = conf->power_level; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 7776d9f1f297..2eb5196977fd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -141,6 +141,16 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work) | |||
141 | rt2x00dev); | 141 | rt2x00dev); |
142 | } | 142 | } |
143 | 143 | ||
144 | static void rt2x00lib_autowakeup(struct work_struct *work) | ||
145 | { | ||
146 | struct rt2x00_dev *rt2x00dev = | ||
147 | container_of(work, struct rt2x00_dev, autowakeup_work.work); | ||
148 | |||
149 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | ||
150 | ERROR(rt2x00dev, "Device failed to wakeup.\n"); | ||
151 | clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); | ||
152 | } | ||
153 | |||
144 | /* | 154 | /* |
145 | * Interrupt context handlers. | 155 | * Interrupt context handlers. |
146 | */ | 156 | */ |
@@ -416,6 +426,77 @@ void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status) | |||
416 | } | 426 | } |
417 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo); | 427 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo); |
418 | 428 | ||
429 | static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie) | ||
430 | { | ||
431 | struct ieee80211_mgmt *mgmt = (void *)data; | ||
432 | u8 *pos, *end; | ||
433 | |||
434 | pos = (u8 *)mgmt->u.beacon.variable; | ||
435 | end = data + len; | ||
436 | while (pos < end) { | ||
437 | if (pos + 2 + pos[1] > end) | ||
438 | return NULL; | ||
439 | |||
440 | if (pos[0] == ie) | ||
441 | return pos; | ||
442 | |||
443 | pos += 2 + pos[1]; | ||
444 | } | ||
445 | |||
446 | return NULL; | ||
447 | } | ||
448 | |||
449 | static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev, | ||
450 | struct sk_buff *skb, | ||
451 | struct rxdone_entry_desc *rxdesc) | ||
452 | { | ||
453 | struct ieee80211_hdr *hdr = (void *) skb->data; | ||
454 | struct ieee80211_tim_ie *tim_ie; | ||
455 | u8 *tim; | ||
456 | u8 tim_len; | ||
457 | bool cam; | ||
458 | |||
459 | /* If this is not a beacon, or if mac80211 has no powersaving | ||
460 | * configured, or if the device is already in powersaving mode | ||
461 | * we can exit now. */ | ||
462 | if (likely(!ieee80211_is_beacon(hdr->frame_control) || | ||
463 | !(rt2x00dev->hw->conf.flags & IEEE80211_CONF_PS))) | ||
464 | return; | ||
465 | |||
466 | /* min. beacon length + FCS_LEN */ | ||
467 | if (skb->len <= 40 + FCS_LEN) | ||
468 | return; | ||
469 | |||
470 | /* and only beacons from the associated BSSID, please */ | ||
471 | if (!(rxdesc->dev_flags & RXDONE_MY_BSS) || | ||
472 | !rt2x00dev->aid) | ||
473 | return; | ||
474 | |||
475 | rt2x00dev->last_beacon = jiffies; | ||
476 | |||
477 | tim = rt2x00lib_find_ie(skb->data, skb->len - FCS_LEN, WLAN_EID_TIM); | ||
478 | if (!tim) | ||
479 | return; | ||
480 | |||
481 | if (tim[1] < sizeof(*tim_ie)) | ||
482 | return; | ||
483 | |||
484 | tim_len = tim[1]; | ||
485 | tim_ie = (struct ieee80211_tim_ie *) &tim[2]; | ||
486 | |||
487 | /* Check whenever the PHY can be turned off again. */ | ||
488 | |||
489 | /* 1. What about buffered unicast traffic for our AID? */ | ||
490 | cam = ieee80211_check_tim(tim_ie, tim_len, rt2x00dev->aid); | ||
491 | |||
492 | /* 2. Maybe the AP wants to send multicast/broadcast data? */ | ||
493 | cam |= (tim_ie->bitmap_ctrl & 0x01); | ||
494 | |||
495 | if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags)) | ||
496 | rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, | ||
497 | IEEE80211_CONF_CHANGE_PS); | ||
498 | } | ||
499 | |||
419 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, | 500 | static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, |
420 | struct rxdone_entry_desc *rxdesc) | 501 | struct rxdone_entry_desc *rxdesc) |
421 | { | 502 | { |
@@ -531,6 +612,12 @@ void rt2x00lib_rxdone(struct queue_entry *entry) | |||
531 | rxdesc.flags |= RX_FLAG_HT; | 612 | rxdesc.flags |= RX_FLAG_HT; |
532 | 613 | ||
533 | /* | 614 | /* |
615 | * Check if this is a beacon, and more frames have been | ||
616 | * buffered while we were in powersaving mode. | ||
617 | */ | ||
618 | rt2x00lib_rxdone_check_ps(rt2x00dev, entry->skb, &rxdesc); | ||
619 | |||
620 | /* | ||
534 | * Update extra components | 621 | * Update extra components |
535 | */ | 622 | */ |
536 | rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); | 623 | rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); |
@@ -1017,6 +1104,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1017 | } | 1104 | } |
1018 | 1105 | ||
1019 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); | 1106 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1107 | INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); | ||
1020 | 1108 | ||
1021 | /* | 1109 | /* |
1022 | * Let the driver probe the device to detect the capabilities. | 1110 | * Let the driver probe the device to detect the capabilities. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index cb208d589ff8..39e1052123e3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -170,19 +170,22 @@ struct rt2x00_async_read_data { | |||
170 | __le32 reg; | 170 | __le32 reg; |
171 | struct usb_ctrlrequest cr; | 171 | struct usb_ctrlrequest cr; |
172 | struct rt2x00_dev *rt2x00dev; | 172 | struct rt2x00_dev *rt2x00dev; |
173 | void (*callback)(struct rt2x00_dev *,int,u32); | 173 | bool (*callback)(struct rt2x00_dev *, int, u32); |
174 | }; | 174 | }; |
175 | 175 | ||
176 | static void rt2x00usb_register_read_async_cb(struct urb *urb) | 176 | static void rt2x00usb_register_read_async_cb(struct urb *urb) |
177 | { | 177 | { |
178 | struct rt2x00_async_read_data *rd = urb->context; | 178 | struct rt2x00_async_read_data *rd = urb->context; |
179 | rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg)); | 179 | if (rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg))) { |
180 | kfree(urb->context); | 180 | if (usb_submit_urb(urb, GFP_ATOMIC) < 0) |
181 | kfree(rd); | ||
182 | } else | ||
183 | kfree(rd); | ||
181 | } | 184 | } |
182 | 185 | ||
183 | void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, | 186 | void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, |
184 | const unsigned int offset, | 187 | const unsigned int offset, |
185 | void (*callback)(struct rt2x00_dev*,int,u32)) | 188 | bool (*callback)(struct rt2x00_dev*, int, u32)) |
186 | { | 189 | { |
187 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | 190 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); |
188 | struct urb *urb; | 191 | struct urb *urb; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 64be34f612f6..323ca7b2b095 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -349,10 +349,12 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
349 | * be called from atomic context. The callback will be called | 349 | * be called from atomic context. The callback will be called |
350 | * when the URB completes. Otherwise the function is similar | 350 | * when the URB completes. Otherwise the function is similar |
351 | * to rt2x00usb_register_read(). | 351 | * to rt2x00usb_register_read(). |
352 | * When the callback function returns false, the memory will be cleaned up, | ||
353 | * when it returns true, the urb will be fired again. | ||
352 | */ | 354 | */ |
353 | void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, | 355 | void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, |
354 | const unsigned int offset, | 356 | const unsigned int offset, |
355 | void (*callback)(struct rt2x00_dev*,int,u32)); | 357 | bool (*callback)(struct rt2x00_dev*, int, u32)); |
356 | 358 | ||
357 | /* | 359 | /* |
358 | * Radio handlers | 360 | * Radio handlers |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index a6ce7d6cbdfa..ad20953cbf05 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2209,6 +2209,7 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2209 | if (!modparam_nohwcrypt) | 2209 | if (!modparam_nohwcrypt) |
2210 | __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); | 2210 | __set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags); |
2211 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); | 2211 | __set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags); |
2212 | __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags); | ||
2212 | 2213 | ||
2213 | /* | 2214 | /* |
2214 | * Set the rssi offset. | 2215 | * Set the rssi offset. |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index b259f807ad27..ccb6da38fe22 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -50,8 +50,9 @@ | |||
50 | *3) functions called by core.c | 50 | *3) functions called by core.c |
51 | *4) wq & timer callback functions | 51 | *4) wq & timer callback functions |
52 | *5) frame process functions | 52 | *5) frame process functions |
53 | *6) sysfs functions | 53 | *6) IOT functions |
54 | *7) ... | 54 | *7) sysfs functions |
55 | *8) ... | ||
55 | */ | 56 | */ |
56 | 57 | ||
57 | /********************************************************* | 58 | /********************************************************* |
@@ -59,7 +60,7 @@ | |||
59 | * mac80211 init functions | 60 | * mac80211 init functions |
60 | * | 61 | * |
61 | *********************************************************/ | 62 | *********************************************************/ |
62 | static struct ieee80211_channel rtl_channeltable[] = { | 63 | static struct ieee80211_channel rtl_channeltable_2g[] = { |
63 | {.center_freq = 2412, .hw_value = 1,}, | 64 | {.center_freq = 2412, .hw_value = 1,}, |
64 | {.center_freq = 2417, .hw_value = 2,}, | 65 | {.center_freq = 2417, .hw_value = 2,}, |
65 | {.center_freq = 2422, .hw_value = 3,}, | 66 | {.center_freq = 2422, .hw_value = 3,}, |
@@ -76,7 +77,34 @@ static struct ieee80211_channel rtl_channeltable[] = { | |||
76 | {.center_freq = 2484, .hw_value = 14,}, | 77 | {.center_freq = 2484, .hw_value = 14,}, |
77 | }; | 78 | }; |
78 | 79 | ||
79 | static struct ieee80211_rate rtl_ratetable[] = { | 80 | static struct ieee80211_channel rtl_channeltable_5g[] = { |
81 | {.center_freq = 5180, .hw_value = 36,}, | ||
82 | {.center_freq = 5200, .hw_value = 40,}, | ||
83 | {.center_freq = 5220, .hw_value = 44,}, | ||
84 | {.center_freq = 5240, .hw_value = 48,}, | ||
85 | {.center_freq = 5260, .hw_value = 52,}, | ||
86 | {.center_freq = 5280, .hw_value = 56,}, | ||
87 | {.center_freq = 5300, .hw_value = 60,}, | ||
88 | {.center_freq = 5320, .hw_value = 64,}, | ||
89 | {.center_freq = 5500, .hw_value = 100,}, | ||
90 | {.center_freq = 5520, .hw_value = 104,}, | ||
91 | {.center_freq = 5540, .hw_value = 108,}, | ||
92 | {.center_freq = 5560, .hw_value = 112,}, | ||
93 | {.center_freq = 5580, .hw_value = 116,}, | ||
94 | {.center_freq = 5600, .hw_value = 120,}, | ||
95 | {.center_freq = 5620, .hw_value = 124,}, | ||
96 | {.center_freq = 5640, .hw_value = 128,}, | ||
97 | {.center_freq = 5660, .hw_value = 132,}, | ||
98 | {.center_freq = 5680, .hw_value = 136,}, | ||
99 | {.center_freq = 5700, .hw_value = 140,}, | ||
100 | {.center_freq = 5745, .hw_value = 149,}, | ||
101 | {.center_freq = 5765, .hw_value = 153,}, | ||
102 | {.center_freq = 5785, .hw_value = 157,}, | ||
103 | {.center_freq = 5805, .hw_value = 161,}, | ||
104 | {.center_freq = 5825, .hw_value = 165,}, | ||
105 | }; | ||
106 | |||
107 | static struct ieee80211_rate rtl_ratetable_2g[] = { | ||
80 | {.bitrate = 10, .hw_value = 0x00,}, | 108 | {.bitrate = 10, .hw_value = 0x00,}, |
81 | {.bitrate = 20, .hw_value = 0x01,}, | 109 | {.bitrate = 20, .hw_value = 0x01,}, |
82 | {.bitrate = 55, .hw_value = 0x02,}, | 110 | {.bitrate = 55, .hw_value = 0x02,}, |
@@ -91,18 +119,57 @@ static struct ieee80211_rate rtl_ratetable[] = { | |||
91 | {.bitrate = 540, .hw_value = 0x0b,}, | 119 | {.bitrate = 540, .hw_value = 0x0b,}, |
92 | }; | 120 | }; |
93 | 121 | ||
122 | static struct ieee80211_rate rtl_ratetable_5g[] = { | ||
123 | {.bitrate = 60, .hw_value = 0x04,}, | ||
124 | {.bitrate = 90, .hw_value = 0x05,}, | ||
125 | {.bitrate = 120, .hw_value = 0x06,}, | ||
126 | {.bitrate = 180, .hw_value = 0x07,}, | ||
127 | {.bitrate = 240, .hw_value = 0x08,}, | ||
128 | {.bitrate = 360, .hw_value = 0x09,}, | ||
129 | {.bitrate = 480, .hw_value = 0x0a,}, | ||
130 | {.bitrate = 540, .hw_value = 0x0b,}, | ||
131 | }; | ||
132 | |||
94 | static const struct ieee80211_supported_band rtl_band_2ghz = { | 133 | static const struct ieee80211_supported_band rtl_band_2ghz = { |
95 | .band = IEEE80211_BAND_2GHZ, | 134 | .band = IEEE80211_BAND_2GHZ, |
96 | 135 | ||
97 | .channels = rtl_channeltable, | 136 | .channels = rtl_channeltable_2g, |
98 | .n_channels = ARRAY_SIZE(rtl_channeltable), | 137 | .n_channels = ARRAY_SIZE(rtl_channeltable_2g), |
138 | |||
139 | .bitrates = rtl_ratetable_2g, | ||
140 | .n_bitrates = ARRAY_SIZE(rtl_ratetable_2g), | ||
141 | |||
142 | .ht_cap = {0}, | ||
143 | }; | ||
144 | |||
145 | static struct ieee80211_supported_band rtl_band_5ghz = { | ||
146 | .band = IEEE80211_BAND_5GHZ, | ||
147 | |||
148 | .channels = rtl_channeltable_5g, | ||
149 | .n_channels = ARRAY_SIZE(rtl_channeltable_5g), | ||
99 | 150 | ||
100 | .bitrates = rtl_ratetable, | 151 | .bitrates = rtl_ratetable_5g, |
101 | .n_bitrates = ARRAY_SIZE(rtl_ratetable), | 152 | .n_bitrates = ARRAY_SIZE(rtl_ratetable_5g), |
102 | 153 | ||
103 | .ht_cap = {0}, | 154 | .ht_cap = {0}, |
104 | }; | 155 | }; |
105 | 156 | ||
157 | static const u8 tid_to_ac[] = { | ||
158 | 2, /* IEEE80211_AC_BE */ | ||
159 | 3, /* IEEE80211_AC_BK */ | ||
160 | 3, /* IEEE80211_AC_BK */ | ||
161 | 2, /* IEEE80211_AC_BE */ | ||
162 | 1, /* IEEE80211_AC_VI */ | ||
163 | 1, /* IEEE80211_AC_VI */ | ||
164 | 0, /* IEEE80211_AC_VO */ | ||
165 | 0, /* IEEE80211_AC_VO */ | ||
166 | }; | ||
167 | |||
168 | u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid) | ||
169 | { | ||
170 | return tid_to_ac[tid]; | ||
171 | } | ||
172 | |||
106 | static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, | 173 | static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, |
107 | struct ieee80211_sta_ht_cap *ht_cap) | 174 | struct ieee80211_sta_ht_cap *ht_cap) |
108 | { | 175 | { |
@@ -115,6 +182,9 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, | |||
115 | IEEE80211_HT_CAP_SGI_20 | | 182 | IEEE80211_HT_CAP_SGI_20 | |
116 | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; | 183 | IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; |
117 | 184 | ||
185 | if (rtlpriv->rtlhal.disable_amsdu_8k) | ||
186 | ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; | ||
187 | |||
118 | /* | 188 | /* |
119 | *Maximum length of AMPDU that the STA can receive. | 189 | *Maximum length of AMPDU that the STA can receive. |
120 | *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) | 190 | *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) |
@@ -159,37 +229,99 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, | |||
159 | 229 | ||
160 | static void _rtl_init_mac80211(struct ieee80211_hw *hw) | 230 | static void _rtl_init_mac80211(struct ieee80211_hw *hw) |
161 | { | 231 | { |
232 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
233 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
162 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); | 234 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); |
163 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 235 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
164 | struct ieee80211_supported_band *sband; | 236 | struct ieee80211_supported_band *sband; |
165 | 237 | ||
166 | /* <1> use mac->bands as mem for hw->wiphy->bands */ | ||
167 | sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); | ||
168 | 238 | ||
169 | /* | 239 | if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && rtlhal->bandset == |
170 | * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] | 240 | BAND_ON_BOTH) { |
171 | * to default value(1T1R) | 241 | /* 1: 2.4 G bands */ |
172 | */ | 242 | /* <1> use mac->bands as mem for hw->wiphy->bands */ |
173 | memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, | 243 | sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); |
174 | sizeof(struct ieee80211_supported_band)); | ||
175 | 244 | ||
176 | /* <3> init ht cap base on ant_num */ | 245 | /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] |
177 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); | 246 | * to default value(1T1R) */ |
247 | memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, | ||
248 | sizeof(struct ieee80211_supported_band)); | ||
178 | 249 | ||
179 | /* <4> set mac->sband to wiphy->sband */ | 250 | /* <3> init ht cap base on ant_num */ |
180 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | 251 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); |
181 | 252 | ||
253 | /* <4> set mac->sband to wiphy->sband */ | ||
254 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | ||
255 | |||
256 | /* 2: 5 G bands */ | ||
257 | /* <1> use mac->bands as mem for hw->wiphy->bands */ | ||
258 | sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); | ||
259 | |||
260 | /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] | ||
261 | * to default value(1T1R) */ | ||
262 | memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz, | ||
263 | sizeof(struct ieee80211_supported_band)); | ||
264 | |||
265 | /* <3> init ht cap base on ant_num */ | ||
266 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); | ||
267 | |||
268 | /* <4> set mac->sband to wiphy->sband */ | ||
269 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; | ||
270 | } else { | ||
271 | if (rtlhal->current_bandtype == BAND_ON_2_4G) { | ||
272 | /* <1> use mac->bands as mem for hw->wiphy->bands */ | ||
273 | sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); | ||
274 | |||
275 | /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] | ||
276 | * to default value(1T1R) */ | ||
277 | memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), | ||
278 | &rtl_band_2ghz, | ||
279 | sizeof(struct ieee80211_supported_band)); | ||
280 | |||
281 | /* <3> init ht cap base on ant_num */ | ||
282 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); | ||
283 | |||
284 | /* <4> set mac->sband to wiphy->sband */ | ||
285 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | ||
286 | } else if (rtlhal->current_bandtype == BAND_ON_5G) { | ||
287 | /* <1> use mac->bands as mem for hw->wiphy->bands */ | ||
288 | sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); | ||
289 | |||
290 | /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] | ||
291 | * to default value(1T1R) */ | ||
292 | memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), | ||
293 | &rtl_band_5ghz, | ||
294 | sizeof(struct ieee80211_supported_band)); | ||
295 | |||
296 | /* <3> init ht cap base on ant_num */ | ||
297 | _rtl_init_hw_ht_capab(hw, &sband->ht_cap); | ||
298 | |||
299 | /* <4> set mac->sband to wiphy->sband */ | ||
300 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; | ||
301 | } else { | ||
302 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
303 | ("Err BAND %d\n", | ||
304 | rtlhal->current_bandtype)); | ||
305 | } | ||
306 | } | ||
182 | /* <5> set hw caps */ | 307 | /* <5> set hw caps */ |
183 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 308 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
184 | IEEE80211_HW_RX_INCLUDES_FCS | | 309 | IEEE80211_HW_RX_INCLUDES_FCS | |
185 | IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/ | 310 | IEEE80211_HW_BEACON_FILTER | |
186 | /*IEEE80211_HW_SUPPORTS_PS | */ | 311 | IEEE80211_HW_AMPDU_AGGREGATION | |
187 | /*IEEE80211_HW_PS_NULLFUNC_STACK | */ | ||
188 | /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ | ||
189 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; | 312 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; |
190 | 313 | ||
314 | /* swlps or hwlps has been set in diff chip in init_sw_vars */ | ||
315 | if (rtlpriv->psc.swctrl_lps) | ||
316 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
317 | IEEE80211_HW_PS_NULLFUNC_STACK | | ||
318 | /* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ | ||
319 | 0; | ||
320 | |||
191 | hw->wiphy->interface_modes = | 321 | hw->wiphy->interface_modes = |
192 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); | 322 | BIT(NL80211_IFTYPE_AP) | |
323 | BIT(NL80211_IFTYPE_STATION) | | ||
324 | BIT(NL80211_IFTYPE_ADHOC); | ||
193 | 325 | ||
194 | hw->wiphy->rts_threshold = 2347; | 326 | hw->wiphy->rts_threshold = 2347; |
195 | 327 | ||
@@ -199,9 +331,10 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) | |||
199 | /* TODO: Correct this value for our hw */ | 331 | /* TODO: Correct this value for our hw */ |
200 | /* TODO: define these hard code value */ | 332 | /* TODO: define these hard code value */ |
201 | hw->channel_change_time = 100; | 333 | hw->channel_change_time = 100; |
202 | hw->max_listen_interval = 5; | 334 | hw->max_listen_interval = 10; |
203 | hw->max_rate_tries = 4; | 335 | hw->max_rate_tries = 4; |
204 | /* hw->max_rates = 1; */ | 336 | /* hw->max_rates = 1; */ |
337 | hw->sta_data_size = sizeof(struct rtl_sta_info); | ||
205 | 338 | ||
206 | /* <6> mac address */ | 339 | /* <6> mac address */ |
207 | if (is_valid_ether_addr(rtlefuse->dev_addr)) { | 340 | if (is_valid_ether_addr(rtlefuse->dev_addr)) { |
@@ -230,6 +363,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) | |||
230 | (void *)rtl_watchdog_wq_callback); | 363 | (void *)rtl_watchdog_wq_callback); |
231 | INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, | 364 | INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, |
232 | (void *)rtl_ips_nic_off_wq_callback); | 365 | (void *)rtl_ips_nic_off_wq_callback); |
366 | INIT_DELAYED_WORK(&rtlpriv->works.ps_work, | ||
367 | (void *)rtl_swlps_wq_callback); | ||
368 | INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq, | ||
369 | (void *)rtl_swlps_rfon_wq_callback); | ||
233 | 370 | ||
234 | } | 371 | } |
235 | 372 | ||
@@ -241,6 +378,8 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw) | |||
241 | 378 | ||
242 | cancel_delayed_work(&rtlpriv->works.watchdog_wq); | 379 | cancel_delayed_work(&rtlpriv->works.watchdog_wq); |
243 | cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); | 380 | cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); |
381 | cancel_delayed_work(&rtlpriv->works.ps_work); | ||
382 | cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); | ||
244 | } | 383 | } |
245 | 384 | ||
246 | void rtl_init_rfkill(struct ieee80211_hw *hw) | 385 | void rtl_init_rfkill(struct ieee80211_hw *hw) |
@@ -310,6 +449,8 @@ int rtl_init_core(struct ieee80211_hw *hw) | |||
310 | spin_lock_init(&rtlpriv->locks.rf_ps_lock); | 449 | spin_lock_init(&rtlpriv->locks.rf_ps_lock); |
311 | spin_lock_init(&rtlpriv->locks.rf_lock); | 450 | spin_lock_init(&rtlpriv->locks.rf_lock); |
312 | spin_lock_init(&rtlpriv->locks.lps_lock); | 451 | spin_lock_init(&rtlpriv->locks.lps_lock); |
452 | spin_lock_init(&rtlpriv->locks.waitq_lock); | ||
453 | spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); | ||
313 | 454 | ||
314 | rtlmac->link_state = MAC80211_NOLINK; | 455 | rtlmac->link_state = MAC80211_NOLINK; |
315 | 456 | ||
@@ -329,12 +470,6 @@ void rtl_init_rx_config(struct ieee80211_hw *hw) | |||
329 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 470 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
330 | 471 | ||
331 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); | 472 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); |
332 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER, | ||
333 | (u8 *) (&mac->rx_mgt_filter)); | ||
334 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER, | ||
335 | (u8 *) (&mac->rx_ctrl_filter)); | ||
336 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER, | ||
337 | (u8 *) (&mac->rx_data_filter)); | ||
338 | } | 473 | } |
339 | 474 | ||
340 | /********************************************************* | 475 | /********************************************************* |
@@ -361,28 +496,40 @@ static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw, | |||
361 | } | 496 | } |
362 | 497 | ||
363 | static void _rtl_query_shortgi(struct ieee80211_hw *hw, | 498 | static void _rtl_query_shortgi(struct ieee80211_hw *hw, |
499 | struct ieee80211_sta *sta, | ||
364 | struct rtl_tcb_desc *tcb_desc, | 500 | struct rtl_tcb_desc *tcb_desc, |
365 | struct ieee80211_tx_info *info) | 501 | struct ieee80211_tx_info *info) |
366 | { | 502 | { |
367 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 503 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
368 | u8 rate_flag = info->control.rates[0].flags; | 504 | u8 rate_flag = info->control.rates[0].flags; |
369 | 505 | u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0; | |
370 | tcb_desc->use_shortgi = false; | 506 | tcb_desc->use_shortgi = false; |
371 | 507 | ||
372 | if (!mac->ht_enable) | 508 | if (sta == NULL) |
373 | return; | 509 | return; |
374 | 510 | ||
375 | if (!mac->sgi_40 && !mac->sgi_20) | 511 | sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; |
512 | sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; | ||
513 | |||
514 | if (!(sta->ht_cap.ht_supported)) | ||
515 | return; | ||
516 | |||
517 | if (!sgi_40 && !sgi_20) | ||
376 | return; | 518 | return; |
377 | 519 | ||
378 | if ((mac->bw_40 == true) && mac->sgi_40) | 520 | if (mac->opmode == NL80211_IFTYPE_STATION) |
521 | bw_40 = mac->bw_40; | ||
522 | else if (mac->opmode == NL80211_IFTYPE_AP || | ||
523 | mac->opmode == NL80211_IFTYPE_ADHOC) | ||
524 | bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
525 | |||
526 | if ((bw_40 == true) && sgi_40) | ||
379 | tcb_desc->use_shortgi = true; | 527 | tcb_desc->use_shortgi = true; |
380 | else if ((mac->bw_40 == false) && mac->sgi_20) | 528 | else if ((bw_40 == false) && sgi_20) |
381 | tcb_desc->use_shortgi = true; | 529 | tcb_desc->use_shortgi = true; |
382 | 530 | ||
383 | if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI)) | 531 | if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI)) |
384 | tcb_desc->use_shortgi = false; | 532 | tcb_desc->use_shortgi = false; |
385 | |||
386 | } | 533 | } |
387 | 534 | ||
388 | static void _rtl_query_protection_mode(struct ieee80211_hw *hw, | 535 | static void _rtl_query_protection_mode(struct ieee80211_hw *hw, |
@@ -410,19 +557,25 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw, | |||
410 | tcb_desc->rts_enable = true; | 557 | tcb_desc->rts_enable = true; |
411 | tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; | 558 | tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; |
412 | } | 559 | } |
413 | |||
414 | } | 560 | } |
415 | 561 | ||
416 | static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, | 562 | static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, |
563 | struct ieee80211_sta *sta, | ||
417 | struct rtl_tcb_desc *tcb_desc) | 564 | struct rtl_tcb_desc *tcb_desc) |
418 | { | 565 | { |
419 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 566 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
420 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 567 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
568 | struct rtl_sta_info *sta_entry = NULL; | ||
569 | u8 ratr_index = 7; | ||
421 | 570 | ||
571 | if (sta) { | ||
572 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
573 | ratr_index = sta_entry->ratr_index; | ||
574 | } | ||
422 | if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) { | 575 | if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) { |
423 | if (mac->opmode == NL80211_IFTYPE_STATION) | 576 | if (mac->opmode == NL80211_IFTYPE_STATION) { |
424 | tcb_desc->ratr_index = 0; | 577 | tcb_desc->ratr_index = 0; |
425 | else if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 578 | } else if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
426 | if (tcb_desc->multicast || tcb_desc->broadcast) { | 579 | if (tcb_desc->multicast || tcb_desc->broadcast) { |
427 | tcb_desc->hw_rate = | 580 | tcb_desc->hw_rate = |
428 | rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; | 581 | rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; |
@@ -430,36 +583,61 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, | |||
430 | } else { | 583 | } else { |
431 | /* TODO */ | 584 | /* TODO */ |
432 | } | 585 | } |
586 | tcb_desc->ratr_index = ratr_index; | ||
587 | } else if (mac->opmode == NL80211_IFTYPE_AP) { | ||
588 | tcb_desc->ratr_index = ratr_index; | ||
433 | } | 589 | } |
434 | } | 590 | } |
435 | 591 | ||
436 | if (rtlpriv->dm.useramask) { | 592 | if (rtlpriv->dm.useramask) { |
437 | /* TODO adhoc and station handled differently in the future */ | 593 | /* TODO we will differentiate adhoc and station futrue */ |
438 | tcb_desc->mac_id = 0; | 594 | if (mac->opmode == NL80211_IFTYPE_STATION) { |
439 | 595 | tcb_desc->mac_id = 0; | |
440 | if ((mac->mode == WIRELESS_MODE_N_24G) || | 596 | |
441 | (mac->mode == WIRELESS_MODE_N_5G)) { | 597 | if (mac->mode == WIRELESS_MODE_N_24G) |
442 | tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB; | 598 | tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB; |
443 | } else if (mac->mode & WIRELESS_MODE_G) { | 599 | else if (mac->mode == WIRELESS_MODE_N_5G) |
444 | tcb_desc->ratr_index = RATR_INX_WIRELESS_GB; | 600 | tcb_desc->ratr_index = RATR_INX_WIRELESS_NG; |
445 | } else if (mac->mode & WIRELESS_MODE_B) { | 601 | else if (mac->mode & WIRELESS_MODE_G) |
446 | tcb_desc->ratr_index = RATR_INX_WIRELESS_B; | 602 | tcb_desc->ratr_index = RATR_INX_WIRELESS_GB; |
603 | else if (mac->mode & WIRELESS_MODE_B) | ||
604 | tcb_desc->ratr_index = RATR_INX_WIRELESS_B; | ||
605 | else if (mac->mode & WIRELESS_MODE_A) | ||
606 | tcb_desc->ratr_index = RATR_INX_WIRELESS_G; | ||
607 | } else if (mac->opmode == NL80211_IFTYPE_AP || | ||
608 | mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
609 | if (NULL != sta) { | ||
610 | if (sta->aid > 0) | ||
611 | tcb_desc->mac_id = sta->aid + 1; | ||
612 | else | ||
613 | tcb_desc->mac_id = 1; | ||
614 | } else { | ||
615 | tcb_desc->mac_id = 0; | ||
616 | } | ||
447 | } | 617 | } |
448 | } | 618 | } |
449 | 619 | ||
450 | } | 620 | } |
451 | 621 | ||
452 | static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, | 622 | static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, |
623 | struct ieee80211_sta *sta, | ||
453 | struct rtl_tcb_desc *tcb_desc) | 624 | struct rtl_tcb_desc *tcb_desc) |
454 | { | 625 | { |
455 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 626 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
456 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 627 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
457 | 628 | ||
458 | tcb_desc->packet_bw = false; | 629 | tcb_desc->packet_bw = false; |
459 | 630 | if (!sta) | |
460 | if (!mac->bw_40 || !mac->ht_enable) | ||
461 | return; | 631 | return; |
462 | 632 | if (mac->opmode == NL80211_IFTYPE_AP || | |
633 | mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
634 | if (!(sta->ht_cap.ht_supported) || | ||
635 | !(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | ||
636 | return; | ||
637 | } else if (mac->opmode == NL80211_IFTYPE_STATION) { | ||
638 | if (!mac->bw_40 || !(sta->ht_cap.ht_supported)) | ||
639 | return; | ||
640 | } | ||
463 | if (tcb_desc->multicast || tcb_desc->broadcast) | 641 | if (tcb_desc->multicast || tcb_desc->broadcast) |
464 | return; | 642 | return; |
465 | 643 | ||
@@ -486,22 +664,21 @@ static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw) | |||
486 | 664 | ||
487 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, | 665 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, |
488 | struct ieee80211_tx_info *info, | 666 | struct ieee80211_tx_info *info, |
667 | struct ieee80211_sta *sta, | ||
489 | struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc) | 668 | struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc) |
490 | { | 669 | { |
491 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 670 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
492 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); | 671 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); |
493 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 672 | struct ieee80211_hdr *hdr = rtl_get_hdr(skb); |
494 | struct ieee80211_rate *txrate; | 673 | struct ieee80211_rate *txrate; |
495 | __le16 fc = hdr->frame_control; | 674 | __le16 fc = hdr->frame_control; |
496 | 675 | ||
497 | memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | 676 | txrate = ieee80211_get_tx_rate(hw, info); |
677 | tcb_desc->hw_rate = txrate->hw_value; | ||
498 | 678 | ||
499 | if (ieee80211_is_data(fc)) { | 679 | if (ieee80211_is_data(fc)) { |
500 | txrate = ieee80211_get_tx_rate(hw, info); | ||
501 | tcb_desc->hw_rate = txrate->hw_value; | ||
502 | |||
503 | /* | 680 | /* |
504 | *we set data rate RTL_RC_CCK_RATE1M | 681 | *we set data rate INX 0 |
505 | *in rtl_rc.c if skb is special data or | 682 | *in rtl_rc.c if skb is special data or |
506 | *mgt which need low data rate. | 683 | *mgt which need low data rate. |
507 | */ | 684 | */ |
@@ -510,12 +687,11 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, | |||
510 | *So tcb_desc->hw_rate is just used for | 687 | *So tcb_desc->hw_rate is just used for |
511 | *special data and mgt frames | 688 | *special data and mgt frames |
512 | */ | 689 | */ |
513 | if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) { | 690 | if (info->control.rates[0].idx == 0 && |
691 | ieee80211_is_nullfunc(fc)) { | ||
514 | tcb_desc->use_driver_rate = true; | 692 | tcb_desc->use_driver_rate = true; |
515 | tcb_desc->ratr_index = 7; | 693 | tcb_desc->ratr_index = RATR_INX_WIRELESS_MC; |
516 | 694 | ||
517 | tcb_desc->hw_rate = | ||
518 | rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; | ||
519 | tcb_desc->disable_ratefallback = 1; | 695 | tcb_desc->disable_ratefallback = 1; |
520 | } else { | 696 | } else { |
521 | /* | 697 | /* |
@@ -525,7 +701,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, | |||
525 | *and N rate will all be controlled by FW | 701 | *and N rate will all be controlled by FW |
526 | *when tcb_desc->use_driver_rate = false | 702 | *when tcb_desc->use_driver_rate = false |
527 | */ | 703 | */ |
528 | if (rtlmac->ht_enable) { | 704 | if (sta && (sta->ht_cap.ht_supported)) { |
529 | tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw); | 705 | tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw); |
530 | } else { | 706 | } else { |
531 | if (rtlmac->mode == WIRELESS_MODE_B) { | 707 | if (rtlmac->mode == WIRELESS_MODE_B) { |
@@ -543,43 +719,25 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, | |||
543 | else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr))) | 719 | else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr))) |
544 | tcb_desc->broadcast = 1; | 720 | tcb_desc->broadcast = 1; |
545 | 721 | ||
546 | _rtl_txrate_selectmode(hw, tcb_desc); | 722 | _rtl_txrate_selectmode(hw, sta, tcb_desc); |
547 | _rtl_query_bandwidth_mode(hw, tcb_desc); | 723 | _rtl_query_bandwidth_mode(hw, sta, tcb_desc); |
548 | _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info); | 724 | _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info); |
549 | _rtl_query_shortgi(hw, tcb_desc, info); | 725 | _rtl_query_shortgi(hw, sta, tcb_desc, info); |
550 | _rtl_query_protection_mode(hw, tcb_desc, info); | 726 | _rtl_query_protection_mode(hw, tcb_desc, info); |
551 | } else { | 727 | } else { |
552 | tcb_desc->use_driver_rate = true; | 728 | tcb_desc->use_driver_rate = true; |
553 | tcb_desc->ratr_index = 7; | 729 | tcb_desc->ratr_index = RATR_INX_WIRELESS_MC; |
554 | tcb_desc->disable_ratefallback = 1; | 730 | tcb_desc->disable_ratefallback = 1; |
555 | tcb_desc->mac_id = 0; | 731 | tcb_desc->mac_id = 0; |
556 | 732 | tcb_desc->packet_bw = false; | |
557 | tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; | ||
558 | } | 733 | } |
559 | } | 734 | } |
560 | EXPORT_SYMBOL(rtl_get_tcb_desc); | 735 | EXPORT_SYMBOL(rtl_get_tcb_desc); |
561 | 736 | ||
562 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
563 | { | ||
564 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
565 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
566 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | ||
567 | __le16 fc = hdr->frame_control; | ||
568 | |||
569 | if (ieee80211_is_auth(fc)) { | ||
570 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); | ||
571 | rtl_ips_nic_on(hw); | ||
572 | |||
573 | mac->link_state = MAC80211_LINKING; | ||
574 | } | ||
575 | |||
576 | return true; | ||
577 | } | ||
578 | |||
579 | bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | 737 | bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) |
580 | { | 738 | { |
581 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 739 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
582 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 740 | struct ieee80211_hdr *hdr = rtl_get_hdr(skb); |
583 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 741 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
584 | __le16 fc = hdr->frame_control; | 742 | __le16 fc = hdr->frame_control; |
585 | u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); | 743 | u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); |
@@ -624,9 +782,8 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
624 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | 782 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) |
625 | { | 783 | { |
626 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 784 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
627 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | ||
628 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 785 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
629 | __le16 fc = hdr->frame_control; | 786 | __le16 fc = rtl_get_fc(skb); |
630 | u16 ether_type; | 787 | u16 ether_type; |
631 | u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb); | 788 | u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb); |
632 | const struct iphdr *ip; | 789 | const struct iphdr *ip; |
@@ -634,12 +791,11 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
634 | if (!ieee80211_is_data(fc)) | 791 | if (!ieee80211_is_data(fc)) |
635 | return false; | 792 | return false; |
636 | 793 | ||
637 | if (ieee80211_is_nullfunc(fc)) | ||
638 | return true; | ||
639 | 794 | ||
640 | ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + | 795 | ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + |
641 | SNAP_SIZE + PROTOC_TYPE_SIZE); | 796 | SNAP_SIZE + PROTOC_TYPE_SIZE); |
642 | ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); | 797 | ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); |
798 | /* ether_type = ntohs(ether_type); */ | ||
643 | 799 | ||
644 | if (ETH_P_IP == ether_type) { | 800 | if (ETH_P_IP == ether_type) { |
645 | if (IPPROTO_UDP == ip->protocol) { | 801 | if (IPPROTO_UDP == ip->protocol) { |
@@ -696,61 +852,92 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
696 | * functions called by core.c | 852 | * functions called by core.c |
697 | * | 853 | * |
698 | *********************************************************/ | 854 | *********************************************************/ |
699 | int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn) | 855 | int rtl_tx_agg_start(struct ieee80211_hw *hw, |
856 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | ||
700 | { | 857 | { |
701 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 858 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
702 | struct rtl_tid_data *tid_data; | 859 | struct rtl_tid_data *tid_data; |
703 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 860 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
861 | struct rtl_sta_info *sta_entry = NULL; | ||
704 | 862 | ||
705 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, | 863 | if (sta == NULL) |
706 | ("on ra = %pM tid = %d\n", ra, tid)); | 864 | return -EINVAL; |
707 | 865 | ||
708 | if (unlikely(tid >= MAX_TID_COUNT)) | 866 | if (unlikely(tid >= MAX_TID_COUNT)) |
709 | return -EINVAL; | 867 | return -EINVAL; |
710 | 868 | ||
711 | if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) { | 869 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; |
712 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 870 | if (!sta_entry) |
713 | ("Start AGG when state is not RTL_AGG_OFF !\n")); | ||
714 | return -ENXIO; | 871 | return -ENXIO; |
715 | } | 872 | tid_data = &sta_entry->tids[tid]; |
716 | |||
717 | tid_data = &mac->tids[tid]; | ||
718 | *ssn = SEQ_TO_SN(tid_data->seq_number); | ||
719 | 873 | ||
720 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, | 874 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, |
721 | ("HW queue is empty tid:%d\n", tid)); | 875 | ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid, |
722 | tid_data->agg.agg_state = RTL_AGG_ON; | 876 | tid_data->seq_number)); |
877 | |||
878 | *ssn = tid_data->seq_number; | ||
879 | tid_data->agg.agg_state = RTL_AGG_START; | ||
723 | 880 | ||
724 | ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid); | 881 | ieee80211_start_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid); |
725 | 882 | ||
726 | return 0; | 883 | return 0; |
727 | } | 884 | } |
728 | 885 | ||
729 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid) | 886 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, |
887 | struct ieee80211_sta *sta, u16 tid) | ||
730 | { | 888 | { |
731 | int ssn = -1; | ||
732 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 889 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
733 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 890 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
734 | struct rtl_tid_data *tid_data; | 891 | struct rtl_tid_data *tid_data; |
892 | struct rtl_sta_info *sta_entry = NULL; | ||
735 | 893 | ||
736 | if (!ra) { | 894 | if (sta == NULL) |
895 | return -EINVAL; | ||
896 | |||
897 | if (!sta->addr) { | ||
737 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); | 898 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); |
738 | return -EINVAL; | 899 | return -EINVAL; |
739 | } | 900 | } |
740 | 901 | ||
902 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, | ||
903 | ("on ra = %pM tid = %d\n", sta->addr, tid)); | ||
904 | |||
741 | if (unlikely(tid >= MAX_TID_COUNT)) | 905 | if (unlikely(tid >= MAX_TID_COUNT)) |
742 | return -EINVAL; | 906 | return -EINVAL; |
743 | 907 | ||
744 | if (mac->tids[tid].agg.agg_state != RTL_AGG_ON) | 908 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; |
745 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 909 | tid_data = &sta_entry->tids[tid]; |
746 | ("Stopping AGG while state not ON or starting\n")); | 910 | sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP; |
911 | |||
912 | ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid); | ||
913 | |||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | int rtl_tx_agg_oper(struct ieee80211_hw *hw, | ||
918 | struct ieee80211_sta *sta, u16 tid) | ||
919 | { | ||
920 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
921 | struct rtl_tid_data *tid_data; | ||
922 | struct rtl_sta_info *sta_entry = NULL; | ||
923 | |||
924 | if (sta == NULL) | ||
925 | return -EINVAL; | ||
926 | |||
927 | if (!sta->addr) { | ||
928 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); | ||
929 | return -EINVAL; | ||
930 | } | ||
747 | 931 | ||
748 | tid_data = &mac->tids[tid]; | 932 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, |
749 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; | 933 | ("on ra = %pM tid = %d\n", sta->addr, tid)); |
750 | 934 | ||
751 | mac->tids[tid].agg.agg_state = RTL_AGG_OFF; | 935 | if (unlikely(tid >= MAX_TID_COUNT)) |
936 | return -EINVAL; | ||
752 | 937 | ||
753 | ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid); | 938 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; |
939 | tid_data = &sta_entry->tids[tid]; | ||
940 | sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL; | ||
754 | 941 | ||
755 | return 0; | 942 | return 0; |
756 | } | 943 | } |
@@ -769,18 +956,16 @@ void rtl_watchdog_wq_callback(void *data) | |||
769 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 956 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
770 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 957 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
771 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 958 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
772 | |||
773 | bool busytraffic = false; | 959 | bool busytraffic = false; |
774 | bool higher_busytraffic = false; | 960 | bool higher_busytraffic = false; |
775 | bool higher_busyrxtraffic = false; | 961 | bool higher_busyrxtraffic = false; |
776 | bool higher_busytxtraffic = false; | 962 | u8 idx, tid; |
777 | |||
778 | u8 idx = 0; | ||
779 | u32 rx_cnt_inp4eriod = 0; | 963 | u32 rx_cnt_inp4eriod = 0; |
780 | u32 tx_cnt_inp4eriod = 0; | 964 | u32 tx_cnt_inp4eriod = 0; |
781 | u32 aver_rx_cnt_inperiod = 0; | 965 | u32 aver_rx_cnt_inperiod = 0; |
782 | u32 aver_tx_cnt_inperiod = 0; | 966 | u32 aver_tx_cnt_inperiod = 0; |
783 | 967 | u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0}; | |
968 | u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0}; | ||
784 | bool enter_ps = false; | 969 | bool enter_ps = false; |
785 | 970 | ||
786 | if (is_hal_stop(rtlhal)) | 971 | if (is_hal_stop(rtlhal)) |
@@ -794,9 +979,6 @@ void rtl_watchdog_wq_callback(void *data) | |||
794 | mac->cnt_after_linked = 0; | 979 | mac->cnt_after_linked = 0; |
795 | } | 980 | } |
796 | 981 | ||
797 | /* <2> DM */ | ||
798 | rtlpriv->cfg->ops->dm_watchdog(hw); | ||
799 | |||
800 | /* | 982 | /* |
801 | *<3> to check if traffic busy, if | 983 | *<3> to check if traffic busy, if |
802 | * busytraffic we don't change channel | 984 | * busytraffic we don't change channel |
@@ -835,8 +1017,27 @@ void rtl_watchdog_wq_callback(void *data) | |||
835 | /* Extremely high Rx data. */ | 1017 | /* Extremely high Rx data. */ |
836 | if (aver_rx_cnt_inperiod > 5000) | 1018 | if (aver_rx_cnt_inperiod > 5000) |
837 | higher_busyrxtraffic = true; | 1019 | higher_busyrxtraffic = true; |
1020 | } | ||
1021 | |||
1022 | /* check every tid's tx traffic */ | ||
1023 | for (tid = 0; tid <= 7; tid++) { | ||
1024 | for (idx = 0; idx <= 2; idx++) | ||
1025 | rtlpriv->link_info.tidtx_in4period[tid][idx] = | ||
1026 | rtlpriv->link_info.tidtx_in4period[tid] | ||
1027 | [idx + 1]; | ||
1028 | rtlpriv->link_info.tidtx_in4period[tid][3] = | ||
1029 | rtlpriv->link_info.tidtx_inperiod[tid]; | ||
1030 | |||
1031 | for (idx = 0; idx <= 3; idx++) | ||
1032 | tidtx_inp4eriod[tid] += | ||
1033 | rtlpriv->link_info.tidtx_in4period[tid][idx]; | ||
1034 | aver_tidtx_inperiod[tid] = tidtx_inp4eriod[tid] / 4; | ||
1035 | if (aver_tidtx_inperiod[tid] > 5000) | ||
1036 | rtlpriv->link_info.higher_busytxtraffic[tid] = | ||
1037 | true; | ||
838 | else | 1038 | else |
839 | higher_busytxtraffic = false; | 1039 | rtlpriv->link_info.higher_busytxtraffic[tid] = |
1040 | false; | ||
840 | } | 1041 | } |
841 | 1042 | ||
842 | if (((rtlpriv->link_info.num_rx_inperiod + | 1043 | if (((rtlpriv->link_info.num_rx_inperiod + |
@@ -855,11 +1056,15 @@ void rtl_watchdog_wq_callback(void *data) | |||
855 | 1056 | ||
856 | rtlpriv->link_info.num_rx_inperiod = 0; | 1057 | rtlpriv->link_info.num_rx_inperiod = 0; |
857 | rtlpriv->link_info.num_tx_inperiod = 0; | 1058 | rtlpriv->link_info.num_tx_inperiod = 0; |
1059 | for (tid = 0; tid <= 7; tid++) | ||
1060 | rtlpriv->link_info.tidtx_inperiod[tid] = 0; | ||
858 | 1061 | ||
859 | rtlpriv->link_info.busytraffic = busytraffic; | 1062 | rtlpriv->link_info.busytraffic = busytraffic; |
860 | rtlpriv->link_info.higher_busytraffic = higher_busytraffic; | 1063 | rtlpriv->link_info.higher_busytraffic = higher_busytraffic; |
861 | rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic; | 1064 | rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic; |
862 | 1065 | ||
1066 | /* <3> DM */ | ||
1067 | rtlpriv->cfg->ops->dm_watchdog(hw); | ||
863 | } | 1068 | } |
864 | 1069 | ||
865 | void rtl_watch_dog_timer_callback(unsigned long data) | 1070 | void rtl_watch_dog_timer_callback(unsigned long data) |
@@ -876,6 +1081,268 @@ void rtl_watch_dog_timer_callback(unsigned long data) | |||
876 | 1081 | ||
877 | /********************************************************* | 1082 | /********************************************************* |
878 | * | 1083 | * |
1084 | * frame process functions | ||
1085 | * | ||
1086 | *********************************************************/ | ||
1087 | u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie) | ||
1088 | { | ||
1089 | struct ieee80211_mgmt *mgmt = (void *)data; | ||
1090 | u8 *pos, *end; | ||
1091 | |||
1092 | pos = (u8 *)mgmt->u.beacon.variable; | ||
1093 | end = data + len; | ||
1094 | while (pos < end) { | ||
1095 | if (pos + 2 + pos[1] > end) | ||
1096 | return NULL; | ||
1097 | |||
1098 | if (pos[0] == ie) | ||
1099 | return pos; | ||
1100 | |||
1101 | pos += 2 + pos[1]; | ||
1102 | } | ||
1103 | return NULL; | ||
1104 | } | ||
1105 | |||
1106 | /* when we use 2 rx ants we send IEEE80211_SMPS_OFF */ | ||
1107 | /* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */ | ||
1108 | static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw, | ||
1109 | enum ieee80211_smps_mode smps, u8 *da, u8 *bssid) | ||
1110 | { | ||
1111 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1112 | struct sk_buff *skb; | ||
1113 | struct ieee80211_mgmt *action_frame; | ||
1114 | |||
1115 | /* 27 = header + category + action + smps mode */ | ||
1116 | skb = dev_alloc_skb(27 + hw->extra_tx_headroom); | ||
1117 | if (!skb) | ||
1118 | return NULL; | ||
1119 | |||
1120 | skb_reserve(skb, hw->extra_tx_headroom); | ||
1121 | action_frame = (void *)skb_put(skb, 27); | ||
1122 | memset(action_frame, 0, 27); | ||
1123 | memcpy(action_frame->da, da, ETH_ALEN); | ||
1124 | memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN); | ||
1125 | memcpy(action_frame->bssid, bssid, ETH_ALEN); | ||
1126 | action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
1127 | IEEE80211_STYPE_ACTION); | ||
1128 | action_frame->u.action.category = WLAN_CATEGORY_HT; | ||
1129 | action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS; | ||
1130 | switch (smps) { | ||
1131 | case IEEE80211_SMPS_AUTOMATIC:/* 0 */ | ||
1132 | case IEEE80211_SMPS_NUM_MODES:/* 4 */ | ||
1133 | WARN_ON(1); | ||
1134 | case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/ | ||
1135 | action_frame->u.action.u.ht_smps.smps_control = | ||
1136 | WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */ | ||
1137 | break; | ||
1138 | case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/ | ||
1139 | action_frame->u.action.u.ht_smps.smps_control = | ||
1140 | WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */ | ||
1141 | break; | ||
1142 | case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/ | ||
1143 | action_frame->u.action.u.ht_smps.smps_control = | ||
1144 | WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */ | ||
1145 | break; | ||
1146 | } | ||
1147 | |||
1148 | return skb; | ||
1149 | } | ||
1150 | |||
1151 | int rtl_send_smps_action(struct ieee80211_hw *hw, | ||
1152 | struct ieee80211_sta *sta, u8 *da, u8 *bssid, | ||
1153 | enum ieee80211_smps_mode smps) | ||
1154 | { | ||
1155 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1156 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1157 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1158 | struct sk_buff *skb = rtl_make_smps_action(hw, smps, da, bssid); | ||
1159 | struct rtl_tcb_desc tcb_desc; | ||
1160 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | ||
1161 | |||
1162 | if (rtlpriv->mac80211.act_scanning) | ||
1163 | goto err_free; | ||
1164 | |||
1165 | if (!sta) | ||
1166 | goto err_free; | ||
1167 | |||
1168 | if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) | ||
1169 | goto err_free; | ||
1170 | |||
1171 | if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) | ||
1172 | goto err_free; | ||
1173 | |||
1174 | /* this is a type = mgmt * stype = action frame */ | ||
1175 | if (skb) { | ||
1176 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1177 | struct rtl_sta_info *sta_entry = | ||
1178 | (struct rtl_sta_info *) sta->drv_priv; | ||
1179 | sta_entry->mimo_ps = smps; | ||
1180 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); | ||
1181 | |||
1182 | info->control.rates[0].idx = 0; | ||
1183 | info->control.sta = sta; | ||
1184 | info->band = hw->conf.channel->band; | ||
1185 | rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); | ||
1186 | } | ||
1187 | err_free: | ||
1188 | return 0; | ||
1189 | } | ||
1190 | |||
1191 | /********************************************************* | ||
1192 | * | ||
1193 | * IOT functions | ||
1194 | * | ||
1195 | *********************************************************/ | ||
1196 | static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw, | ||
1197 | struct octet_string vendor_ie) | ||
1198 | { | ||
1199 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1200 | bool matched = false; | ||
1201 | static u8 athcap_1[] = { 0x00, 0x03, 0x7F }; | ||
1202 | static u8 athcap_2[] = { 0x00, 0x13, 0x74 }; | ||
1203 | static u8 broadcap_1[] = { 0x00, 0x10, 0x18 }; | ||
1204 | static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 }; | ||
1205 | static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 }; | ||
1206 | static u8 racap[] = { 0x00, 0x0c, 0x43 }; | ||
1207 | static u8 ciscocap[] = { 0x00, 0x40, 0x96 }; | ||
1208 | static u8 marvcap[] = { 0x00, 0x50, 0x43 }; | ||
1209 | |||
1210 | if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 || | ||
1211 | memcmp(vendor_ie.octet, athcap_2, 3) == 0) { | ||
1212 | rtlpriv->mac80211.vendor = PEER_ATH; | ||
1213 | matched = true; | ||
1214 | } else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 || | ||
1215 | memcmp(vendor_ie.octet, broadcap_2, 3) == 0 || | ||
1216 | memcmp(vendor_ie.octet, broadcap_3, 3) == 0) { | ||
1217 | rtlpriv->mac80211.vendor = PEER_BROAD; | ||
1218 | matched = true; | ||
1219 | } else if (memcmp(vendor_ie.octet, racap, 3) == 0) { | ||
1220 | rtlpriv->mac80211.vendor = PEER_RAL; | ||
1221 | matched = true; | ||
1222 | } else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) { | ||
1223 | rtlpriv->mac80211.vendor = PEER_CISCO; | ||
1224 | matched = true; | ||
1225 | } else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) { | ||
1226 | rtlpriv->mac80211.vendor = PEER_MARV; | ||
1227 | matched = true; | ||
1228 | } | ||
1229 | |||
1230 | return matched; | ||
1231 | } | ||
1232 | |||
1233 | static bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data, | ||
1234 | unsigned int len) | ||
1235 | { | ||
1236 | struct ieee80211_mgmt *mgmt = (void *)data; | ||
1237 | struct octet_string vendor_ie; | ||
1238 | u8 *pos, *end; | ||
1239 | |||
1240 | pos = (u8 *)mgmt->u.beacon.variable; | ||
1241 | end = data + len; | ||
1242 | while (pos < end) { | ||
1243 | if (pos[0] == 221) { | ||
1244 | vendor_ie.length = pos[1]; | ||
1245 | vendor_ie.octet = &pos[2]; | ||
1246 | if (rtl_chk_vendor_ouisub(hw, vendor_ie)) | ||
1247 | return true; | ||
1248 | } | ||
1249 | |||
1250 | if (pos + 2 + pos[1] > end) | ||
1251 | return false; | ||
1252 | |||
1253 | pos += 2 + pos[1]; | ||
1254 | } | ||
1255 | return false; | ||
1256 | } | ||
1257 | |||
1258 | void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) | ||
1259 | { | ||
1260 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1261 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1262 | struct ieee80211_hdr *hdr = (void *)data; | ||
1263 | u32 vendor = PEER_UNKNOWN; | ||
1264 | |||
1265 | static u8 ap3_1[3] = { 0x00, 0x14, 0xbf }; | ||
1266 | static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 }; | ||
1267 | static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e }; | ||
1268 | static u8 ap4_1[3] = { 0x00, 0x90, 0xcc }; | ||
1269 | static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e }; | ||
1270 | static u8 ap4_3[3] = { 0x00, 0x18, 0x02 }; | ||
1271 | static u8 ap4_4[3] = { 0x00, 0x17, 0x3f }; | ||
1272 | static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf }; | ||
1273 | static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 }; | ||
1274 | static u8 ap5_2[3] = { 0x00, 0x21, 0x91 }; | ||
1275 | static u8 ap5_3[3] = { 0x00, 0x24, 0x01 }; | ||
1276 | static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 }; | ||
1277 | static u8 ap5_5[3] = { 0x00, 0x17, 0x9A }; | ||
1278 | static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 }; | ||
1279 | static u8 ap6_1[3] = { 0x00, 0x17, 0x94 }; | ||
1280 | static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 }; | ||
1281 | |||
1282 | if (mac->opmode != NL80211_IFTYPE_STATION) | ||
1283 | return; | ||
1284 | |||
1285 | if (mac->link_state == MAC80211_NOLINK) { | ||
1286 | mac->vendor = PEER_UNKNOWN; | ||
1287 | return; | ||
1288 | } | ||
1289 | |||
1290 | if (mac->cnt_after_linked > 2) | ||
1291 | return; | ||
1292 | |||
1293 | /* check if this really is a beacon */ | ||
1294 | if (!ieee80211_is_beacon(hdr->frame_control)) | ||
1295 | return; | ||
1296 | |||
1297 | /* min. beacon length + FCS_LEN */ | ||
1298 | if (len <= 40 + FCS_LEN) | ||
1299 | return; | ||
1300 | |||
1301 | /* and only beacons from the associated BSSID, please */ | ||
1302 | if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid)) | ||
1303 | return; | ||
1304 | |||
1305 | if (rtl_find_221_ie(hw, data, len)) | ||
1306 | vendor = mac->vendor; | ||
1307 | |||
1308 | if ((memcmp(mac->bssid, ap5_1, 3) == 0) || | ||
1309 | (memcmp(mac->bssid, ap5_2, 3) == 0) || | ||
1310 | (memcmp(mac->bssid, ap5_3, 3) == 0) || | ||
1311 | (memcmp(mac->bssid, ap5_4, 3) == 0) || | ||
1312 | (memcmp(mac->bssid, ap5_5, 3) == 0) || | ||
1313 | (memcmp(mac->bssid, ap5_6, 3) == 0) || | ||
1314 | vendor == PEER_ATH) { | ||
1315 | vendor = PEER_ATH; | ||
1316 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n")); | ||
1317 | } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || | ||
1318 | (memcmp(mac->bssid, ap4_5, 3) == 0) || | ||
1319 | (memcmp(mac->bssid, ap4_1, 3) == 0) || | ||
1320 | (memcmp(mac->bssid, ap4_2, 3) == 0) || | ||
1321 | (memcmp(mac->bssid, ap4_3, 3) == 0) || | ||
1322 | vendor == PEER_RAL) { | ||
1323 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n")); | ||
1324 | vendor = PEER_RAL; | ||
1325 | } else if (memcmp(mac->bssid, ap6_1, 3) == 0 || | ||
1326 | vendor == PEER_CISCO) { | ||
1327 | vendor = PEER_CISCO; | ||
1328 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n")); | ||
1329 | } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || | ||
1330 | (memcmp(mac->bssid, ap3_2, 3) == 0) || | ||
1331 | (memcmp(mac->bssid, ap3_3, 3) == 0) || | ||
1332 | vendor == PEER_BROAD) { | ||
1333 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n")); | ||
1334 | vendor = PEER_BROAD; | ||
1335 | } else if (memcmp(mac->bssid, ap7_1, 3) == 0 || | ||
1336 | vendor == PEER_MARV) { | ||
1337 | vendor = PEER_MARV; | ||
1338 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n")); | ||
1339 | } | ||
1340 | |||
1341 | mac->vendor = vendor; | ||
1342 | } | ||
1343 | |||
1344 | /********************************************************* | ||
1345 | * | ||
879 | * sysfs functions | 1346 | * sysfs functions |
880 | * | 1347 | * |
881 | *********************************************************/ | 1348 | *********************************************************/ |
@@ -941,12 +1408,13 @@ static int __init rtl_core_module_init(void) | |||
941 | if (rtl_rate_control_register()) | 1408 | if (rtl_rate_control_register()) |
942 | printk(KERN_ERR "rtlwifi: Unable to register rtl_rc," | 1409 | printk(KERN_ERR "rtlwifi: Unable to register rtl_rc," |
943 | "use default RC !!\n"); | 1410 | "use default RC !!\n"); |
1411 | |||
944 | return 0; | 1412 | return 0; |
945 | } | 1413 | } |
946 | 1414 | ||
947 | static void __exit rtl_core_module_exit(void) | 1415 | static void __exit rtl_core_module_exit(void) |
948 | { | 1416 | { |
949 | /*RC*/ | 1417 | /*RC*/ |
950 | rtl_rate_control_unregister(); | 1418 | rtl_rate_control_unregister(); |
951 | } | 1419 | } |
952 | 1420 | ||
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index 043045342bc7..a91f3eee59c8 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h | |||
@@ -24,13 +24,26 @@ | |||
24 | * Hsinchu 300, Taiwan. | 24 | * Hsinchu 300, Taiwan. |
25 | * | 25 | * |
26 | * Larry Finger <Larry.Finger@lwfinger.net> | 26 | * Larry Finger <Larry.Finger@lwfinger.net> |
27 | * | ||
27 | *****************************************************************************/ | 28 | *****************************************************************************/ |
28 | 29 | ||
29 | #ifndef __RTL_BASE_H__ | 30 | #ifndef __RTL_BASE_H__ |
30 | #define __RTL_BASE_H__ | 31 | #define __RTL_BASE_H__ |
31 | 32 | ||
33 | enum ap_peer { | ||
34 | PEER_UNKNOWN = 0, | ||
35 | PEER_RTL = 1, | ||
36 | PEER_RTL_92SE = 2, | ||
37 | PEER_BROAD = 3, | ||
38 | PEER_RAL = 4, | ||
39 | PEER_ATH = 5, | ||
40 | PEER_CISCO = 6, | ||
41 | PEER_MARV = 7, | ||
42 | PEER_AIRGO = 9, | ||
43 | PEER_MAX = 10, | ||
44 | } ; | ||
45 | |||
32 | #define RTL_DUMMY_OFFSET 0 | 46 | #define RTL_DUMMY_OFFSET 0 |
33 | #define RTL_RX_DESC_SIZE 24 | ||
34 | #define RTL_DUMMY_UNIT 8 | 47 | #define RTL_DUMMY_UNIT 8 |
35 | #define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) | 48 | #define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) |
36 | #define RTL_TX_DESC_SIZE 32 | 49 | #define RTL_TX_DESC_SIZE 32 |
@@ -53,6 +66,14 @@ | |||
53 | #define FRAME_OFFSET_SEQUENCE 22 | 66 | #define FRAME_OFFSET_SEQUENCE 22 |
54 | #define FRAME_OFFSET_ADDRESS4 24 | 67 | #define FRAME_OFFSET_ADDRESS4 24 |
55 | 68 | ||
69 | #define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \ | ||
70 | WRITEEF2BYTE(_hdr, _val) | ||
71 | #define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \ | ||
72 | WRITEEF1BYTE(_hdr, _val) | ||
73 | #define SET_80211_HDR_PWR_MGNT(_hdr, _val) \ | ||
74 | SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val) | ||
75 | #define SET_80211_HDR_TO_DS(_hdr, _val) \ | ||
76 | SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val) | ||
56 | 77 | ||
57 | #define SET_80211_PS_POLL_AID(_hdr, _val) \ | 78 | #define SET_80211_PS_POLL_AID(_hdr, _val) \ |
58 | (*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val)) | 79 | (*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val)) |
@@ -64,11 +85,27 @@ | |||
64 | #define SET_80211_HDR_DURATION(_hdr, _val) \ | 85 | #define SET_80211_HDR_DURATION(_hdr, _val) \ |
65 | (*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val)) | 86 | (*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val)) |
66 | #define SET_80211_HDR_ADDRESS1(_hdr, _val) \ | 87 | #define SET_80211_HDR_ADDRESS1(_hdr, _val) \ |
67 | memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val), ETH_ALEN) | 88 | CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8 *)(_val)) |
68 | #define SET_80211_HDR_ADDRESS2(_hdr, _val) \ | 89 | #define SET_80211_HDR_ADDRESS2(_hdr, _val) \ |
69 | memcpy((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val), ETH_ALEN) | 90 | CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS2, (u8 *)(_val)) |
70 | #define SET_80211_HDR_ADDRESS3(_hdr, _val) \ | 91 | #define SET_80211_HDR_ADDRESS3(_hdr, _val) \ |
71 | memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val), ETH_ALEN) | 92 | CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val)) |
93 | #define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \ | ||
94 | WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val) | ||
95 | |||
96 | #define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \ | ||
97 | WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val) | ||
98 | #define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \ | ||
99 | WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val) | ||
100 | #define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \ | ||
101 | WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val) | ||
102 | #define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \ | ||
103 | READEF2BYTE(((u8 *)(__phdr)) + 34) | ||
104 | #define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ | ||
105 | WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val) | ||
106 | #define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ | ||
107 | SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \ | ||
108 | (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val)))) | ||
72 | 109 | ||
73 | int rtl_init_core(struct ieee80211_hw *hw); | 110 | int rtl_init_core(struct ieee80211_hw *hw); |
74 | void rtl_deinit_core(struct ieee80211_hw *hw); | 111 | void rtl_deinit_core(struct ieee80211_hw *hw); |
@@ -80,18 +117,27 @@ void rtl_watch_dog_timer_callback(unsigned long data); | |||
80 | void rtl_deinit_deferred_work(struct ieee80211_hw *hw); | 117 | void rtl_deinit_deferred_work(struct ieee80211_hw *hw); |
81 | 118 | ||
82 | bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); | 119 | bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); |
83 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
84 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); | 120 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); |
85 | 121 | ||
86 | void rtl_watch_dog_timer_callback(unsigned long data); | 122 | void rtl_watch_dog_timer_callback(unsigned long data); |
87 | int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, | 123 | int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_sta *sta, |
88 | u16 tid, u16 *ssn); | 124 | u16 tid, u16 *ssn); |
89 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid); | 125 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_sta *sta, |
126 | u16 tid); | ||
127 | int rtl_tx_agg_oper(struct ieee80211_hw *hw, struct ieee80211_sta *sta, | ||
128 | u16 tid); | ||
90 | void rtl_watchdog_wq_callback(void *data); | 129 | void rtl_watchdog_wq_callback(void *data); |
91 | 130 | ||
92 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, | 131 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, |
93 | struct ieee80211_tx_info *info, | 132 | struct ieee80211_tx_info *info, |
133 | struct ieee80211_sta *sta, | ||
94 | struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc); | 134 | struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc); |
95 | 135 | ||
136 | int rtl_send_smps_action(struct ieee80211_hw *hw, | ||
137 | struct ieee80211_sta *sta, u8 *da, u8 *bssid, | ||
138 | enum ieee80211_smps_mode smps); | ||
139 | u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); | ||
140 | void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); | ||
141 | u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid); | ||
96 | extern struct attribute_group rtl_attribute_group; | 142 | extern struct attribute_group rtl_attribute_group; |
97 | #endif | 143 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 52c9c1367cac..7295af0536b7 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c | |||
@@ -23,6 +23,8 @@ | |||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | 23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, |
24 | * Hsinchu 300, Taiwan. | 24 | * Hsinchu 300, Taiwan. |
25 | * | 25 | * |
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
26 | *****************************************************************************/ | 28 | *****************************************************************************/ |
27 | 29 | ||
28 | #include "wifi.h" | 30 | #include "wifi.h" |
@@ -49,7 +51,7 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, | |||
49 | u32 target_content = 0; | 51 | u32 target_content = 0; |
50 | u8 entry_i; | 52 | u8 entry_i; |
51 | 53 | ||
52 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 54 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
53 | ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n", | 55 | ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n", |
54 | key_cont_128[0], key_cont_128[1], | 56 | key_cont_128[0], key_cont_128[1], |
55 | key_cont_128[2], key_cont_128[3], | 57 | key_cont_128[2], key_cont_128[3], |
@@ -68,15 +70,13 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, | |||
68 | rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], | 70 | rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], |
69 | target_command); | 71 | target_command); |
70 | 72 | ||
71 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 73 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
72 | ("rtl_cam_program_entry(): " | 74 | ("WRITE %x: %x\n", |
73 | "WRITE %x: %x\n", | ||
74 | rtlpriv->cfg->maps[WCAMI], target_content)); | 75 | rtlpriv->cfg->maps[WCAMI], target_content)); |
75 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 76 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
76 | ("The Key ID is %d\n", entry_no)); | 77 | ("The Key ID is %d\n", entry_no)); |
77 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 78 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
78 | ("rtl_cam_program_entry(): " | 79 | ("WRITE %x: %x\n", |
79 | "WRITE %x: %x\n", | ||
80 | rtlpriv->cfg->maps[RWCAM], target_command)); | 80 | rtlpriv->cfg->maps[RWCAM], target_command)); |
81 | 81 | ||
82 | } else if (entry_i == 1) { | 82 | } else if (entry_i == 1) { |
@@ -91,12 +91,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, | |||
91 | rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], | 91 | rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], |
92 | target_command); | 92 | target_command); |
93 | 93 | ||
94 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 94 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
95 | ("rtl_cam_program_entry(): WRITE A4: %x\n", | 95 | ("WRITE A4: %x\n", target_content)); |
96 | target_content)); | 96 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
97 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 97 | ("WRITE A0: %x\n", target_command)); |
98 | ("rtl_cam_program_entry(): WRITE A0: %x\n", | ||
99 | target_command)); | ||
100 | 98 | ||
101 | } else { | 99 | } else { |
102 | 100 | ||
@@ -113,16 +111,14 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, | |||
113 | target_command); | 111 | target_command); |
114 | udelay(100); | 112 | udelay(100); |
115 | 113 | ||
116 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 114 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
117 | ("rtl_cam_program_entry(): WRITE A4: %x\n", | 115 | ("WRITE A4: %x\n", target_content)); |
118 | target_content)); | 116 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
119 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 117 | ("WRITE A0: %x\n", target_command)); |
120 | ("rtl_cam_program_entry(): WRITE A0: %x\n", | ||
121 | target_command)); | ||
122 | } | 118 | } |
123 | } | 119 | } |
124 | 120 | ||
125 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 121 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
126 | ("after set key, usconfig:%x\n", us_config)); | 122 | ("after set key, usconfig:%x\n", us_config)); |
127 | } | 123 | } |
128 | 124 | ||
@@ -289,3 +285,71 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) | |||
289 | 285 | ||
290 | } | 286 | } |
291 | EXPORT_SYMBOL(rtl_cam_empty_entry); | 287 | EXPORT_SYMBOL(rtl_cam_empty_entry); |
288 | |||
289 | u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) | ||
290 | { | ||
291 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
292 | u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4; | ||
293 | u8 entry_idx = 0; | ||
294 | u8 i, *addr; | ||
295 | |||
296 | if (NULL == sta_addr) { | ||
297 | RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, | ||
298 | ("sta_addr is NULL.\n")); | ||
299 | return TOTAL_CAM_ENTRY; | ||
300 | } | ||
301 | /* Does STA already exist? */ | ||
302 | for (i = 4; i < TOTAL_CAM_ENTRY; i++) { | ||
303 | addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; | ||
304 | if (memcmp(addr, sta_addr, ETH_ALEN) == 0) | ||
305 | return i; | ||
306 | } | ||
307 | /* Get a free CAM entry. */ | ||
308 | for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) { | ||
309 | if ((bitmap & BIT(0)) == 0) { | ||
310 | RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, | ||
311 | ("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", | ||
312 | rtlpriv->sec.hwsec_cam_bitmap, entry_idx)); | ||
313 | rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx; | ||
314 | memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx], | ||
315 | sta_addr, ETH_ALEN); | ||
316 | return entry_idx; | ||
317 | } | ||
318 | bitmap = bitmap >> 1; | ||
319 | } | ||
320 | return TOTAL_CAM_ENTRY; | ||
321 | } | ||
322 | EXPORT_SYMBOL(rtl_cam_get_free_entry); | ||
323 | |||
324 | void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) | ||
325 | { | ||
326 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
327 | u32 bitmap; | ||
328 | u8 i, *addr; | ||
329 | |||
330 | if (NULL == sta_addr) { | ||
331 | RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, | ||
332 | ("sta_addr is NULL.\n")); | ||
333 | } | ||
334 | |||
335 | if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\ | ||
336 | sta_addr[4]|sta_addr[5]) == 0) { | ||
337 | RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, | ||
338 | ("sta_addr is 00:00:00:00:00:00.\n")); | ||
339 | return; | ||
340 | } | ||
341 | /* Does STA already exist? */ | ||
342 | for (i = 4; i < TOTAL_CAM_ENTRY; i++) { | ||
343 | addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; | ||
344 | bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i; | ||
345 | if (((bitmap & BIT(0)) == BIT(0)) && | ||
346 | (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { | ||
347 | /* Remove from HW Security CAM */ | ||
348 | memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN); | ||
349 | rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); | ||
350 | printk(KERN_INFO "&&&&&&&&&del entry %d\n", i); | ||
351 | } | ||
352 | } | ||
353 | return; | ||
354 | } | ||
355 | EXPORT_SYMBOL(rtl_cam_del_entry); | ||
diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h index dd82f057d53d..c62da4eefc75 100644 --- a/drivers/net/wireless/rtlwifi/cam.h +++ b/drivers/net/wireless/rtlwifi/cam.h | |||
@@ -23,12 +23,13 @@ | |||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | 23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, |
24 | * Hsinchu 300, Taiwan. | 24 | * Hsinchu 300, Taiwan. |
25 | * | 25 | * |
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
26 | *****************************************************************************/ | 28 | *****************************************************************************/ |
27 | 29 | ||
28 | #ifndef __RTL_CAM_H_ | 30 | #ifndef __RTL_CAM_H_ |
29 | #define __RTL_CAM_H_ | 31 | #define __RTL_CAM_H_ |
30 | 32 | ||
31 | #define TOTAL_CAM_ENTRY 32 | ||
32 | #define CAM_CONTENT_COUNT 8 | 33 | #define CAM_CONTENT_COUNT 8 |
33 | 34 | ||
34 | #define CFG_DEFAULT_KEY BIT(5) | 35 | #define CFG_DEFAULT_KEY BIT(5) |
@@ -49,5 +50,7 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, | |||
49 | void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index); | 50 | void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index); |
50 | void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index); | 51 | void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index); |
51 | void rtl_cam_reset_sec_info(struct ieee80211_hw *hw); | 52 | void rtl_cam_reset_sec_info(struct ieee80211_hw *hw); |
53 | u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr); | ||
54 | void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr); | ||
52 | 55 | ||
53 | #endif | 56 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 8fed3c687619..fc89cd8c8320 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
@@ -24,6 +24,7 @@ | |||
24 | * Hsinchu 300, Taiwan. | 24 | * Hsinchu 300, Taiwan. |
25 | * | 25 | * |
26 | * Larry Finger <Larry.Finger@lwfinger.net> | 26 | * Larry Finger <Larry.Finger@lwfinger.net> |
27 | * | ||
27 | *****************************************************************************/ | 28 | *****************************************************************************/ |
28 | 29 | ||
29 | #include "wifi.h" | 30 | #include "wifi.h" |
@@ -70,6 +71,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw) | |||
70 | 71 | ||
71 | mac->link_state = MAC80211_NOLINK; | 72 | mac->link_state = MAC80211_NOLINK; |
72 | memset(mac->bssid, 0, 6); | 73 | memset(mac->bssid, 0, 6); |
74 | mac->vendor = PEER_UNKNOWN; | ||
73 | 75 | ||
74 | /*reset sec info */ | 76 | /*reset sec info */ |
75 | rtl_cam_reset_sec_info(hw); | 77 | rtl_cam_reset_sec_info(hw); |
@@ -85,6 +87,8 @@ static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
85 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 87 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
86 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 88 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
87 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 89 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
90 | struct rtl_tcb_desc tcb_desc; | ||
91 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | ||
88 | 92 | ||
89 | if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) | 93 | if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) |
90 | goto err_free; | 94 | goto err_free; |
@@ -92,8 +96,8 @@ static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
92 | if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) | 96 | if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) |
93 | goto err_free; | 97 | goto err_free; |
94 | 98 | ||
95 | 99 | if (!rtlpriv->intf_ops->waitq_insert(hw, skb)) | |
96 | rtlpriv->intf_ops->adapter_tx(hw, skb); | 100 | rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); |
97 | 101 | ||
98 | return; | 102 | return; |
99 | 103 | ||
@@ -134,10 +138,26 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, | |||
134 | 138 | ||
135 | mac->link_state = MAC80211_LINKED; | 139 | mac->link_state = MAC80211_LINKED; |
136 | rtlpriv->cfg->ops->set_bcn_reg(hw); | 140 | rtlpriv->cfg->ops->set_bcn_reg(hw); |
141 | if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) | ||
142 | mac->basic_rates = 0xfff; | ||
143 | else | ||
144 | mac->basic_rates = 0xff0; | ||
145 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, | ||
146 | (u8 *) (&mac->basic_rates)); | ||
147 | |||
137 | break; | 148 | break; |
138 | case NL80211_IFTYPE_AP: | 149 | case NL80211_IFTYPE_AP: |
139 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, | 150 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, |
140 | ("NL80211_IFTYPE_AP\n")); | 151 | ("NL80211_IFTYPE_AP\n")); |
152 | |||
153 | mac->link_state = MAC80211_LINKED; | ||
154 | rtlpriv->cfg->ops->set_bcn_reg(hw); | ||
155 | if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) | ||
156 | mac->basic_rates = 0xfff; | ||
157 | else | ||
158 | mac->basic_rates = 0xff0; | ||
159 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, | ||
160 | (u8 *) (&mac->basic_rates)); | ||
141 | break; | 161 | break; |
142 | default: | 162 | default: |
143 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 163 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
@@ -184,13 +204,12 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw, | |||
184 | mac->vif = NULL; | 204 | mac->vif = NULL; |
185 | mac->link_state = MAC80211_NOLINK; | 205 | mac->link_state = MAC80211_NOLINK; |
186 | memset(mac->bssid, 0, 6); | 206 | memset(mac->bssid, 0, 6); |
207 | mac->vendor = PEER_UNKNOWN; | ||
187 | mac->opmode = NL80211_IFTYPE_UNSPECIFIED; | 208 | mac->opmode = NL80211_IFTYPE_UNSPECIFIED; |
188 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); | 209 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); |
189 | |||
190 | mutex_unlock(&rtlpriv->locks.conf_mutex); | 210 | mutex_unlock(&rtlpriv->locks.conf_mutex); |
191 | } | 211 | } |
192 | 212 | ||
193 | |||
194 | static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | 213 | static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) |
195 | { | 214 | { |
196 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 215 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -222,10 +241,25 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
222 | 241 | ||
223 | /*For LPS */ | 242 | /*For LPS */ |
224 | if (changed & IEEE80211_CONF_CHANGE_PS) { | 243 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
225 | if (conf->flags & IEEE80211_CONF_PS) | 244 | cancel_delayed_work(&rtlpriv->works.ps_work); |
226 | rtl_lps_enter(hw); | 245 | cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); |
227 | else | 246 | if (conf->flags & IEEE80211_CONF_PS) { |
228 | rtl_lps_leave(hw); | 247 | rtlpriv->psc.sw_ps_enabled = true; |
248 | /* sleep here is must, or we may recv the beacon and | ||
249 | * cause mac80211 into wrong ps state, this will cause | ||
250 | * power save nullfunc send fail, and further cause | ||
251 | * pkt loss, So sleep must quickly but not immediatly | ||
252 | * because that will cause nullfunc send by mac80211 | ||
253 | * fail, and cause pkt loss, we have tested that 5mA | ||
254 | * is worked very well */ | ||
255 | if (!rtlpriv->psc.multi_buffered) | ||
256 | queue_delayed_work(rtlpriv->works.rtl_wq, | ||
257 | &rtlpriv->works.ps_work, | ||
258 | MSECS(5)); | ||
259 | } else { | ||
260 | rtl_swlps_rf_awake(hw); | ||
261 | rtlpriv->psc.sw_ps_enabled = false; | ||
262 | } | ||
229 | } | 263 | } |
230 | 264 | ||
231 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { | 265 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { |
@@ -257,7 +291,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
257 | case NL80211_CHAN_NO_HT: | 291 | case NL80211_CHAN_NO_HT: |
258 | /* SC */ | 292 | /* SC */ |
259 | mac->cur_40_prime_sc = | 293 | mac->cur_40_prime_sc = |
260 | PRIME_CHNL_OFFSET_DONT_CARE; | 294 | PRIME_CHNL_OFFSET_DONT_CARE; |
261 | rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20; | 295 | rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20; |
262 | mac->bw_40 = false; | 296 | mac->bw_40 = false; |
263 | break; | 297 | break; |
@@ -265,7 +299,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
265 | /* SC */ | 299 | /* SC */ |
266 | mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER; | 300 | mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER; |
267 | rtlphy->current_chan_bw = | 301 | rtlphy->current_chan_bw = |
268 | HT_CHANNEL_WIDTH_20_40; | 302 | HT_CHANNEL_WIDTH_20_40; |
269 | mac->bw_40 = true; | 303 | mac->bw_40 = true; |
270 | 304 | ||
271 | /*wide channel */ | 305 | /*wide channel */ |
@@ -276,7 +310,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
276 | /* SC */ | 310 | /* SC */ |
277 | mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER; | 311 | mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER; |
278 | rtlphy->current_chan_bw = | 312 | rtlphy->current_chan_bw = |
279 | HT_CHANNEL_WIDTH_20_40; | 313 | HT_CHANNEL_WIDTH_20_40; |
280 | mac->bw_40 = true; | 314 | mac->bw_40 = true; |
281 | 315 | ||
282 | /*wide channel */ | 316 | /*wide channel */ |
@@ -286,16 +320,29 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) | |||
286 | default: | 320 | default: |
287 | mac->bw_40 = false; | 321 | mac->bw_40 = false; |
288 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 322 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
289 | ("switch case not processed\n")); | 323 | ("switch case not processed\n")); |
290 | break; | 324 | break; |
291 | } | 325 | } |
292 | 326 | ||
293 | if (wide_chan <= 0) | 327 | if (wide_chan <= 0) |
294 | wide_chan = 1; | 328 | wide_chan = 1; |
329 | |||
330 | /* In scanning, before we go offchannel we may send a ps=1 null | ||
331 | * to AP, and then we may send a ps = 0 null to AP quickly, but | ||
332 | * first null may have caused AP to put lots of packet to hw tx | ||
333 | * buffer. These packets must be tx'd before we go off channel | ||
334 | * so we must delay more time to let AP flush these packets | ||
335 | * before going offchannel, or dis-association or delete BA will | ||
336 | * happen by AP | ||
337 | */ | ||
338 | if (rtlpriv->mac80211.offchan_deley) { | ||
339 | rtlpriv->mac80211.offchan_deley = false; | ||
340 | mdelay(50); | ||
341 | } | ||
295 | rtlphy->current_channel = wide_chan; | 342 | rtlphy->current_channel = wide_chan; |
296 | 343 | ||
297 | rtlpriv->cfg->ops->set_channel_access(hw); | ||
298 | rtlpriv->cfg->ops->switch_channel(hw); | 344 | rtlpriv->cfg->ops->switch_channel(hw); |
345 | rtlpriv->cfg->ops->set_channel_access(hw); | ||
299 | rtlpriv->cfg->ops->set_bw_mode(hw, | 346 | rtlpriv->cfg->ops->set_bw_mode(hw, |
300 | hw->conf.channel_type); | 347 | hw->conf.channel_type); |
301 | } | 348 | } |
@@ -343,27 +390,28 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, | |||
343 | } | 390 | } |
344 | } | 391 | } |
345 | 392 | ||
346 | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { | 393 | /* if ssid not set to hw don't check bssid |
347 | /* | 394 | * here just used for linked scanning, & linked |
348 | *TODO: BIT(5) is probe response BIT(8) is beacon | 395 | * and nolink check bssid is set in set network_type */ |
349 | *TODO: Use define for BIT(5) and BIT(8) | 396 | if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) && |
350 | */ | 397 | (mac->link_state >= MAC80211_LINKED)) { |
351 | if (*new_flags & FIF_BCN_PRBRESP_PROMISC) | 398 | if (mac->opmode != NL80211_IFTYPE_AP) { |
352 | mac->rx_mgt_filter |= (BIT(5) | BIT(8)); | 399 | if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { |
353 | else | 400 | rtlpriv->cfg->ops->set_chk_bssid(hw, false); |
354 | mac->rx_mgt_filter &= ~(BIT(5) | BIT(8)); | 401 | } else { |
402 | rtlpriv->cfg->ops->set_chk_bssid(hw, true); | ||
403 | } | ||
404 | } | ||
355 | } | 405 | } |
356 | 406 | ||
357 | if (changed_flags & FIF_CONTROL) { | 407 | if (changed_flags & FIF_CONTROL) { |
358 | if (*new_flags & FIF_CONTROL) { | 408 | if (*new_flags & FIF_CONTROL) { |
359 | mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; | 409 | mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; |
360 | mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER; | ||
361 | 410 | ||
362 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, | 411 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, |
363 | ("Enable receive control frame.\n")); | 412 | ("Enable receive control frame.\n")); |
364 | } else { | 413 | } else { |
365 | mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; | 414 | mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; |
366 | mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER; | ||
367 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, | 415 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, |
368 | ("Disable receive control frame.\n")); | 416 | ("Disable receive control frame.\n")); |
369 | } | 417 | } |
@@ -380,14 +428,54 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, | |||
380 | ("Disable receive other BSS's frame.\n")); | 428 | ("Disable receive other BSS's frame.\n")); |
381 | } | 429 | } |
382 | } | 430 | } |
383 | |||
384 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); | ||
385 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER, | ||
386 | (u8 *) (&mac->rx_mgt_filter)); | ||
387 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER, | ||
388 | (u8 *) (&mac->rx_ctrl_filter)); | ||
389 | } | 431 | } |
432 | static int rtl_op_sta_add(struct ieee80211_hw *hw, | ||
433 | struct ieee80211_vif *vif, | ||
434 | struct ieee80211_sta *sta) | ||
435 | { | ||
436 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
437 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
438 | struct rtl_sta_info *sta_entry; | ||
439 | |||
440 | if (sta) { | ||
441 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
442 | if (rtlhal->current_bandtype == BAND_ON_2_4G) { | ||
443 | sta_entry->wireless_mode = WIRELESS_MODE_G; | ||
444 | if (sta->supp_rates[0] <= 0xf) | ||
445 | sta_entry->wireless_mode = WIRELESS_MODE_B; | ||
446 | if (sta->ht_cap.ht_supported == true) | ||
447 | sta_entry->wireless_mode = WIRELESS_MODE_N_24G; | ||
448 | } else if (rtlhal->current_bandtype == BAND_ON_5G) { | ||
449 | sta_entry->wireless_mode = WIRELESS_MODE_A; | ||
450 | if (sta->ht_cap.ht_supported == true) | ||
451 | sta_entry->wireless_mode = WIRELESS_MODE_N_24G; | ||
452 | } | ||
453 | |||
454 | /* I found some times mac80211 give wrong supp_rates for adhoc*/ | ||
455 | if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) | ||
456 | sta_entry->wireless_mode = WIRELESS_MODE_G; | ||
390 | 457 | ||
458 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | ||
459 | ("Add sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr))); | ||
460 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); | ||
461 | } | ||
462 | return 0; | ||
463 | } | ||
464 | static int rtl_op_sta_remove(struct ieee80211_hw *hw, | ||
465 | struct ieee80211_vif *vif, | ||
466 | struct ieee80211_sta *sta) | ||
467 | { | ||
468 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
469 | struct rtl_sta_info *sta_entry; | ||
470 | if (sta) { | ||
471 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | ||
472 | ("Remove sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr))); | ||
473 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
474 | sta_entry->wireless_mode = 0; | ||
475 | sta_entry->ratr_index = 0; | ||
476 | } | ||
477 | return 0; | ||
478 | } | ||
391 | static int _rtl_get_hal_qnum(u16 queue) | 479 | static int _rtl_get_hal_qnum(u16 queue) |
392 | { | 480 | { |
393 | int qnum; | 481 | int qnum; |
@@ -444,19 +532,18 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
444 | struct ieee80211_bss_conf *bss_conf, u32 changed) | 532 | struct ieee80211_bss_conf *bss_conf, u32 changed) |
445 | { | 533 | { |
446 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 534 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
535 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
447 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 536 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
448 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 537 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
538 | struct ieee80211_sta *sta = NULL; | ||
449 | 539 | ||
450 | mutex_lock(&rtlpriv->locks.conf_mutex); | 540 | mutex_lock(&rtlpriv->locks.conf_mutex); |
451 | |||
452 | if ((vif->type == NL80211_IFTYPE_ADHOC) || | 541 | if ((vif->type == NL80211_IFTYPE_ADHOC) || |
453 | (vif->type == NL80211_IFTYPE_AP) || | 542 | (vif->type == NL80211_IFTYPE_AP) || |
454 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | 543 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { |
455 | |||
456 | if ((changed & BSS_CHANGED_BEACON) || | 544 | if ((changed & BSS_CHANGED_BEACON) || |
457 | (changed & BSS_CHANGED_BEACON_ENABLED && | 545 | (changed & BSS_CHANGED_BEACON_ENABLED && |
458 | bss_conf->enable_beacon)) { | 546 | bss_conf->enable_beacon)) { |
459 | |||
460 | if (mac->beacon_enabled == 0) { | 547 | if (mac->beacon_enabled == 0) { |
461 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 548 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
462 | ("BSS_CHANGED_BEACON_ENABLED\n")); | 549 | ("BSS_CHANGED_BEACON_ENABLED\n")); |
@@ -468,8 +555,13 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
468 | rtlpriv->cfg->maps | 555 | rtlpriv->cfg->maps |
469 | [RTL_IBSS_INT_MASKS], | 556 | [RTL_IBSS_INT_MASKS], |
470 | 0); | 557 | 0); |
558 | |||
559 | if (rtlpriv->cfg->ops->linked_set_reg) | ||
560 | rtlpriv->cfg->ops->linked_set_reg(hw); | ||
471 | } | 561 | } |
472 | } else { | 562 | } |
563 | if ((changed & BSS_CHANGED_BEACON_ENABLED && | ||
564 | !bss_conf->enable_beacon)) { | ||
473 | if (mac->beacon_enabled == 1) { | 565 | if (mac->beacon_enabled == 1) { |
474 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 566 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
475 | ("ADHOC DISABLE BEACON\n")); | 567 | ("ADHOC DISABLE BEACON\n")); |
@@ -480,7 +572,6 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
480 | [RTL_IBSS_INT_MASKS]); | 572 | [RTL_IBSS_INT_MASKS]); |
481 | } | 573 | } |
482 | } | 574 | } |
483 | |||
484 | if (changed & BSS_CHANGED_BEACON_INT) { | 575 | if (changed & BSS_CHANGED_BEACON_INT) { |
485 | RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, | 576 | RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, |
486 | ("BSS_CHANGED_BEACON_INT\n")); | 577 | ("BSS_CHANGED_BEACON_INT\n")); |
@@ -492,11 +583,25 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
492 | /*TODO: reference to enum ieee80211_bss_change */ | 583 | /*TODO: reference to enum ieee80211_bss_change */ |
493 | if (changed & BSS_CHANGED_ASSOC) { | 584 | if (changed & BSS_CHANGED_ASSOC) { |
494 | if (bss_conf->assoc) { | 585 | if (bss_conf->assoc) { |
586 | /* we should reset all sec info & cam | ||
587 | * before set cam after linked, we should not | ||
588 | * reset in disassoc, that will cause tkip->wep | ||
589 | * fail because some flag will be wrong */ | ||
590 | /* reset sec info */ | ||
591 | rtl_cam_reset_sec_info(hw); | ||
592 | /* reset cam to fix wep fail issue | ||
593 | * when change from wpa to wep */ | ||
594 | rtl_cam_reset_all_entry(hw); | ||
595 | |||
495 | mac->link_state = MAC80211_LINKED; | 596 | mac->link_state = MAC80211_LINKED; |
496 | mac->cnt_after_linked = 0; | 597 | mac->cnt_after_linked = 0; |
497 | mac->assoc_id = bss_conf->aid; | 598 | mac->assoc_id = bss_conf->aid; |
498 | memcpy(mac->bssid, bss_conf->bssid, 6); | 599 | memcpy(mac->bssid, bss_conf->bssid, 6); |
499 | 600 | ||
601 | if (rtlpriv->cfg->ops->linked_set_reg) | ||
602 | rtlpriv->cfg->ops->linked_set_reg(hw); | ||
603 | if (mac->opmode == NL80211_IFTYPE_STATION && sta) | ||
604 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); | ||
500 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 605 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
501 | ("BSS_CHANGED_ASSOC\n")); | 606 | ("BSS_CHANGED_ASSOC\n")); |
502 | } else { | 607 | } else { |
@@ -505,9 +610,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
505 | 610 | ||
506 | mac->link_state = MAC80211_NOLINK; | 611 | mac->link_state = MAC80211_NOLINK; |
507 | memset(mac->bssid, 0, 6); | 612 | memset(mac->bssid, 0, 6); |
508 | 613 | mac->vendor = PEER_UNKNOWN; | |
509 | /* reset sec info */ | ||
510 | rtl_cam_reset_sec_info(hw); | ||
511 | 614 | ||
512 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 615 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
513 | ("BSS_CHANGED_UN_ASSOC\n")); | 616 | ("BSS_CHANGED_UN_ASSOC\n")); |
@@ -544,14 +647,10 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
544 | } | 647 | } |
545 | 648 | ||
546 | if (changed & BSS_CHANGED_HT) { | 649 | if (changed & BSS_CHANGED_HT) { |
547 | struct ieee80211_sta *sta = NULL; | ||
548 | |||
549 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 650 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
550 | ("BSS_CHANGED_HT\n")); | 651 | ("BSS_CHANGED_HT\n")); |
551 | |||
552 | rcu_read_lock(); | 652 | rcu_read_lock(); |
553 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | 653 | sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); |
554 | |||
555 | if (sta) { | 654 | if (sta) { |
556 | if (sta->ht_cap.ampdu_density > | 655 | if (sta->ht_cap.ampdu_density > |
557 | mac->current_ampdu_density) | 656 | mac->current_ampdu_density) |
@@ -573,9 +672,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
573 | } | 672 | } |
574 | 673 | ||
575 | if (changed & BSS_CHANGED_BSSID) { | 674 | if (changed & BSS_CHANGED_BSSID) { |
576 | struct ieee80211_sta *sta = NULL; | ||
577 | u32 basic_rates; | 675 | u32 basic_rates; |
578 | u8 i; | ||
579 | 676 | ||
580 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, | 677 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, |
581 | (u8 *) bss_conf->bssid); | 678 | (u8 *) bss_conf->bssid); |
@@ -583,96 +680,65 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
583 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, | 680 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, |
584 | (MAC_FMT "\n", MAC_ARG(bss_conf->bssid))); | 681 | (MAC_FMT "\n", MAC_ARG(bss_conf->bssid))); |
585 | 682 | ||
683 | mac->vendor = PEER_UNKNOWN; | ||
586 | memcpy(mac->bssid, bss_conf->bssid, 6); | 684 | memcpy(mac->bssid, bss_conf->bssid, 6); |
587 | if (is_valid_ether_addr(bss_conf->bssid)) { | 685 | rtlpriv->cfg->ops->set_network_type(hw, vif->type); |
588 | switch (vif->type) { | ||
589 | case NL80211_IFTYPE_UNSPECIFIED: | ||
590 | break; | ||
591 | case NL80211_IFTYPE_ADHOC: | ||
592 | break; | ||
593 | case NL80211_IFTYPE_STATION: | ||
594 | break; | ||
595 | case NL80211_IFTYPE_AP: | ||
596 | break; | ||
597 | default: | ||
598 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
599 | ("switch case not process\n")); | ||
600 | break; | ||
601 | } | ||
602 | rtlpriv->cfg->ops->set_network_type(hw, vif->type); | ||
603 | } else | ||
604 | rtlpriv->cfg->ops->set_network_type(hw, | ||
605 | NL80211_IFTYPE_UNSPECIFIED); | ||
606 | |||
607 | memset(mac->mcs, 0, 16); | ||
608 | mac->ht_enable = false; | ||
609 | mac->sgi_40 = false; | ||
610 | mac->sgi_20 = false; | ||
611 | |||
612 | if (!bss_conf->use_short_slot) | ||
613 | mac->mode = WIRELESS_MODE_B; | ||
614 | else | ||
615 | mac->mode = WIRELESS_MODE_G; | ||
616 | 686 | ||
617 | rcu_read_lock(); | 687 | rcu_read_lock(); |
618 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | 688 | sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); |
689 | if (!sta) { | ||
690 | rcu_read_unlock(); | ||
691 | goto out; | ||
692 | } | ||
619 | 693 | ||
620 | if (sta) { | 694 | if (rtlhal->current_bandtype == BAND_ON_5G) { |
621 | if (sta->ht_cap.ht_supported) { | 695 | mac->mode = WIRELESS_MODE_A; |
696 | } else { | ||
697 | if (sta->supp_rates[0] <= 0xf) | ||
698 | mac->mode = WIRELESS_MODE_B; | ||
699 | else | ||
700 | mac->mode = WIRELESS_MODE_G; | ||
701 | } | ||
702 | |||
703 | if (sta->ht_cap.ht_supported) { | ||
704 | if (rtlhal->current_bandtype == BAND_ON_2_4G) | ||
622 | mac->mode = WIRELESS_MODE_N_24G; | 705 | mac->mode = WIRELESS_MODE_N_24G; |
623 | mac->ht_enable = true; | 706 | else |
624 | } | 707 | mac->mode = WIRELESS_MODE_N_5G; |
708 | } | ||
625 | 709 | ||
626 | if (mac->ht_enable) { | 710 | /* just station need it, because ibss & ap mode will |
627 | u16 ht_cap = sta->ht_cap.cap; | 711 | * set in sta_add, and will be NULL here */ |
628 | memcpy(mac->mcs, (u8 *) (&sta->ht_cap.mcs), 16); | 712 | if (mac->opmode == NL80211_IFTYPE_STATION) { |
629 | 713 | struct rtl_sta_info *sta_entry; | |
630 | for (i = 0; i < 16; i++) | 714 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; |
631 | RT_TRACE(rtlpriv, COMP_MAC80211, | 715 | sta_entry->wireless_mode = mac->mode; |
632 | DBG_LOUD, ("%x ", | 716 | } |
633 | mac->mcs[i])); | 717 | |
634 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, | 718 | if (sta->ht_cap.ht_supported) { |
635 | ("\n")); | 719 | mac->ht_enable = true; |
636 | 720 | ||
637 | if (ht_cap & IEEE80211_HT_CAP_SGI_40) | 721 | /* |
638 | mac->sgi_40 = true; | 722 | * for cisco 1252 bw20 it's wrong |
639 | 723 | * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { | |
640 | if (ht_cap & IEEE80211_HT_CAP_SGI_20) | 724 | * mac->bw_40 = true; |
641 | mac->sgi_20 = true; | 725 | * } |
642 | 726 | * */ | |
643 | /* | ||
644 | * for cisco 1252 bw20 it's wrong | ||
645 | * if (ht_cap & | ||
646 | * IEEE80211_HT_CAP_SUP_WIDTH_20_40) { | ||
647 | * mac->bw_40 = true; | ||
648 | * } | ||
649 | */ | ||
650 | } | ||
651 | } | 727 | } |
652 | rcu_read_unlock(); | ||
653 | 728 | ||
654 | /*mac80211 just give us CCK rates any time | ||
655 | *So we add G rate in basic rates when | ||
656 | not in B mode*/ | ||
657 | if (changed & BSS_CHANGED_BASIC_RATES) { | 729 | if (changed & BSS_CHANGED_BASIC_RATES) { |
658 | if (mac->mode == WIRELESS_MODE_B) | 730 | /* for 5G must << RATE_6M_INDEX=4, |
659 | basic_rates = bss_conf->basic_rates | 0x00f; | 731 | * because 5G have no cck rate*/ |
732 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
733 | basic_rates = sta->supp_rates[1] << 4; | ||
660 | else | 734 | else |
661 | basic_rates = bss_conf->basic_rates | 0xff0; | 735 | basic_rates = sta->supp_rates[0]; |
662 | |||
663 | if (!vif) | ||
664 | goto out; | ||
665 | 736 | ||
666 | mac->basic_rates = basic_rates; | 737 | mac->basic_rates = basic_rates; |
667 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, | 738 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, |
668 | (u8 *) (&basic_rates)); | 739 | (u8 *) (&basic_rates)); |
669 | |||
670 | if (rtlpriv->dm.useramask) | ||
671 | rtlpriv->cfg->ops->update_rate_mask(hw, 0); | ||
672 | else | ||
673 | rtlpriv->cfg->ops->update_rate_table(hw); | ||
674 | |||
675 | } | 740 | } |
741 | rcu_read_unlock(); | ||
676 | } | 742 | } |
677 | 743 | ||
678 | /* | 744 | /* |
@@ -758,16 +824,17 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw, | |||
758 | case IEEE80211_AMPDU_TX_START: | 824 | case IEEE80211_AMPDU_TX_START: |
759 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 825 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
760 | ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); | 826 | ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); |
761 | return rtl_tx_agg_start(hw, sta->addr, tid, ssn); | 827 | return rtl_tx_agg_start(hw, sta, tid, ssn); |
762 | break; | 828 | break; |
763 | case IEEE80211_AMPDU_TX_STOP: | 829 | case IEEE80211_AMPDU_TX_STOP: |
764 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 830 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
765 | ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); | 831 | ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); |
766 | return rtl_tx_agg_stop(hw, sta->addr, tid); | 832 | return rtl_tx_agg_stop(hw, sta, tid); |
767 | break; | 833 | break; |
768 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 834 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
769 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 835 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
770 | ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); | 836 | ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); |
837 | rtl_tx_agg_oper(hw, sta, tid); | ||
771 | break; | 838 | break; |
772 | case IEEE80211_AMPDU_RX_START: | 839 | case IEEE80211_AMPDU_RX_START: |
773 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, | 840 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, |
@@ -797,8 +864,12 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) | |||
797 | if (mac->link_state == MAC80211_LINKED) { | 864 | if (mac->link_state == MAC80211_LINKED) { |
798 | rtl_lps_leave(hw); | 865 | rtl_lps_leave(hw); |
799 | mac->link_state = MAC80211_LINKED_SCANNING; | 866 | mac->link_state = MAC80211_LINKED_SCANNING; |
800 | } else | 867 | } else { |
801 | rtl_ips_nic_on(hw); | 868 | rtl_ips_nic_on(hw); |
869 | } | ||
870 | |||
871 | /* Dual mac */ | ||
872 | rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; | ||
802 | 873 | ||
803 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY); | 874 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY); |
804 | rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP); | 875 | rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP); |
@@ -810,22 +881,19 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) | |||
810 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 881 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
811 | 882 | ||
812 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); | 883 | RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); |
813 | |||
814 | rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE); | ||
815 | mac->act_scanning = false; | 884 | mac->act_scanning = false; |
885 | /* Dual mac */ | ||
886 | rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; | ||
887 | |||
816 | if (mac->link_state == MAC80211_LINKED_SCANNING) { | 888 | if (mac->link_state == MAC80211_LINKED_SCANNING) { |
817 | mac->link_state = MAC80211_LINKED; | 889 | mac->link_state = MAC80211_LINKED; |
818 | 890 | if (mac->opmode == NL80211_IFTYPE_STATION) { | |
819 | /* fix fwlps issue */ | 891 | /* fix fwlps issue */ |
820 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); | 892 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); |
821 | 893 | } | |
822 | if (rtlpriv->dm.useramask) | ||
823 | rtlpriv->cfg->ops->update_rate_mask(hw, 0); | ||
824 | else | ||
825 | rtlpriv->cfg->ops->update_rate_table(hw); | ||
826 | |||
827 | } | 894 | } |
828 | 895 | ||
896 | rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE); | ||
829 | } | 897 | } |
830 | 898 | ||
831 | static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 899 | static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
@@ -856,49 +924,73 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
856 | rtl_ips_nic_on(hw); | 924 | rtl_ips_nic_on(hw); |
857 | mutex_lock(&rtlpriv->locks.conf_mutex); | 925 | mutex_lock(&rtlpriv->locks.conf_mutex); |
858 | /* <1> get encryption alg */ | 926 | /* <1> get encryption alg */ |
927 | |||
859 | switch (key->cipher) { | 928 | switch (key->cipher) { |
860 | case WLAN_CIPHER_SUITE_WEP40: | 929 | case WLAN_CIPHER_SUITE_WEP40: |
861 | key_type = WEP40_ENCRYPTION; | 930 | key_type = WEP40_ENCRYPTION; |
862 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); | 931 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); |
863 | rtlpriv->sec.use_defaultkey = true; | ||
864 | break; | 932 | break; |
865 | case WLAN_CIPHER_SUITE_WEP104: | 933 | case WLAN_CIPHER_SUITE_WEP104: |
866 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 934 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, |
867 | ("alg:WEP104\n")); | 935 | ("alg:WEP104\n")); |
868 | key_type = WEP104_ENCRYPTION; | 936 | key_type = WEP104_ENCRYPTION; |
869 | rtlpriv->sec.use_defaultkey = true; | ||
870 | break; | 937 | break; |
871 | case WLAN_CIPHER_SUITE_TKIP: | 938 | case WLAN_CIPHER_SUITE_TKIP: |
872 | key_type = TKIP_ENCRYPTION; | 939 | key_type = TKIP_ENCRYPTION; |
873 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); | 940 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); |
874 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
875 | rtlpriv->sec.use_defaultkey = true; | ||
876 | break; | 941 | break; |
877 | case WLAN_CIPHER_SUITE_CCMP: | 942 | case WLAN_CIPHER_SUITE_CCMP: |
878 | key_type = AESCCMP_ENCRYPTION; | 943 | key_type = AESCCMP_ENCRYPTION; |
879 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); | 944 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); |
880 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
881 | rtlpriv->sec.use_defaultkey = true; | ||
882 | break; | 945 | break; |
883 | default: | 946 | default: |
884 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 947 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
885 | ("alg_err:%x!!!!:\n", key->cipher)); | 948 | ("alg_err:%x!!!!:\n", key->cipher)); |
886 | goto out_unlock; | 949 | goto out_unlock; |
887 | } | 950 | } |
951 | if (key_type == WEP40_ENCRYPTION || | ||
952 | key_type == WEP104_ENCRYPTION || | ||
953 | mac->opmode == NL80211_IFTYPE_ADHOC) | ||
954 | rtlpriv->sec.use_defaultkey = true; | ||
955 | |||
888 | /* <2> get key_idx */ | 956 | /* <2> get key_idx */ |
889 | key_idx = (u8) (key->keyidx); | 957 | key_idx = (u8) (key->keyidx); |
890 | if (key_idx > 3) | 958 | if (key_idx > 3) |
891 | goto out_unlock; | 959 | goto out_unlock; |
892 | /* <3> if pairwise key enable_hw_sec */ | 960 | /* <3> if pairwise key enable_hw_sec */ |
893 | group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE); | 961 | group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE); |
894 | if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) || | 962 | |
895 | rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) { | 963 | /* wep always be group key, but there are two conditions: |
896 | if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION && | 964 | * 1) wep only: is just for wep enc, in this condition |
897 | (key_type == WEP40_ENCRYPTION || | 965 | * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION |
898 | key_type == WEP104_ENCRYPTION)) | 966 | * will be true & enable_hw_sec will be set when wep |
899 | wep_only = true; | 967 | * ke setting. |
900 | rtlpriv->sec.pairwise_enc_algorithm = key_type; | 968 | * 2) wep(group) + AES(pairwise): some AP like cisco |
901 | rtlpriv->cfg->ops->enable_hw_sec(hw); | 969 | * may use it, in this condition enable_hw_sec will not |
970 | * be set when wep key setting */ | ||
971 | /* we must reset sec_info after lingked before set key, | ||
972 | * or some flag will be wrong*/ | ||
973 | if (mac->opmode == NL80211_IFTYPE_AP) { | ||
974 | if (!group_key || key_type == WEP40_ENCRYPTION || | ||
975 | key_type == WEP104_ENCRYPTION) { | ||
976 | if (group_key) | ||
977 | wep_only = true; | ||
978 | rtlpriv->cfg->ops->enable_hw_sec(hw); | ||
979 | } | ||
980 | } else { | ||
981 | if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) || | ||
982 | rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) { | ||
983 | if (rtlpriv->sec.pairwise_enc_algorithm == | ||
984 | NO_ENCRYPTION && | ||
985 | (key_type == WEP40_ENCRYPTION || | ||
986 | key_type == WEP104_ENCRYPTION)) | ||
987 | wep_only = true; | ||
988 | rtlpriv->sec.pairwise_enc_algorithm = key_type; | ||
989 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
990 | ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1" | ||
991 | " TKIP:2 AES:4 WEP104:5)\n", key_type)); | ||
992 | rtlpriv->cfg->ops->enable_hw_sec(hw); | ||
993 | } | ||
902 | } | 994 | } |
903 | /* <4> set key based on cmd */ | 995 | /* <4> set key based on cmd */ |
904 | switch (cmd) { | 996 | switch (cmd) { |
@@ -930,6 +1022,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
930 | if (!sta) { | 1022 | if (!sta) { |
931 | RT_ASSERT(false, ("pairwise key withnot" | 1023 | RT_ASSERT(false, ("pairwise key withnot" |
932 | "mac_addr\n")); | 1024 | "mac_addr\n")); |
1025 | |||
933 | err = -EOPNOTSUPP; | 1026 | err = -EOPNOTSUPP; |
934 | goto out_unlock; | 1027 | goto out_unlock; |
935 | } | 1028 | } |
@@ -957,6 +1050,10 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
957 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 1050 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, |
958 | ("disable key delete one entry\n")); | 1051 | ("disable key delete one entry\n")); |
959 | /*set local buf about wep key. */ | 1052 | /*set local buf about wep key. */ |
1053 | if (mac->opmode == NL80211_IFTYPE_AP) { | ||
1054 | if (sta) | ||
1055 | rtl_cam_del_entry(hw, sta->addr); | ||
1056 | } | ||
960 | memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); | 1057 | memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); |
961 | rtlpriv->sec.key_len[key_idx] = 0; | 1058 | rtlpriv->sec.key_len[key_idx] = 0; |
962 | memcpy(mac_addr, zero_addr, ETH_ALEN); | 1059 | memcpy(mac_addr, zero_addr, ETH_ALEN); |
@@ -1009,6 +1106,18 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) | |||
1009 | mutex_unlock(&rtlpriv->locks.conf_mutex); | 1106 | mutex_unlock(&rtlpriv->locks.conf_mutex); |
1010 | } | 1107 | } |
1011 | 1108 | ||
1109 | /* this function is called by mac80211 to flush tx buffer | ||
1110 | * before switch channle or power save, or tx buffer packet | ||
1111 | * maybe send after offchannel or rf sleep, this may cause | ||
1112 | * dis-association by AP */ | ||
1113 | static void rtl_op_flush(struct ieee80211_hw *hw, bool drop) | ||
1114 | { | ||
1115 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1116 | |||
1117 | if (rtlpriv->intf_ops->flush) | ||
1118 | rtlpriv->intf_ops->flush(hw, drop); | ||
1119 | } | ||
1120 | |||
1012 | const struct ieee80211_ops rtl_ops = { | 1121 | const struct ieee80211_ops rtl_ops = { |
1013 | .start = rtl_op_start, | 1122 | .start = rtl_op_start, |
1014 | .stop = rtl_op_stop, | 1123 | .stop = rtl_op_stop, |
@@ -1017,6 +1126,8 @@ const struct ieee80211_ops rtl_ops = { | |||
1017 | .remove_interface = rtl_op_remove_interface, | 1126 | .remove_interface = rtl_op_remove_interface, |
1018 | .config = rtl_op_config, | 1127 | .config = rtl_op_config, |
1019 | .configure_filter = rtl_op_configure_filter, | 1128 | .configure_filter = rtl_op_configure_filter, |
1129 | .sta_add = rtl_op_sta_add, | ||
1130 | .sta_remove = rtl_op_sta_remove, | ||
1020 | .set_key = rtl_op_set_key, | 1131 | .set_key = rtl_op_set_key, |
1021 | .conf_tx = rtl_op_conf_tx, | 1132 | .conf_tx = rtl_op_conf_tx, |
1022 | .bss_info_changed = rtl_op_bss_info_changed, | 1133 | .bss_info_changed = rtl_op_bss_info_changed, |
@@ -1028,4 +1139,5 @@ const struct ieee80211_ops rtl_ops = { | |||
1028 | .sw_scan_start = rtl_op_sw_scan_start, | 1139 | .sw_scan_start = rtl_op_sw_scan_start, |
1029 | .sw_scan_complete = rtl_op_sw_scan_complete, | 1140 | .sw_scan_complete = rtl_op_sw_scan_complete, |
1030 | .rfkill_poll = rtl_op_rfkill_poll, | 1141 | .rfkill_poll = rtl_op_rfkill_poll, |
1142 | .flush = rtl_op_flush, | ||
1031 | }; | 1143 | }; |
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 0ef31c3c6196..4b247db2861d 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h | |||
@@ -24,6 +24,7 @@ | |||
24 | * Hsinchu 300, Taiwan. | 24 | * Hsinchu 300, Taiwan. |
25 | * | 25 | * |
26 | * Larry Finger <Larry.Finger@lwfinger.net> | 26 | * Larry Finger <Larry.Finger@lwfinger.net> |
27 | * | ||
27 | *****************************************************************************/ | 28 | *****************************************************************************/ |
28 | 29 | ||
29 | #ifndef __RTL_CORE_H__ | 30 | #ifndef __RTL_CORE_H__ |
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 5d73c0f7012c..510d42edb8ca 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c | |||
@@ -52,8 +52,6 @@ static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = { | |||
52 | {11, 0, 0, 28} | 52 | {11, 0, 0, 28} |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, | ||
56 | u8 *pbuf); | ||
57 | static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset, | 55 | static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset, |
58 | u8 *value); | 56 | u8 *value); |
59 | static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset, | 57 | static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset, |
@@ -79,7 +77,7 @@ static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, | |||
79 | u8 *targetdata); | 77 | u8 *targetdata); |
80 | static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, | 78 | static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, |
81 | u16 efuse_addr, u8 word_en, u8 *data); | 79 | u16 efuse_addr, u8 word_en, u8 *data); |
82 | static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, | 80 | static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, |
83 | u8 pwrstate); | 81 | u8 pwrstate); |
84 | static u16 efuse_get_current_size(struct ieee80211_hw *hw); | 82 | static u16 efuse_get_current_size(struct ieee80211_hw *hw); |
85 | static u8 efuse_calculate_word_cnts(u8 word_en); | 83 | static u8 efuse_calculate_word_cnts(u8 word_en); |
@@ -115,8 +113,10 @@ u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address) | |||
115 | u8 bytetemp; | 113 | u8 bytetemp; |
116 | u8 temp; | 114 | u8 temp; |
117 | u32 k = 0; | 115 | u32 k = 0; |
116 | const u32 efuse_len = | ||
117 | rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; | ||
118 | 118 | ||
119 | if (address < EFUSE_REAL_CONTENT_LEN) { | 119 | if (address < efuse_len) { |
120 | temp = address & 0xFF; | 120 | temp = address & 0xFF; |
121 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, | 121 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, |
122 | temp); | 122 | temp); |
@@ -158,11 +158,13 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) | |||
158 | u8 bytetemp; | 158 | u8 bytetemp; |
159 | u8 temp; | 159 | u8 temp; |
160 | u32 k = 0; | 160 | u32 k = 0; |
161 | const u32 efuse_len = | ||
162 | rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; | ||
161 | 163 | ||
162 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, | 164 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, |
163 | ("Addr=%x Data =%x\n", address, value)); | 165 | ("Addr=%x Data =%x\n", address, value)); |
164 | 166 | ||
165 | if (address < EFUSE_REAL_CONTENT_LEN) { | 167 | if (address < efuse_len) { |
166 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); | 168 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); |
167 | 169 | ||
168 | temp = address & 0xFF; | 170 | temp = address & 0xFF; |
@@ -198,7 +200,7 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) | |||
198 | 200 | ||
199 | } | 201 | } |
200 | 202 | ||
201 | static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf) | 203 | void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf) |
202 | { | 204 | { |
203 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 205 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
204 | u32 value32; | 206 | u32 value32; |
@@ -233,24 +235,28 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
233 | { | 235 | { |
234 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 236 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
235 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 237 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
236 | u8 efuse_tbl[EFUSE_MAP_LEN]; | 238 | u8 efuse_tbl[HWSET_MAX_SIZE]; |
237 | u8 rtemp8[1]; | 239 | u8 rtemp8[1]; |
238 | u16 efuse_addr = 0; | 240 | u16 efuse_addr = 0; |
239 | u8 offset, wren; | 241 | u8 offset, wren; |
240 | u16 i; | 242 | u16 i; |
241 | u16 j; | 243 | u16 j; |
244 | const u16 efuse_max_section = | ||
245 | rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP]; | ||
246 | const u32 efuse_len = | ||
247 | rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; | ||
242 | u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT]; | 248 | u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT]; |
243 | u16 efuse_utilized = 0; | 249 | u16 efuse_utilized = 0; |
244 | u8 efuse_usage; | 250 | u8 efuse_usage; |
245 | 251 | ||
246 | if ((_offset + _size_byte) > EFUSE_MAP_LEN) { | 252 | if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) { |
247 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, | 253 | RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, |
248 | ("read_efuse(): Invalid offset(%#x) with read " | 254 | ("read_efuse(): Invalid offset(%#x) with read " |
249 | "bytes(%#x)!!\n", _offset, _size_byte)); | 255 | "bytes(%#x)!!\n", _offset, _size_byte)); |
250 | return; | 256 | return; |
251 | } | 257 | } |
252 | 258 | ||
253 | for (i = 0; i < EFUSE_MAX_SECTION; i++) | 259 | for (i = 0; i < efuse_max_section; i++) |
254 | for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) | 260 | for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) |
255 | efuse_word[i][j] = 0xFFFF; | 261 | efuse_word[i][j] = 0xFFFF; |
256 | 262 | ||
@@ -262,10 +268,10 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
262 | efuse_addr++; | 268 | efuse_addr++; |
263 | } | 269 | } |
264 | 270 | ||
265 | while ((*rtemp8 != 0xFF) && (efuse_addr < EFUSE_REAL_CONTENT_LEN)) { | 271 | while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) { |
266 | offset = ((*rtemp8 >> 4) & 0x0f); | 272 | offset = ((*rtemp8 >> 4) & 0x0f); |
267 | 273 | ||
268 | if (offset < EFUSE_MAX_SECTION) { | 274 | if (offset < efuse_max_section) { |
269 | wren = (*rtemp8 & 0x0f); | 275 | wren = (*rtemp8 & 0x0f); |
270 | RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, | 276 | RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, |
271 | ("offset-%d Worden=%x\n", offset, wren)); | 277 | ("offset-%d Worden=%x\n", offset, wren)); |
@@ -281,7 +287,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
281 | efuse_utilized++; | 287 | efuse_utilized++; |
282 | efuse_word[offset][i] = (*rtemp8 & 0xff); | 288 | efuse_word[offset][i] = (*rtemp8 & 0xff); |
283 | 289 | ||
284 | if (efuse_addr >= EFUSE_REAL_CONTENT_LEN) | 290 | if (efuse_addr >= efuse_len) |
285 | break; | 291 | break; |
286 | 292 | ||
287 | RTPRINT(rtlpriv, FEEPROM, | 293 | RTPRINT(rtlpriv, FEEPROM, |
@@ -294,7 +300,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
294 | efuse_word[offset][i] |= | 300 | efuse_word[offset][i] |= |
295 | (((u16)*rtemp8 << 8) & 0xff00); | 301 | (((u16)*rtemp8 << 8) & 0xff00); |
296 | 302 | ||
297 | if (efuse_addr >= EFUSE_REAL_CONTENT_LEN) | 303 | if (efuse_addr >= efuse_len) |
298 | break; | 304 | break; |
299 | } | 305 | } |
300 | 306 | ||
@@ -305,13 +311,13 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
305 | RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, | 311 | RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, |
306 | ("Addr=%d\n", efuse_addr)); | 312 | ("Addr=%d\n", efuse_addr)); |
307 | read_efuse_byte(hw, efuse_addr, rtemp8); | 313 | read_efuse_byte(hw, efuse_addr, rtemp8); |
308 | if (*rtemp8 != 0xFF && (efuse_addr < 512)) { | 314 | if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) { |
309 | efuse_utilized++; | 315 | efuse_utilized++; |
310 | efuse_addr++; | 316 | efuse_addr++; |
311 | } | 317 | } |
312 | } | 318 | } |
313 | 319 | ||
314 | for (i = 0; i < EFUSE_MAX_SECTION; i++) { | 320 | for (i = 0; i < efuse_max_section; i++) { |
315 | for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { | 321 | for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { |
316 | efuse_tbl[(i * 8) + (j * 2)] = | 322 | efuse_tbl[(i * 8) + (j * 2)] = |
317 | (efuse_word[i][j] & 0xff); | 323 | (efuse_word[i][j] & 0xff); |
@@ -324,7 +330,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
324 | pbuf[i] = efuse_tbl[_offset + i]; | 330 | pbuf[i] = efuse_tbl[_offset + i]; |
325 | 331 | ||
326 | rtlefuse->efuse_usedbytes = efuse_utilized; | 332 | rtlefuse->efuse_usedbytes = efuse_utilized; |
327 | efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN); | 333 | efuse_usage = (u8) ((efuse_utilized * 100) / efuse_len); |
328 | rtlefuse->efuse_usedpercentage = efuse_usage; | 334 | rtlefuse->efuse_usedpercentage = efuse_usage; |
329 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES, | 335 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES, |
330 | (u8 *)&efuse_utilized); | 336 | (u8 *)&efuse_utilized); |
@@ -478,9 +484,10 @@ void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw) | |||
478 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 484 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
479 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 485 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
480 | 486 | ||
481 | if (rtlefuse->autoload_failflag == true) { | 487 | if (rtlefuse->autoload_failflag == true) |
482 | memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, 128); | 488 | memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, |
483 | } else | 489 | rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); |
490 | else | ||
484 | efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); | 491 | efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); |
485 | 492 | ||
486 | memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], | 493 | memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], |
@@ -632,8 +639,9 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) | |||
632 | 639 | ||
633 | static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse) | 640 | static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse) |
634 | { | 641 | { |
642 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
635 | efuse_power_switch(hw, false, true); | 643 | efuse_power_switch(hw, false, true); |
636 | read_efuse(hw, 0, 128, efuse); | 644 | read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse); |
637 | efuse_power_switch(hw, false, false); | 645 | efuse_power_switch(hw, false, false); |
638 | } | 646 | } |
639 | 647 | ||
@@ -641,7 +649,7 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
641 | u8 efuse_data, u8 offset, u8 *tmpdata, | 649 | u8 efuse_data, u8 offset, u8 *tmpdata, |
642 | u8 *readstate) | 650 | u8 *readstate) |
643 | { | 651 | { |
644 | bool bdataempty = true; | 652 | bool dataempty = true; |
645 | u8 hoffset; | 653 | u8 hoffset; |
646 | u8 tmpidx; | 654 | u8 tmpidx; |
647 | u8 hworden; | 655 | u8 hworden; |
@@ -657,13 +665,13 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
657 | &efuse_data)) { | 665 | &efuse_data)) { |
658 | tmpdata[tmpidx] = efuse_data; | 666 | tmpdata[tmpidx] = efuse_data; |
659 | if (efuse_data != 0xff) | 667 | if (efuse_data != 0xff) |
660 | bdataempty = true; | 668 | dataempty = true; |
661 | } | 669 | } |
662 | } | 670 | } |
663 | 671 | ||
664 | if (bdataempty == true) | 672 | if (dataempty == true) { |
665 | *readstate = PG_STATE_DATA; | 673 | *readstate = PG_STATE_DATA; |
666 | else { | 674 | } else { |
667 | *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; | 675 | *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; |
668 | *readstate = PG_STATE_HEADER; | 676 | *readstate = PG_STATE_HEADER; |
669 | } | 677 | } |
@@ -677,9 +685,7 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
677 | static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) | 685 | static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) |
678 | { | 686 | { |
679 | u8 readstate = PG_STATE_HEADER; | 687 | u8 readstate = PG_STATE_HEADER; |
680 | |||
681 | bool continual = true; | 688 | bool continual = true; |
682 | |||
683 | u8 efuse_data, word_cnts = 0; | 689 | u8 efuse_data, word_cnts = 0; |
684 | u16 efuse_addr = 0; | 690 | u16 efuse_addr = 0; |
685 | u8 tmpdata[8]; | 691 | u8 tmpdata[8]; |
@@ -795,19 +801,20 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
795 | tmp_word_en &= (~BIT(1)); | 801 | tmp_word_en &= (~BIT(1)); |
796 | 802 | ||
797 | if ((target_pkt->word_en & BIT(2)) ^ | 803 | if ((target_pkt->word_en & BIT(2)) ^ |
798 | (match_word_en & BIT(2))) | 804 | (match_word_en & BIT(2))) |
799 | tmp_word_en &= (~BIT(2)); | 805 | tmp_word_en &= (~BIT(2)); |
800 | 806 | ||
801 | if ((target_pkt->word_en & BIT(3)) ^ | 807 | if ((target_pkt->word_en & BIT(3)) ^ |
802 | (match_word_en & BIT(3))) | 808 | (match_word_en & BIT(3))) |
803 | tmp_word_en &= (~BIT(3)); | 809 | tmp_word_en &= (~BIT(3)); |
804 | 810 | ||
805 | if ((tmp_word_en & 0x0F) != 0x0F) { | 811 | if ((tmp_word_en & 0x0F) != 0x0F) { |
806 | *efuse_addr = efuse_get_current_size(hw); | 812 | *efuse_addr = efuse_get_current_size(hw); |
807 | target_pkt->offset = offset; | 813 | target_pkt->offset = offset; |
808 | target_pkt->word_en = tmp_word_en; | 814 | target_pkt->word_en = tmp_word_en; |
809 | } else | 815 | } else { |
810 | *continual = false; | 816 | *continual = false; |
817 | } | ||
811 | *write_state = PG_STATE_HEADER; | 818 | *write_state = PG_STATE_HEADER; |
812 | *repeat_times += 1; | 819 | *repeat_times += 1; |
813 | if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { | 820 | if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { |
@@ -842,9 +849,9 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
842 | efuse_one_byte_write(hw, *efuse_addr, pg_header); | 849 | efuse_one_byte_write(hw, *efuse_addr, pg_header); |
843 | efuse_one_byte_read(hw, *efuse_addr, &tmp_header); | 850 | efuse_one_byte_read(hw, *efuse_addr, &tmp_header); |
844 | 851 | ||
845 | if (tmp_header == pg_header) | 852 | if (tmp_header == pg_header) { |
846 | *write_state = PG_STATE_DATA; | 853 | *write_state = PG_STATE_DATA; |
847 | else if (tmp_header == 0xFF) { | 854 | } else if (tmp_header == 0xFF) { |
848 | *write_state = PG_STATE_HEADER; | 855 | *write_state = PG_STATE_HEADER; |
849 | *repeat_times += 1; | 856 | *repeat_times += 1; |
850 | if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { | 857 | if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { |
@@ -871,11 +878,13 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
871 | reorg_worden, | 878 | reorg_worden, |
872 | originaldata); | 879 | originaldata); |
873 | *efuse_addr = efuse_get_current_size(hw); | 880 | *efuse_addr = efuse_get_current_size(hw); |
874 | } else | 881 | } else { |
875 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) | 882 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) |
876 | + 1; | 883 | + 1; |
877 | } else | 884 | } |
885 | } else { | ||
878 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; | 886 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; |
887 | } | ||
879 | 888 | ||
880 | *write_state = PG_STATE_HEADER; | 889 | *write_state = PG_STATE_HEADER; |
881 | *repeat_times += 1; | 890 | *repeat_times += 1; |
@@ -1069,10 +1078,12 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, | |||
1069 | static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) | 1078 | static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) |
1070 | { | 1079 | { |
1071 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1080 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1081 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1072 | u8 tempval; | 1082 | u8 tempval; |
1073 | u16 tmpV16; | 1083 | u16 tmpV16; |
1074 | 1084 | ||
1075 | if (pwrstate) { | 1085 | if (pwrstate && (rtlhal->hw_type != |
1086 | HARDWARE_TYPE_RTL8192SE)) { | ||
1076 | tmpV16 = rtl_read_word(rtlpriv, | 1087 | tmpV16 = rtl_read_word(rtlpriv, |
1077 | rtlpriv->cfg->maps[SYS_ISO_CTRL]); | 1088 | rtlpriv->cfg->maps[SYS_ISO_CTRL]); |
1078 | if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { | 1089 | if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { |
@@ -1105,13 +1116,22 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) | |||
1105 | tempval = rtl_read_byte(rtlpriv, | 1116 | tempval = rtl_read_byte(rtlpriv, |
1106 | rtlpriv->cfg->maps[EFUSE_TEST] + | 1117 | rtlpriv->cfg->maps[EFUSE_TEST] + |
1107 | 3); | 1118 | 3); |
1108 | tempval &= 0x0F; | 1119 | |
1109 | tempval |= (VOLTAGE_V25 << 4); | 1120 | if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) { |
1121 | tempval &= 0x0F; | ||
1122 | tempval |= (VOLTAGE_V25 << 4); | ||
1123 | } | ||
1124 | |||
1110 | rtl_write_byte(rtlpriv, | 1125 | rtl_write_byte(rtlpriv, |
1111 | rtlpriv->cfg->maps[EFUSE_TEST] + 3, | 1126 | rtlpriv->cfg->maps[EFUSE_TEST] + 3, |
1112 | (tempval | 0x80)); | 1127 | (tempval | 0x80)); |
1113 | } | 1128 | } |
1114 | 1129 | ||
1130 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { | ||
1131 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], | ||
1132 | 0x03); | ||
1133 | } | ||
1134 | |||
1115 | } else { | 1135 | } else { |
1116 | if (write) { | 1136 | if (write) { |
1117 | tempval = rtl_read_byte(rtlpriv, | 1137 | tempval = rtl_read_byte(rtlpriv, |
@@ -1122,6 +1142,11 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) | |||
1122 | (tempval & 0x7F)); | 1142 | (tempval & 0x7F)); |
1123 | } | 1143 | } |
1124 | 1144 | ||
1145 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { | ||
1146 | rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], | ||
1147 | 0x02); | ||
1148 | } | ||
1149 | |||
1125 | } | 1150 | } |
1126 | 1151 | ||
1127 | } | 1152 | } |
diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h index 47774dd4c2a6..164dabaa7615 100644 --- a/drivers/net/wireless/rtlwifi/efuse.h +++ b/drivers/net/wireless/rtlwifi/efuse.h | |||
@@ -30,9 +30,10 @@ | |||
30 | #ifndef __RTL_EFUSE_H_ | 30 | #ifndef __RTL_EFUSE_H_ |
31 | #define __RTL_EFUSE_H_ | 31 | #define __RTL_EFUSE_H_ |
32 | 32 | ||
33 | #define EFUSE_IC_ID_OFFSET 506 | ||
34 | |||
33 | #define EFUSE_REAL_CONTENT_LEN 512 | 35 | #define EFUSE_REAL_CONTENT_LEN 512 |
34 | #define EFUSE_MAP_LEN 128 | 36 | #define EFUSE_MAP_LEN 128 |
35 | #define EFUSE_MAX_SECTION 16 | ||
36 | #define EFUSE_MAX_WORD_UNIT 4 | 37 | #define EFUSE_MAX_WORD_UNIT 4 |
37 | 38 | ||
38 | #define EFUSE_INIT_MAP 0 | 39 | #define EFUSE_INIT_MAP 0 |
@@ -52,6 +53,7 @@ | |||
52 | #define _PRE_EXECUTE_READ_CMD_ | 53 | #define _PRE_EXECUTE_READ_CMD_ |
53 | 54 | ||
54 | #define EFUSE_REPEAT_THRESHOLD_ 3 | 55 | #define EFUSE_REPEAT_THRESHOLD_ 3 |
56 | #define EFUSE_ERROE_HANDLE 1 | ||
55 | 57 | ||
56 | struct efuse_map { | 58 | struct efuse_map { |
57 | u8 offset; | 59 | u8 offset; |
@@ -103,6 +105,7 @@ struct efuse_priv { | |||
103 | u8 tx_power_g[14]; | 105 | u8 tx_power_g[14]; |
104 | }; | 106 | }; |
105 | 107 | ||
108 | extern void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); | ||
106 | extern void efuse_initialize(struct ieee80211_hw *hw); | 109 | extern void efuse_initialize(struct ieee80211_hw *hw); |
107 | extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); | 110 | extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); |
108 | extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); | 111 | extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index c3dd4cc678ba..3550c9fb96e5 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "pci.h" | 32 | #include "pci.h" |
33 | #include "base.h" | 33 | #include "base.h" |
34 | #include "ps.h" | 34 | #include "ps.h" |
35 | #include "efuse.h" | ||
35 | 36 | ||
36 | static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { | 37 | static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { |
37 | INTEL_VENDOR_ID, | 38 | INTEL_VENDOR_ID, |
@@ -40,6 +41,31 @@ static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { | |||
40 | SIS_VENDOR_ID | 41 | SIS_VENDOR_ID |
41 | }; | 42 | }; |
42 | 43 | ||
44 | static const u8 ac_to_hwq[] = { | ||
45 | VO_QUEUE, | ||
46 | VI_QUEUE, | ||
47 | BE_QUEUE, | ||
48 | BK_QUEUE | ||
49 | }; | ||
50 | |||
51 | static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw, | ||
52 | struct sk_buff *skb) | ||
53 | { | ||
54 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
55 | __le16 fc = rtl_get_fc(skb); | ||
56 | u8 queue_index = skb_get_queue_mapping(skb); | ||
57 | |||
58 | if (unlikely(ieee80211_is_beacon(fc))) | ||
59 | return BEACON_QUEUE; | ||
60 | if (ieee80211_is_mgmt(fc)) | ||
61 | return MGNT_QUEUE; | ||
62 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) | ||
63 | if (ieee80211_is_nullfunc(fc)) | ||
64 | return HIGH_QUEUE; | ||
65 | |||
66 | return ac_to_hwq[queue_index]; | ||
67 | } | ||
68 | |||
43 | /* Update PCI dependent default settings*/ | 69 | /* Update PCI dependent default settings*/ |
44 | static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) | 70 | static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) |
45 | { | 71 | { |
@@ -48,6 +74,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) | |||
48 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 74 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
49 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 75 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
50 | u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; | 76 | u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; |
77 | u8 init_aspm; | ||
51 | 78 | ||
52 | ppsc->reg_rfps_level = 0; | 79 | ppsc->reg_rfps_level = 0; |
53 | ppsc->support_aspm = 0; | 80 | ppsc->support_aspm = 0; |
@@ -113,25 +140,45 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) | |||
113 | 140 | ||
114 | /*Set HW definition to determine if it supports ASPM. */ | 141 | /*Set HW definition to determine if it supports ASPM. */ |
115 | switch (rtlpci->const_support_pciaspm) { | 142 | switch (rtlpci->const_support_pciaspm) { |
116 | case 0: | 143 | case 0:{ |
117 | /*Not support ASPM. */ | 144 | /*Not support ASPM. */ |
118 | ppsc->support_aspm = false; | 145 | bool support_aspm = false; |
119 | break; | 146 | ppsc->support_aspm = support_aspm; |
120 | case 1: | 147 | break; |
121 | /*Support ASPM. */ | 148 | } |
122 | ppsc->support_aspm = true; | 149 | case 1:{ |
123 | ppsc->support_backdoor = true; | 150 | /*Support ASPM. */ |
124 | break; | 151 | bool support_aspm = true; |
152 | bool support_backdoor = true; | ||
153 | ppsc->support_aspm = support_aspm; | ||
154 | |||
155 | /*if (priv->oem_id == RT_CID_TOSHIBA && | ||
156 | !priv->ndis_adapter.amd_l1_patch) | ||
157 | support_backdoor = false; */ | ||
158 | |||
159 | ppsc->support_backdoor = support_backdoor; | ||
160 | |||
161 | break; | ||
162 | } | ||
125 | case 2: | 163 | case 2: |
126 | /*ASPM value set by chipset. */ | 164 | /*ASPM value set by chipset. */ |
127 | if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) | 165 | if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { |
128 | ppsc->support_aspm = true; | 166 | bool support_aspm = true; |
167 | ppsc->support_aspm = support_aspm; | ||
168 | } | ||
129 | break; | 169 | break; |
130 | default: | 170 | default: |
131 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 171 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
132 | ("switch case not process\n")); | 172 | ("switch case not process\n")); |
133 | break; | 173 | break; |
134 | } | 174 | } |
175 | |||
176 | /* toshiba aspm issue, toshiba will set aspm selfly | ||
177 | * so we should not set aspm in driver */ | ||
178 | pci_read_config_byte(rtlpci->pdev, 0x80, &init_aspm); | ||
179 | if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE && | ||
180 | init_aspm == 0x43) | ||
181 | ppsc->support_aspm = false; | ||
135 | } | 182 | } |
136 | 183 | ||
137 | static bool _rtl_pci_platform_switch_device_pci_aspm( | 184 | static bool _rtl_pci_platform_switch_device_pci_aspm( |
@@ -139,8 +186,11 @@ static bool _rtl_pci_platform_switch_device_pci_aspm( | |||
139 | u8 value) | 186 | u8 value) |
140 | { | 187 | { |
141 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 188 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
189 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
190 | |||
191 | if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) | ||
192 | value |= 0x40; | ||
142 | 193 | ||
143 | value |= 0x40; | ||
144 | pci_write_config_byte(rtlpci->pdev, 0x80, value); | 194 | pci_write_config_byte(rtlpci->pdev, 0x80, value); |
145 | 195 | ||
146 | return false; | 196 | return false; |
@@ -150,11 +200,13 @@ static bool _rtl_pci_platform_switch_device_pci_aspm( | |||
150 | static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) | 200 | static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) |
151 | { | 201 | { |
152 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 202 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
153 | u8 buffer; | 203 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
154 | 204 | ||
155 | buffer = value; | ||
156 | pci_write_config_byte(rtlpci->pdev, 0x81, value); | 205 | pci_write_config_byte(rtlpci->pdev, 0x81, value); |
157 | 206 | ||
207 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) | ||
208 | udelay(100); | ||
209 | |||
158 | return true; | 210 | return true; |
159 | } | 211 | } |
160 | 212 | ||
@@ -175,6 +227,9 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) | |||
175 | u16 aspmlevel = 0; | 227 | u16 aspmlevel = 0; |
176 | u8 tmp_u1b = 0; | 228 | u8 tmp_u1b = 0; |
177 | 229 | ||
230 | if (!ppsc->support_aspm) | ||
231 | return; | ||
232 | |||
178 | if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { | 233 | if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { |
179 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | 234 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, |
180 | ("PCI(Bridge) UNKNOWN.\n")); | 235 | ("PCI(Bridge) UNKNOWN.\n")); |
@@ -228,6 +283,9 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) | |||
228 | u8 u_pcibridge_aspmsetting; | 283 | u8 u_pcibridge_aspmsetting; |
229 | u8 u_device_aspmsetting; | 284 | u8 u_device_aspmsetting; |
230 | 285 | ||
286 | if (!ppsc->support_aspm) | ||
287 | return; | ||
288 | |||
231 | if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { | 289 | if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { |
232 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | 290 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, |
233 | ("PCI(Bridge) UNKNOWN.\n")); | 291 | ("PCI(Bridge) UNKNOWN.\n")); |
@@ -272,7 +330,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) | |||
272 | RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); | 330 | RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); |
273 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); | 331 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); |
274 | } | 332 | } |
275 | udelay(200); | 333 | udelay(100); |
276 | } | 334 | } |
277 | 335 | ||
278 | static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw) | 336 | static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw) |
@@ -309,13 +367,13 @@ static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) | |||
309 | u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset; | 367 | u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset; |
310 | u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport; | 368 | u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport; |
311 | u8 linkctrl_reg; | 369 | u8 linkctrl_reg; |
312 | u8 num4bBytes; | 370 | u8 num4bbytes; |
313 | 371 | ||
314 | num4bBytes = (capabilityoffset + 0x10) / 4; | 372 | num4bbytes = (capabilityoffset + 0x10) / 4; |
315 | 373 | ||
316 | /*Read Link Control Register */ | 374 | /*Read Link Control Register */ |
317 | rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, | 375 | rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, |
318 | pcicfg_addrport + (num4bBytes << 2)); | 376 | pcicfg_addrport + (num4bbytes << 2)); |
319 | rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg); | 377 | rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg); |
320 | 378 | ||
321 | pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; | 379 | pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; |
@@ -348,7 +406,7 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev, | |||
348 | pci_write_config_byte(pdev, 0x70f, tmp); | 406 | pci_write_config_byte(pdev, 0x70f, tmp); |
349 | } | 407 | } |
350 | 408 | ||
351 | static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw) | 409 | static void rtl_pci_init_aspm(struct ieee80211_hw *hw) |
352 | { | 410 | { |
353 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 411 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
354 | 412 | ||
@@ -362,52 +420,6 @@ static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw) | |||
362 | 420 | ||
363 | } | 421 | } |
364 | 422 | ||
365 | static void rtl_pci_init_aspm(struct ieee80211_hw *hw) | ||
366 | { | ||
367 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
368 | |||
369 | /*close ASPM for AMD defaultly */ | ||
370 | rtlpci->const_amdpci_aspm = 0; | ||
371 | |||
372 | /* | ||
373 | * ASPM PS mode. | ||
374 | * 0 - Disable ASPM, | ||
375 | * 1 - Enable ASPM without Clock Req, | ||
376 | * 2 - Enable ASPM with Clock Req, | ||
377 | * 3 - Always Enable ASPM with Clock Req, | ||
378 | * 4 - Always Enable ASPM without Clock Req. | ||
379 | * set defult to RTL8192CE:3 RTL8192E:2 | ||
380 | * */ | ||
381 | rtlpci->const_pci_aspm = 3; | ||
382 | |||
383 | /*Setting for PCI-E device */ | ||
384 | rtlpci->const_devicepci_aspm_setting = 0x03; | ||
385 | |||
386 | /*Setting for PCI-E bridge */ | ||
387 | rtlpci->const_hostpci_aspm_setting = 0x02; | ||
388 | |||
389 | /* | ||
390 | * In Hw/Sw Radio Off situation. | ||
391 | * 0 - Default, | ||
392 | * 1 - From ASPM setting without low Mac Pwr, | ||
393 | * 2 - From ASPM setting with low Mac Pwr, | ||
394 | * 3 - Bus D3 | ||
395 | * set default to RTL8192CE:0 RTL8192SE:2 | ||
396 | */ | ||
397 | rtlpci->const_hwsw_rfoff_d3 = 0; | ||
398 | |||
399 | /* | ||
400 | * This setting works for those device with | ||
401 | * backdoor ASPM setting such as EPHY setting. | ||
402 | * 0 - Not support ASPM, | ||
403 | * 1 - Support ASPM, | ||
404 | * 2 - According to chipset. | ||
405 | */ | ||
406 | rtlpci->const_support_pciaspm = 1; | ||
407 | |||
408 | _rtl_pci_initialize_adapter_common(hw); | ||
409 | } | ||
410 | |||
411 | static void _rtl_pci_io_handler_init(struct device *dev, | 423 | static void _rtl_pci_io_handler_init(struct device *dev, |
412 | struct ieee80211_hw *hw) | 424 | struct ieee80211_hw *hw) |
413 | { | 425 | { |
@@ -429,6 +441,90 @@ static void _rtl_pci_io_handler_release(struct ieee80211_hw *hw) | |||
429 | { | 441 | { |
430 | } | 442 | } |
431 | 443 | ||
444 | static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw, | ||
445 | struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc, u8 tid) | ||
446 | { | ||
447 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
448 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
449 | u8 additionlen = FCS_LEN; | ||
450 | struct sk_buff *next_skb; | ||
451 | |||
452 | /* here open is 4, wep/tkip is 8, aes is 12*/ | ||
453 | if (info->control.hw_key) | ||
454 | additionlen += info->control.hw_key->icv_len; | ||
455 | |||
456 | /* The most skb num is 6 */ | ||
457 | tcb_desc->empkt_num = 0; | ||
458 | spin_lock_bh(&rtlpriv->locks.waitq_lock); | ||
459 | skb_queue_walk(&rtlpriv->mac80211.skb_waitq[tid], next_skb) { | ||
460 | struct ieee80211_tx_info *next_info; | ||
461 | |||
462 | next_info = IEEE80211_SKB_CB(next_skb); | ||
463 | if (next_info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
464 | tcb_desc->empkt_len[tcb_desc->empkt_num] = | ||
465 | next_skb->len + additionlen; | ||
466 | tcb_desc->empkt_num++; | ||
467 | } else { | ||
468 | break; | ||
469 | } | ||
470 | |||
471 | if (skb_queue_is_last(&rtlpriv->mac80211.skb_waitq[tid], | ||
472 | next_skb)) | ||
473 | break; | ||
474 | |||
475 | if (tcb_desc->empkt_num >= 5) | ||
476 | break; | ||
477 | } | ||
478 | spin_unlock_bh(&rtlpriv->locks.waitq_lock); | ||
479 | |||
480 | return true; | ||
481 | } | ||
482 | |||
483 | /* just for early mode now */ | ||
484 | static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw) | ||
485 | { | ||
486 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
487 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
488 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
489 | struct sk_buff *skb = NULL; | ||
490 | struct ieee80211_tx_info *info = NULL; | ||
491 | int tid; /* should be int */ | ||
492 | |||
493 | if (!rtlpriv->rtlhal.earlymode_enable) | ||
494 | return; | ||
495 | |||
496 | /* we juse use em for BE/BK/VI/VO */ | ||
497 | for (tid = 7; tid >= 0; tid--) { | ||
498 | u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(hw, tid)]; | ||
499 | struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; | ||
500 | while (!mac->act_scanning && | ||
501 | rtlpriv->psc.rfpwr_state == ERFON) { | ||
502 | struct rtl_tcb_desc tcb_desc; | ||
503 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | ||
504 | |||
505 | spin_lock_bh(&rtlpriv->locks.waitq_lock); | ||
506 | if (!skb_queue_empty(&mac->skb_waitq[tid]) && | ||
507 | (ring->entries - skb_queue_len(&ring->queue) > 5)) { | ||
508 | skb = skb_dequeue(&mac->skb_waitq[tid]); | ||
509 | } else { | ||
510 | spin_unlock_bh(&rtlpriv->locks.waitq_lock); | ||
511 | break; | ||
512 | } | ||
513 | spin_unlock_bh(&rtlpriv->locks.waitq_lock); | ||
514 | |||
515 | /* Some macaddr can't do early mode. like | ||
516 | * multicast/broadcast/no_qos data */ | ||
517 | info = IEEE80211_SKB_CB(skb); | ||
518 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||
519 | _rtl_update_earlymode_info(hw, skb, | ||
520 | &tcb_desc, tid); | ||
521 | |||
522 | rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); | ||
523 | } | ||
524 | } | ||
525 | } | ||
526 | |||
527 | |||
432 | static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) | 528 | static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) |
433 | { | 529 | { |
434 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 530 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -440,6 +536,8 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) | |||
440 | struct rtl_tx_desc *entry = &ring->desc[ring->idx]; | 536 | struct rtl_tx_desc *entry = &ring->desc[ring->idx]; |
441 | struct sk_buff *skb; | 537 | struct sk_buff *skb; |
442 | struct ieee80211_tx_info *info; | 538 | struct ieee80211_tx_info *info; |
539 | __le16 fc; | ||
540 | u8 tid; | ||
443 | 541 | ||
444 | u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true, | 542 | u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true, |
445 | HW_DESC_OWN); | 543 | HW_DESC_OWN); |
@@ -460,6 +558,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) | |||
460 | HW_DESC_TXBUFF_ADDR), | 558 | HW_DESC_TXBUFF_ADDR), |
461 | skb->len, PCI_DMA_TODEVICE); | 559 | skb->len, PCI_DMA_TODEVICE); |
462 | 560 | ||
561 | /* remove early mode header */ | ||
562 | if (rtlpriv->rtlhal.earlymode_enable) | ||
563 | skb_pull(skb, EM_HDR_LEN); | ||
564 | |||
463 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, | 565 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, |
464 | ("new ring->idx:%d, " | 566 | ("new ring->idx:%d, " |
465 | "free: skb_queue_len:%d, free: seq:%x\n", | 567 | "free: skb_queue_len:%d, free: seq:%x\n", |
@@ -467,6 +569,30 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) | |||
467 | skb_queue_len(&ring->queue), | 569 | skb_queue_len(&ring->queue), |
468 | *(u16 *) (skb->data + 22))); | 570 | *(u16 *) (skb->data + 22))); |
469 | 571 | ||
572 | if (prio == TXCMD_QUEUE) { | ||
573 | dev_kfree_skb(skb); | ||
574 | goto tx_status_ok; | ||
575 | |||
576 | } | ||
577 | |||
578 | /* for sw LPS, just after NULL skb send out, we can | ||
579 | * sure AP kown we are sleeped, our we should not let | ||
580 | * rf to sleep*/ | ||
581 | fc = rtl_get_fc(skb); | ||
582 | if (ieee80211_is_nullfunc(fc)) { | ||
583 | if (ieee80211_has_pm(fc)) { | ||
584 | rtlpriv->mac80211.offchan_deley = true; | ||
585 | rtlpriv->psc.state_inap = 1; | ||
586 | } else { | ||
587 | rtlpriv->psc.state_inap = 0; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | /* update tid tx pkt num */ | ||
592 | tid = rtl_get_tid(skb); | ||
593 | if (tid <= 7) | ||
594 | rtlpriv->link_info.tidtx_inperiod[tid]++; | ||
595 | |||
470 | info = IEEE80211_SKB_CB(skb); | 596 | info = IEEE80211_SKB_CB(skb); |
471 | ieee80211_tx_info_clear_status(info); | 597 | ieee80211_tx_info_clear_status(info); |
472 | 598 | ||
@@ -489,7 +615,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) | |||
489 | skb_get_queue_mapping | 615 | skb_get_queue_mapping |
490 | (skb)); | 616 | (skb)); |
491 | } | 617 | } |
492 | 618 | tx_status_ok: | |
493 | skb = NULL; | 619 | skb = NULL; |
494 | } | 620 | } |
495 | 621 | ||
@@ -561,23 +687,21 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
561 | *skb_trim(skb, skb->len - 4); | 687 | *skb_trim(skb, skb->len - 4); |
562 | */ | 688 | */ |
563 | 689 | ||
564 | hdr = (struct ieee80211_hdr *)(skb->data); | 690 | hdr = rtl_get_hdr(skb); |
565 | fc = hdr->frame_control; | 691 | fc = rtl_get_fc(skb); |
566 | 692 | ||
567 | if (!stats.crc) { | 693 | if (!stats.crc || !stats.hwerror) { |
568 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, | 694 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, |
569 | sizeof(rx_status)); | 695 | sizeof(rx_status)); |
570 | 696 | ||
571 | if (is_broadcast_ether_addr(hdr->addr1)) | 697 | if (is_broadcast_ether_addr(hdr->addr1)) { |
572 | ;/*TODO*/ | 698 | ;/*TODO*/ |
573 | else { | 699 | } else if (is_multicast_ether_addr(hdr->addr1)) { |
574 | if (is_multicast_ether_addr(hdr->addr1)) | 700 | ;/*TODO*/ |
575 | ;/*TODO*/ | 701 | } else { |
576 | else { | 702 | unicast = true; |
577 | unicast = true; | 703 | rtlpriv->stats.rxbytesunicast += |
578 | rtlpriv->stats.rxbytesunicast += | 704 | skb->len; |
579 | skb->len; | ||
580 | } | ||
581 | } | 705 | } |
582 | 706 | ||
583 | rtl_is_special_data(hw, skb, false); | 707 | rtl_is_special_data(hw, skb, false); |
@@ -591,28 +715,38 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
591 | num_rx_inperiod++; | 715 | num_rx_inperiod++; |
592 | } | 716 | } |
593 | 717 | ||
594 | if (unlikely(!rtl_action_proc(hw, skb, | 718 | /* for sw lps */ |
595 | false))) { | 719 | rtl_swlps_beacon(hw, (void *)skb->data, |
720 | skb->len); | ||
721 | rtl_recognize_peer(hw, (void *)skb->data, | ||
722 | skb->len); | ||
723 | if ((rtlpriv->mac80211.opmode == | ||
724 | NL80211_IFTYPE_AP) && | ||
725 | (rtlpriv->rtlhal.current_bandtype == | ||
726 | BAND_ON_2_4G) && | ||
727 | (ieee80211_is_beacon(fc) || | ||
728 | ieee80211_is_probe_resp(fc))) { | ||
596 | dev_kfree_skb_any(skb); | 729 | dev_kfree_skb_any(skb); |
597 | } else { | 730 | } else { |
598 | struct sk_buff *uskb = NULL; | 731 | if (unlikely(!rtl_action_proc(hw, skb, |
599 | u8 *pdata; | 732 | false))) { |
600 | uskb = dev_alloc_skb(skb->len + 128); | 733 | dev_kfree_skb_any(skb); |
601 | if (!uskb) { | 734 | } else { |
602 | RT_TRACE(rtlpriv, | 735 | struct sk_buff *uskb = NULL; |
603 | (COMP_INTR | COMP_RECV), | 736 | u8 *pdata; |
604 | DBG_EMERG, | 737 | uskb = dev_alloc_skb(skb->len |
605 | ("can't alloc rx skb\n")); | 738 | + 128); |
606 | goto done; | 739 | memcpy(IEEE80211_SKB_RXCB(uskb), |
740 | &rx_status, | ||
741 | sizeof(rx_status)); | ||
742 | pdata = (u8 *)skb_put(uskb, | ||
743 | skb->len); | ||
744 | memcpy(pdata, skb->data, | ||
745 | skb->len); | ||
746 | dev_kfree_skb_any(skb); | ||
747 | |||
748 | ieee80211_rx_irqsafe(hw, uskb); | ||
607 | } | 749 | } |
608 | memcpy(IEEE80211_SKB_RXCB(uskb), | ||
609 | &rx_status, | ||
610 | sizeof(rx_status)); | ||
611 | pdata = (u8 *)skb_put(uskb, skb->len); | ||
612 | memcpy(pdata, skb->data, skb->len); | ||
613 | dev_kfree_skb_any(skb); | ||
614 | |||
615 | ieee80211_rx_irqsafe(hw, uskb); | ||
616 | } | 750 | } |
617 | } else { | 751 | } else { |
618 | dev_kfree_skb_any(skb); | 752 | dev_kfree_skb_any(skb); |
@@ -627,7 +761,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
627 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); | 761 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); |
628 | if (unlikely(!new_skb)) { | 762 | if (unlikely(!new_skb)) { |
629 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), | 763 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), |
630 | DBG_EMERG, | 764 | DBG_DMESG, |
631 | ("can't alloc skb for rx\n")); | 765 | ("can't alloc skb for rx\n")); |
632 | goto done; | 766 | goto done; |
633 | } | 767 | } |
@@ -645,7 +779,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
645 | 779 | ||
646 | } | 780 | } |
647 | done: | 781 | done: |
648 | bufferaddress = (u32)(*((dma_addr_t *) skb->cb)); | 782 | bufferaddress = (*((dma_addr_t *)skb->cb)); |
649 | tmp_one = 1; | 783 | tmp_one = 1; |
650 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, | 784 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, |
651 | HW_DESC_RXBUFF_ADDR, | 785 | HW_DESC_RXBUFF_ADDR, |
@@ -674,6 +808,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) | |||
674 | struct ieee80211_hw *hw = dev_id; | 808 | struct ieee80211_hw *hw = dev_id; |
675 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 809 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
676 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 810 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
811 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
677 | unsigned long flags; | 812 | unsigned long flags; |
678 | u32 inta = 0; | 813 | u32 inta = 0; |
679 | u32 intb = 0; | 814 | u32 intb = 0; |
@@ -760,23 +895,36 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) | |||
760 | _rtl_pci_tx_isr(hw, VO_QUEUE); | 895 | _rtl_pci_tx_isr(hw, VO_QUEUE); |
761 | } | 896 | } |
762 | 897 | ||
898 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { | ||
899 | if (inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) { | ||
900 | rtlpriv->link_info.num_tx_inperiod++; | ||
901 | |||
902 | RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, | ||
903 | ("CMD TX OK interrupt!\n")); | ||
904 | _rtl_pci_tx_isr(hw, TXCMD_QUEUE); | ||
905 | } | ||
906 | } | ||
907 | |||
763 | /*<2> Rx related */ | 908 | /*<2> Rx related */ |
764 | if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { | 909 | if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { |
765 | RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n")); | 910 | RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n")); |
766 | tasklet_schedule(&rtlpriv->works.irq_tasklet); | 911 | _rtl_pci_rx_interrupt(hw); |
767 | } | 912 | } |
768 | 913 | ||
769 | if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { | 914 | if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { |
770 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 915 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
771 | ("rx descriptor unavailable!\n")); | 916 | ("rx descriptor unavailable!\n")); |
772 | tasklet_schedule(&rtlpriv->works.irq_tasklet); | 917 | _rtl_pci_rx_interrupt(hw); |
773 | } | 918 | } |
774 | 919 | ||
775 | if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { | 920 | if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { |
776 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n")); | 921 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n")); |
777 | tasklet_schedule(&rtlpriv->works.irq_tasklet); | 922 | _rtl_pci_rx_interrupt(hw); |
778 | } | 923 | } |
779 | 924 | ||
925 | if (rtlpriv->rtlhal.earlymode_enable) | ||
926 | tasklet_schedule(&rtlpriv->works.irq_tasklet); | ||
927 | |||
780 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | 928 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); |
781 | return IRQ_HANDLED; | 929 | return IRQ_HANDLED; |
782 | 930 | ||
@@ -787,7 +935,7 @@ done: | |||
787 | 935 | ||
788 | static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw) | 936 | static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw) |
789 | { | 937 | { |
790 | _rtl_pci_rx_interrupt(hw); | 938 | _rtl_pci_tx_chk_waitq(hw); |
791 | } | 939 | } |
792 | 940 | ||
793 | static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | 941 | static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) |
@@ -795,14 +943,15 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | |||
795 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 943 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
796 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 944 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
797 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 945 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
798 | struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; | 946 | struct rtl8192_tx_ring *ring = NULL; |
799 | struct ieee80211_hdr *hdr = NULL; | 947 | struct ieee80211_hdr *hdr = NULL; |
800 | struct ieee80211_tx_info *info = NULL; | 948 | struct ieee80211_tx_info *info = NULL; |
801 | struct sk_buff *pskb = NULL; | 949 | struct sk_buff *pskb = NULL; |
802 | struct rtl_tx_desc *pdesc = NULL; | 950 | struct rtl_tx_desc *pdesc = NULL; |
803 | unsigned int queue_index; | 951 | struct rtl_tcb_desc tcb_desc; |
804 | u8 temp_one = 1; | 952 | u8 temp_one = 1; |
805 | 953 | ||
954 | memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | ||
806 | ring = &rtlpci->tx_ring[BEACON_QUEUE]; | 955 | ring = &rtlpci->tx_ring[BEACON_QUEUE]; |
807 | pskb = __skb_dequeue(&ring->queue); | 956 | pskb = __skb_dequeue(&ring->queue); |
808 | if (pskb) | 957 | if (pskb) |
@@ -812,14 +961,11 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | |||
812 | pskb = ieee80211_beacon_get(hw, mac->vif); | 961 | pskb = ieee80211_beacon_get(hw, mac->vif); |
813 | if (pskb == NULL) | 962 | if (pskb == NULL) |
814 | return; | 963 | return; |
815 | hdr = (struct ieee80211_hdr *)(pskb->data); | 964 | hdr = rtl_get_hdr(pskb); |
816 | info = IEEE80211_SKB_CB(pskb); | 965 | info = IEEE80211_SKB_CB(pskb); |
817 | |||
818 | queue_index = BEACON_QUEUE; | ||
819 | |||
820 | pdesc = &ring->desc[0]; | 966 | pdesc = &ring->desc[0]; |
821 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, | 967 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, |
822 | info, pskb, queue_index); | 968 | info, pskb, BEACON_QUEUE, &tcb_desc); |
823 | 969 | ||
824 | __skb_queue_tail(&ring->queue, pskb); | 970 | __skb_queue_tail(&ring->queue, pskb); |
825 | 971 | ||
@@ -861,7 +1007,6 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw, | |||
861 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1007 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
862 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 1008 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
863 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 1009 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
864 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
865 | 1010 | ||
866 | rtlpci->up_first_time = true; | 1011 | rtlpci->up_first_time = true; |
867 | rtlpci->being_init_adapter = false; | 1012 | rtlpci->being_init_adapter = false; |
@@ -869,31 +1014,20 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw, | |||
869 | rtlhal->hw = hw; | 1014 | rtlhal->hw = hw; |
870 | rtlpci->pdev = pdev; | 1015 | rtlpci->pdev = pdev; |
871 | 1016 | ||
872 | ppsc->inactiveps = false; | ||
873 | ppsc->leisure_ps = true; | ||
874 | ppsc->fwctrl_lps = true; | ||
875 | ppsc->reg_fwctrl_lps = 3; | ||
876 | ppsc->reg_max_lps_awakeintvl = 5; | ||
877 | |||
878 | if (ppsc->reg_fwctrl_lps == 1) | ||
879 | ppsc->fwctrl_psmode = FW_PS_MIN_MODE; | ||
880 | else if (ppsc->reg_fwctrl_lps == 2) | ||
881 | ppsc->fwctrl_psmode = FW_PS_MAX_MODE; | ||
882 | else if (ppsc->reg_fwctrl_lps == 3) | ||
883 | ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; | ||
884 | |||
885 | /*Tx/Rx related var */ | 1017 | /*Tx/Rx related var */ |
886 | _rtl_pci_init_trx_var(hw); | 1018 | _rtl_pci_init_trx_var(hw); |
887 | 1019 | ||
888 | /*IBSS*/ mac->beacon_interval = 100; | 1020 | /*IBSS*/ mac->beacon_interval = 100; |
889 | 1021 | ||
890 | /*AMPDU*/ mac->min_space_cfg = 0; | 1022 | /*AMPDU*/ |
1023 | mac->min_space_cfg = 0; | ||
891 | mac->max_mss_density = 0; | 1024 | mac->max_mss_density = 0; |
892 | /*set sane AMPDU defaults */ | 1025 | /*set sane AMPDU defaults */ |
893 | mac->current_ampdu_density = 7; | 1026 | mac->current_ampdu_density = 7; |
894 | mac->current_ampdu_factor = 3; | 1027 | mac->current_ampdu_factor = 3; |
895 | 1028 | ||
896 | /*QOS*/ rtlpci->acm_method = eAcmWay2_SW; | 1029 | /*QOS*/ |
1030 | rtlpci->acm_method = eAcmWay2_SW; | ||
897 | 1031 | ||
898 | /*task */ | 1032 | /*task */ |
899 | tasklet_init(&rtlpriv->works.irq_tasklet, | 1033 | tasklet_init(&rtlpriv->works.irq_tasklet, |
@@ -934,7 +1068,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, | |||
934 | ("queue:%d, ring_addr:%p\n", prio, ring)); | 1068 | ("queue:%d, ring_addr:%p\n", prio, ring)); |
935 | 1069 | ||
936 | for (i = 0; i < entries; i++) { | 1070 | for (i = 0; i < entries; i++) { |
937 | nextdescaddress = (u32) dma + ((i + 1) % entries) * | 1071 | nextdescaddress = (u32) dma + |
1072 | ((i + 1) % entries) * | ||
938 | sizeof(*ring); | 1073 | sizeof(*ring); |
939 | 1074 | ||
940 | rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), | 1075 | rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), |
@@ -999,7 +1134,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) | |||
999 | rtlpci->rxbuffersize, | 1134 | rtlpci->rxbuffersize, |
1000 | PCI_DMA_FROMDEVICE); | 1135 | PCI_DMA_FROMDEVICE); |
1001 | 1136 | ||
1002 | bufferaddress = (u32)(*((dma_addr_t *)skb->cb)); | 1137 | bufferaddress = (*((dma_addr_t *)skb->cb)); |
1003 | rtlpriv->cfg->ops->set_desc((u8 *)entry, false, | 1138 | rtlpriv->cfg->ops->set_desc((u8 *)entry, false, |
1004 | HW_DESC_RXBUFF_ADDR, | 1139 | HW_DESC_RXBUFF_ADDR, |
1005 | (u8 *)&bufferaddress); | 1140 | (u8 *)&bufferaddress); |
@@ -1182,72 +1317,73 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) | |||
1182 | return 0; | 1317 | return 0; |
1183 | } | 1318 | } |
1184 | 1319 | ||
1185 | static unsigned int _rtl_mac_to_hwqueue(__le16 fc, | 1320 | static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, |
1186 | unsigned int mac80211_queue_index) | 1321 | struct sk_buff *skb) |
1187 | { | 1322 | { |
1188 | unsigned int hw_queue_index; | 1323 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1189 | 1324 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | |
1190 | if (unlikely(ieee80211_is_beacon(fc))) { | 1325 | struct ieee80211_sta *sta = info->control.sta; |
1191 | hw_queue_index = BEACON_QUEUE; | 1326 | struct rtl_sta_info *sta_entry = NULL; |
1192 | goto out; | 1327 | u8 tid = rtl_get_tid(skb); |
1193 | } | 1328 | |
1194 | 1329 | if (!sta) | |
1195 | if (ieee80211_is_mgmt(fc)) { | 1330 | return false; |
1196 | hw_queue_index = MGNT_QUEUE; | 1331 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; |
1197 | goto out; | 1332 | |
1198 | } | 1333 | if (!rtlpriv->rtlhal.earlymode_enable) |
1199 | 1334 | return false; | |
1200 | switch (mac80211_queue_index) { | 1335 | if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL) |
1201 | case 0: | 1336 | return false; |
1202 | hw_queue_index = VO_QUEUE; | 1337 | if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE) |
1203 | break; | 1338 | return false; |
1204 | case 1: | 1339 | if (tid > 7) |
1205 | hw_queue_index = VI_QUEUE; | 1340 | return false; |
1206 | break; | 1341 | |
1207 | case 2: | 1342 | /* maybe every tid should be checked */ |
1208 | hw_queue_index = BE_QUEUE;; | 1343 | if (!rtlpriv->link_info.higher_busytxtraffic[tid]) |
1209 | break; | 1344 | return false; |
1210 | case 3: | 1345 | |
1211 | hw_queue_index = BK_QUEUE; | 1346 | spin_lock_bh(&rtlpriv->locks.waitq_lock); |
1212 | break; | 1347 | skb_queue_tail(&rtlpriv->mac80211.skb_waitq[tid], skb); |
1213 | default: | 1348 | spin_unlock_bh(&rtlpriv->locks.waitq_lock); |
1214 | hw_queue_index = BE_QUEUE; | ||
1215 | RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n", | ||
1216 | mac80211_queue_index)); | ||
1217 | break; | ||
1218 | } | ||
1219 | 1349 | ||
1220 | out: | 1350 | return true; |
1221 | return hw_queue_index; | ||
1222 | } | 1351 | } |
1223 | 1352 | ||
1224 | static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 1353 | static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, |
1354 | struct rtl_tcb_desc *ptcb_desc) | ||
1225 | { | 1355 | { |
1226 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1356 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1227 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1357 | struct rtl_sta_info *sta_entry = NULL; |
1228 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1358 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1359 | struct ieee80211_sta *sta = info->control.sta; | ||
1229 | struct rtl8192_tx_ring *ring; | 1360 | struct rtl8192_tx_ring *ring; |
1230 | struct rtl_tx_desc *pdesc; | 1361 | struct rtl_tx_desc *pdesc; |
1231 | u8 idx; | 1362 | u8 idx; |
1232 | unsigned int queue_index, hw_queue; | 1363 | u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb); |
1233 | unsigned long flags; | 1364 | unsigned long flags; |
1234 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 1365 | struct ieee80211_hdr *hdr = rtl_get_hdr(skb); |
1235 | __le16 fc = hdr->frame_control; | 1366 | __le16 fc = rtl_get_fc(skb); |
1236 | u8 *pda_addr = hdr->addr1; | 1367 | u8 *pda_addr = hdr->addr1; |
1237 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 1368 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
1238 | /*ssn */ | 1369 | /*ssn */ |
1239 | u8 *qc = NULL; | ||
1240 | u8 tid = 0; | 1370 | u8 tid = 0; |
1241 | u16 seq_number = 0; | 1371 | u16 seq_number = 0; |
1242 | u8 own; | 1372 | u8 own; |
1243 | u8 temp_one = 1; | 1373 | u8 temp_one = 1; |
1244 | 1374 | ||
1245 | if (ieee80211_is_mgmt(fc)) | 1375 | if (ieee80211_is_auth(fc)) { |
1246 | rtl_tx_mgmt_proc(hw, skb); | 1376 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); |
1247 | rtl_action_proc(hw, skb, true); | 1377 | rtl_ips_nic_on(hw); |
1378 | } | ||
1379 | |||
1380 | if (rtlpriv->psc.sw_ps_enabled) { | ||
1381 | if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && | ||
1382 | !ieee80211_has_pm(fc)) | ||
1383 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); | ||
1384 | } | ||
1248 | 1385 | ||
1249 | queue_index = skb_get_queue_mapping(skb); | 1386 | rtl_action_proc(hw, skb, true); |
1250 | hw_queue = _rtl_mac_to_hwqueue(fc, queue_index); | ||
1251 | 1387 | ||
1252 | if (is_multicast_ether_addr(pda_addr)) | 1388 | if (is_multicast_ether_addr(pda_addr)) |
1253 | rtlpriv->stats.txbytesmulticast += skb->len; | 1389 | rtlpriv->stats.txbytesmulticast += skb->len; |
@@ -1257,7 +1393,6 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1257 | rtlpriv->stats.txbytesunicast += skb->len; | 1393 | rtlpriv->stats.txbytesunicast += skb->len; |
1258 | 1394 | ||
1259 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); | 1395 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); |
1260 | |||
1261 | ring = &rtlpci->tx_ring[hw_queue]; | 1396 | ring = &rtlpci->tx_ring[hw_queue]; |
1262 | if (hw_queue != BEACON_QUEUE) | 1397 | if (hw_queue != BEACON_QUEUE) |
1263 | idx = (ring->idx + skb_queue_len(&ring->queue)) % | 1398 | idx = (ring->idx + skb_queue_len(&ring->queue)) % |
@@ -1280,43 +1415,30 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1280 | return skb->len; | 1415 | return skb->len; |
1281 | } | 1416 | } |
1282 | 1417 | ||
1283 | /* | ||
1284 | *if(ieee80211_is_nullfunc(fc)) { | ||
1285 | * spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | ||
1286 | * return 1; | ||
1287 | *} | ||
1288 | */ | ||
1289 | |||
1290 | if (ieee80211_is_data_qos(fc)) { | 1418 | if (ieee80211_is_data_qos(fc)) { |
1291 | qc = ieee80211_get_qos_ctl(hdr); | 1419 | tid = rtl_get_tid(skb); |
1292 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 1420 | if (sta) { |
1293 | 1421 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; | |
1294 | seq_number = mac->tids[tid].seq_number; | 1422 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & |
1295 | seq_number &= IEEE80211_SCTL_SEQ; | 1423 | IEEE80211_SCTL_SEQ) >> 4; |
1296 | /* | 1424 | seq_number += 1; |
1297 | *hdr->seq_ctrl = hdr->seq_ctrl & | 1425 | |
1298 | *cpu_to_le16(IEEE80211_SCTL_FRAG); | 1426 | if (!ieee80211_has_morefrags(hdr->frame_control)) |
1299 | *hdr->seq_ctrl |= cpu_to_le16(seq_number); | 1427 | sta_entry->tids[tid].seq_number = seq_number; |
1300 | */ | 1428 | } |
1301 | |||
1302 | seq_number += 1; | ||
1303 | } | 1429 | } |
1304 | 1430 | ||
1305 | if (ieee80211_is_data(fc)) | 1431 | if (ieee80211_is_data(fc)) |
1306 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); | 1432 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); |
1307 | 1433 | ||
1308 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, | 1434 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, |
1309 | info, skb, hw_queue); | 1435 | info, skb, hw_queue, ptcb_desc); |
1310 | 1436 | ||
1311 | __skb_queue_tail(&ring->queue, skb); | 1437 | __skb_queue_tail(&ring->queue, skb); |
1312 | 1438 | ||
1313 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, | 1439 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true, |
1314 | HW_DESC_OWN, (u8 *)&temp_one); | 1440 | HW_DESC_OWN, (u8 *)&temp_one); |
1315 | 1441 | ||
1316 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | ||
1317 | if (qc) | ||
1318 | mac->tids[tid].seq_number = seq_number; | ||
1319 | } | ||
1320 | 1442 | ||
1321 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && | 1443 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && |
1322 | hw_queue != BEACON_QUEUE) { | 1444 | hw_queue != BEACON_QUEUE) { |
@@ -1338,6 +1460,35 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1338 | return 0; | 1460 | return 0; |
1339 | } | 1461 | } |
1340 | 1462 | ||
1463 | static void rtl_pci_flush(struct ieee80211_hw *hw, bool drop) | ||
1464 | { | ||
1465 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1466 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1467 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1468 | u16 i = 0; | ||
1469 | int queue_id; | ||
1470 | struct rtl8192_tx_ring *ring; | ||
1471 | |||
1472 | for (queue_id = RTL_PCI_MAX_TX_QUEUE_COUNT - 1; queue_id >= 0;) { | ||
1473 | u32 queue_len; | ||
1474 | ring = &pcipriv->dev.tx_ring[queue_id]; | ||
1475 | queue_len = skb_queue_len(&ring->queue); | ||
1476 | if (queue_len == 0 || queue_id == BEACON_QUEUE || | ||
1477 | queue_id == TXCMD_QUEUE) { | ||
1478 | queue_id--; | ||
1479 | continue; | ||
1480 | } else { | ||
1481 | msleep(20); | ||
1482 | i++; | ||
1483 | } | ||
1484 | |||
1485 | /* we just wait 1s for all queues */ | ||
1486 | if (rtlpriv->psc.rfpwr_state == ERFOFF || | ||
1487 | is_hal_stop(rtlhal) || i >= 200) | ||
1488 | return; | ||
1489 | } | ||
1490 | } | ||
1491 | |||
1341 | static void rtl_pci_deinit(struct ieee80211_hw *hw) | 1492 | static void rtl_pci_deinit(struct ieee80211_hw *hw) |
1342 | { | 1493 | { |
1343 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1494 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -1456,11 +1607,13 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, | |||
1456 | struct pci_dev *bridge_pdev = pdev->bus->self; | 1607 | struct pci_dev *bridge_pdev = pdev->bus->self; |
1457 | u16 venderid; | 1608 | u16 venderid; |
1458 | u16 deviceid; | 1609 | u16 deviceid; |
1610 | u8 revisionid; | ||
1459 | u16 irqline; | 1611 | u16 irqline; |
1460 | u8 tmp; | 1612 | u8 tmp; |
1461 | 1613 | ||
1462 | venderid = pdev->vendor; | 1614 | venderid = pdev->vendor; |
1463 | deviceid = pdev->device; | 1615 | deviceid = pdev->device; |
1616 | pci_read_config_byte(pdev, 0x8, &revisionid); | ||
1464 | pci_read_config_word(pdev, 0x3C, &irqline); | 1617 | pci_read_config_word(pdev, 0x3C, &irqline); |
1465 | 1618 | ||
1466 | if (deviceid == RTL_PCI_8192_DID || | 1619 | if (deviceid == RTL_PCI_8192_DID || |
@@ -1471,7 +1624,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, | |||
1471 | deviceid == RTL_PCI_8173_DID || | 1624 | deviceid == RTL_PCI_8173_DID || |
1472 | deviceid == RTL_PCI_8172_DID || | 1625 | deviceid == RTL_PCI_8172_DID || |
1473 | deviceid == RTL_PCI_8171_DID) { | 1626 | deviceid == RTL_PCI_8171_DID) { |
1474 | switch (pdev->revision) { | 1627 | switch (revisionid) { |
1475 | case RTL_PCI_REVISION_ID_8192PCIE: | 1628 | case RTL_PCI_REVISION_ID_8192PCIE: |
1476 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | 1629 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
1477 | ("8192 PCI-E is found - " | 1630 | ("8192 PCI-E is found - " |
@@ -1500,6 +1653,12 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, | |||
1500 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | 1653 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
1501 | ("8192C PCI-E is found - " | 1654 | ("8192C PCI-E is found - " |
1502 | "vid/did=%x/%x\n", venderid, deviceid)); | 1655 | "vid/did=%x/%x\n", venderid, deviceid)); |
1656 | } else if (deviceid == RTL_PCI_8192DE_DID || | ||
1657 | deviceid == RTL_PCI_8192DE_DID2) { | ||
1658 | rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE; | ||
1659 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
1660 | ("8192D PCI-E is found - " | ||
1661 | "vid/did=%x/%x\n", venderid, deviceid)); | ||
1503 | } else { | 1662 | } else { |
1504 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 1663 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
1505 | ("Err: Unknown device -" | 1664 | ("Err: Unknown device -" |
@@ -1508,6 +1667,25 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, | |||
1508 | rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; | 1667 | rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; |
1509 | } | 1668 | } |
1510 | 1669 | ||
1670 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) { | ||
1671 | if (revisionid == 0 || revisionid == 1) { | ||
1672 | if (revisionid == 0) { | ||
1673 | RT_TRACE(rtlpriv, COMP_INIT, | ||
1674 | DBG_LOUD, ("Find 92DE MAC0.\n")); | ||
1675 | rtlhal->interfaceindex = 0; | ||
1676 | } else if (revisionid == 1) { | ||
1677 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1678 | ("Find 92DE MAC1.\n")); | ||
1679 | rtlhal->interfaceindex = 1; | ||
1680 | } | ||
1681 | } else { | ||
1682 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1683 | ("Unknown device - " | ||
1684 | "VendorID/DeviceID=%x/%x, Revision=%x\n", | ||
1685 | venderid, deviceid, revisionid)); | ||
1686 | rtlhal->interfaceindex = 0; | ||
1687 | } | ||
1688 | } | ||
1511 | /*find bus info */ | 1689 | /*find bus info */ |
1512 | pcipriv->ndis_adapter.busnumber = pdev->bus->number; | 1690 | pcipriv->ndis_adapter.busnumber = pdev->bus->number; |
1513 | pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); | 1691 | pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); |
@@ -1533,12 +1711,12 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, | |||
1533 | PCI_SLOT(bridge_pdev->devfn); | 1711 | PCI_SLOT(bridge_pdev->devfn); |
1534 | pcipriv->ndis_adapter.pcibridge_funcnum = | 1712 | pcipriv->ndis_adapter.pcibridge_funcnum = |
1535 | PCI_FUNC(bridge_pdev->devfn); | 1713 | PCI_FUNC(bridge_pdev->devfn); |
1536 | pcipriv->ndis_adapter.pcibridge_pciehdr_offset = | ||
1537 | pci_pcie_cap(bridge_pdev); | ||
1538 | pcipriv->ndis_adapter.pcicfg_addrport = | 1714 | pcipriv->ndis_adapter.pcicfg_addrport = |
1539 | (pcipriv->ndis_adapter.pcibridge_busnum << 16) | | 1715 | (pcipriv->ndis_adapter.pcibridge_busnum << 16) | |
1540 | (pcipriv->ndis_adapter.pcibridge_devnum << 11) | | 1716 | (pcipriv->ndis_adapter.pcibridge_devnum << 11) | |
1541 | (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31); | 1717 | (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31); |
1718 | pcipriv->ndis_adapter.pcibridge_pciehdr_offset = | ||
1719 | pci_pcie_cap(bridge_pdev); | ||
1542 | pcipriv->ndis_adapter.num4bytes = | 1720 | pcipriv->ndis_adapter.num4bytes = |
1543 | (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; | 1721 | (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; |
1544 | 1722 | ||
@@ -1621,6 +1799,11 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, | |||
1621 | pcipriv = (void *)rtlpriv->priv; | 1799 | pcipriv = (void *)rtlpriv->priv; |
1622 | pcipriv->dev.pdev = pdev; | 1800 | pcipriv->dev.pdev = pdev; |
1623 | 1801 | ||
1802 | /* init cfg & intf_ops */ | ||
1803 | rtlpriv->rtlhal.interface = INTF_PCI; | ||
1804 | rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); | ||
1805 | rtlpriv->intf_ops = &rtl_pci_ops; | ||
1806 | |||
1624 | /* | 1807 | /* |
1625 | *init dbgp flags before all | 1808 | *init dbgp flags before all |
1626 | *other functions, because we will | 1809 | *other functions, because we will |
@@ -1638,13 +1821,14 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, | |||
1638 | return err; | 1821 | return err; |
1639 | } | 1822 | } |
1640 | 1823 | ||
1641 | pmem_start = pci_resource_start(pdev, 2); | 1824 | pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); |
1642 | pmem_len = pci_resource_len(pdev, 2); | 1825 | pmem_len = pci_resource_len(pdev, rtlpriv->cfg->bar_id); |
1643 | pmem_flags = pci_resource_flags(pdev, 2); | 1826 | pmem_flags = pci_resource_flags(pdev, rtlpriv->cfg->bar_id); |
1644 | 1827 | ||
1645 | /*shared mem start */ | 1828 | /*shared mem start */ |
1646 | rtlpriv->io.pci_mem_start = | 1829 | rtlpriv->io.pci_mem_start = |
1647 | (unsigned long)pci_iomap(pdev, 2, pmem_len); | 1830 | (unsigned long)pci_iomap(pdev, |
1831 | rtlpriv->cfg->bar_id, pmem_len); | ||
1648 | if (rtlpriv->io.pci_mem_start == 0) { | 1832 | if (rtlpriv->io.pci_mem_start == 0) { |
1649 | RT_ASSERT(false, ("Can't map PCI mem\n")); | 1833 | RT_ASSERT(false, ("Can't map PCI mem\n")); |
1650 | goto fail2; | 1834 | goto fail2; |
@@ -1663,11 +1847,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, | |||
1663 | pci_write_config_byte(pdev, 0x04, 0x06); | 1847 | pci_write_config_byte(pdev, 0x04, 0x06); |
1664 | pci_write_config_byte(pdev, 0x04, 0x07); | 1848 | pci_write_config_byte(pdev, 0x04, 0x07); |
1665 | 1849 | ||
1666 | /* init cfg & intf_ops */ | ||
1667 | rtlpriv->rtlhal.interface = INTF_PCI; | ||
1668 | rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); | ||
1669 | rtlpriv->intf_ops = &rtl_pci_ops; | ||
1670 | |||
1671 | /* find adapter */ | 1850 | /* find adapter */ |
1672 | _rtl_pci_find_adapter(pdev, hw); | 1851 | _rtl_pci_find_adapter(pdev, hw); |
1673 | 1852 | ||
@@ -1785,8 +1964,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev) | |||
1785 | 1964 | ||
1786 | rtl_pci_deinit(hw); | 1965 | rtl_pci_deinit(hw); |
1787 | rtl_deinit_core(hw); | 1966 | rtl_deinit_core(hw); |
1788 | if (rtlpriv->cfg->ops->deinit_sw_leds) | ||
1789 | rtlpriv->cfg->ops->deinit_sw_leds(hw); | ||
1790 | _rtl_pci_io_handler_release(hw); | 1967 | _rtl_pci_io_handler_release(hw); |
1791 | rtlpriv->cfg->ops->deinit_sw_vars(hw); | 1968 | rtlpriv->cfg->ops->deinit_sw_vars(hw); |
1792 | 1969 | ||
@@ -1801,6 +1978,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev) | |||
1801 | } | 1978 | } |
1802 | 1979 | ||
1803 | pci_disable_device(pdev); | 1980 | pci_disable_device(pdev); |
1981 | |||
1982 | rtl_pci_disable_aspm(hw); | ||
1983 | |||
1804 | pci_set_drvdata(pdev, NULL); | 1984 | pci_set_drvdata(pdev, NULL); |
1805 | 1985 | ||
1806 | ieee80211_free_hw(hw); | 1986 | ieee80211_free_hw(hw); |
@@ -1824,10 +2004,15 @@ no need to call hw_disable here. | |||
1824 | ****************************************/ | 2004 | ****************************************/ |
1825 | int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 2005 | int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
1826 | { | 2006 | { |
2007 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
2008 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2009 | |||
2010 | rtlpriv->cfg->ops->hw_suspend(hw); | ||
2011 | rtl_deinit_rfkill(hw); | ||
2012 | |||
1827 | pci_save_state(pdev); | 2013 | pci_save_state(pdev); |
1828 | pci_disable_device(pdev); | 2014 | pci_disable_device(pdev); |
1829 | pci_set_power_state(pdev, PCI_D3hot); | 2015 | pci_set_power_state(pdev, PCI_D3hot); |
1830 | |||
1831 | return 0; | 2016 | return 0; |
1832 | } | 2017 | } |
1833 | EXPORT_SYMBOL(rtl_pci_suspend); | 2018 | EXPORT_SYMBOL(rtl_pci_suspend); |
@@ -1835,6 +2020,8 @@ EXPORT_SYMBOL(rtl_pci_suspend); | |||
1835 | int rtl_pci_resume(struct pci_dev *pdev) | 2020 | int rtl_pci_resume(struct pci_dev *pdev) |
1836 | { | 2021 | { |
1837 | int ret; | 2022 | int ret; |
2023 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
2024 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1838 | 2025 | ||
1839 | pci_set_power_state(pdev, PCI_D0); | 2026 | pci_set_power_state(pdev, PCI_D0); |
1840 | ret = pci_enable_device(pdev); | 2027 | ret = pci_enable_device(pdev); |
@@ -1845,15 +2032,20 @@ int rtl_pci_resume(struct pci_dev *pdev) | |||
1845 | 2032 | ||
1846 | pci_restore_state(pdev); | 2033 | pci_restore_state(pdev); |
1847 | 2034 | ||
2035 | rtlpriv->cfg->ops->hw_resume(hw); | ||
2036 | rtl_init_rfkill(hw); | ||
1848 | return 0; | 2037 | return 0; |
1849 | } | 2038 | } |
1850 | EXPORT_SYMBOL(rtl_pci_resume); | 2039 | EXPORT_SYMBOL(rtl_pci_resume); |
1851 | 2040 | ||
1852 | struct rtl_intf_ops rtl_pci_ops = { | 2041 | struct rtl_intf_ops rtl_pci_ops = { |
2042 | .read_efuse_byte = read_efuse_byte, | ||
1853 | .adapter_start = rtl_pci_start, | 2043 | .adapter_start = rtl_pci_start, |
1854 | .adapter_stop = rtl_pci_stop, | 2044 | .adapter_stop = rtl_pci_stop, |
1855 | .adapter_tx = rtl_pci_tx, | 2045 | .adapter_tx = rtl_pci_tx, |
2046 | .flush = rtl_pci_flush, | ||
1856 | .reset_trx_ring = rtl_pci_reset_trx_ring, | 2047 | .reset_trx_ring = rtl_pci_reset_trx_ring, |
2048 | .waitq_insert = rtl_pci_tx_chk_waitq_insert, | ||
1857 | 2049 | ||
1858 | .disable_aspm = rtl_pci_disable_aspm, | 2050 | .disable_aspm = rtl_pci_disable_aspm, |
1859 | .enable_aspm = rtl_pci_enable_aspm, | 2051 | .enable_aspm = rtl_pci_enable_aspm, |
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index 12747b9c71e1..671b1f5aa0cf 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h | |||
@@ -102,8 +102,8 @@ | |||
102 | #define RTL_PCI_8191CE_DID 0x8177 /*8192ce */ | 102 | #define RTL_PCI_8191CE_DID 0x8177 /*8192ce */ |
103 | #define RTL_PCI_8188CE_DID 0x8176 /*8192ce */ | 103 | #define RTL_PCI_8188CE_DID 0x8176 /*8192ce */ |
104 | #define RTL_PCI_8192CU_DID 0x8191 /*8192ce */ | 104 | #define RTL_PCI_8192CU_DID 0x8191 /*8192ce */ |
105 | #define RTL_PCI_8192DE_DID 0x092D /*8192ce */ | 105 | #define RTL_PCI_8192DE_DID 0x8193 /*8192de */ |
106 | #define RTL_PCI_8192DU_DID 0x092D /*8192ce */ | 106 | #define RTL_PCI_8192DE_DID2 0x002B /*92DE*/ |
107 | 107 | ||
108 | /*8192 support 16 pages of IO registers*/ | 108 | /*8192 support 16 pages of IO registers*/ |
109 | #define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000 | 109 | #define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000 |
@@ -129,6 +129,11 @@ enum pci_bridge_vendor { | |||
129 | PCI_BRIDGE_VENDOR_MAX, | 129 | PCI_BRIDGE_VENDOR_MAX, |
130 | }; | 130 | }; |
131 | 131 | ||
132 | struct rtl_pci_capabilities_header { | ||
133 | u8 capability_id; | ||
134 | u8 next; | ||
135 | }; | ||
136 | |||
132 | struct rtl_rx_desc { | 137 | struct rtl_rx_desc { |
133 | u32 dword[8]; | 138 | u32 dword[8]; |
134 | } __packed; | 139 | } __packed; |
@@ -161,7 +166,9 @@ struct rtl_pci { | |||
161 | 166 | ||
162 | bool driver_is_goingto_unload; | 167 | bool driver_is_goingto_unload; |
163 | bool up_first_time; | 168 | bool up_first_time; |
169 | bool first_init; | ||
164 | bool being_init_adapter; | 170 | bool being_init_adapter; |
171 | bool init_ready; | ||
165 | bool irq_enabled; | 172 | bool irq_enabled; |
166 | 173 | ||
167 | /*Tx */ | 174 | /*Tx */ |
@@ -197,6 +204,9 @@ struct rtl_pci { | |||
197 | 204 | ||
198 | /*QOS & EDCA */ | 205 | /*QOS & EDCA */ |
199 | enum acm_method acm_method; | 206 | enum acm_method acm_method; |
207 | |||
208 | u16 shortretry_limit; | ||
209 | u16 longretry_limit; | ||
200 | }; | 210 | }; |
201 | 211 | ||
202 | struct mp_adapter { | 212 | struct mp_adapter { |
@@ -227,6 +237,7 @@ struct rtl_pci_priv { | |||
227 | struct rtl_pci dev; | 237 | struct rtl_pci dev; |
228 | struct mp_adapter ndis_adapter; | 238 | struct mp_adapter ndis_adapter; |
229 | struct rtl_led_ctl ledctl; | 239 | struct rtl_led_ctl ledctl; |
240 | struct bt_coexist_info bt_coexist; | ||
230 | }; | 241 | }; |
231 | 242 | ||
232 | #define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv)) | 243 | #define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv)) |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index c8395fb0c050..2bb71195e976 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -36,7 +36,6 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) | |||
36 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 36 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
37 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 37 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
38 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 38 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
39 | bool init_status = true; | ||
40 | 39 | ||
41 | /*<1> reset trx ring */ | 40 | /*<1> reset trx ring */ |
42 | if (rtlhal->interface == INTF_PCI) | 41 | if (rtlhal->interface == INTF_PCI) |
@@ -49,7 +48,6 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) | |||
49 | /*<2> Enable Adapter */ | 48 | /*<2> Enable Adapter */ |
50 | rtlpriv->cfg->ops->hw_init(hw); | 49 | rtlpriv->cfg->ops->hw_init(hw); |
51 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | 50 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); |
52 | /*init_status = false; */ | ||
53 | 51 | ||
54 | /*<3> Enable Interrupt */ | 52 | /*<3> Enable Interrupt */ |
55 | rtlpriv->cfg->ops->enable_interrupt(hw); | 53 | rtlpriv->cfg->ops->enable_interrupt(hw); |
@@ -57,7 +55,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) | |||
57 | /*<enable timer> */ | 55 | /*<enable timer> */ |
58 | rtl_watch_dog_timer_callback((unsigned long)hw); | 56 | rtl_watch_dog_timer_callback((unsigned long)hw); |
59 | 57 | ||
60 | return init_status; | 58 | return true; |
61 | } | 59 | } |
62 | EXPORT_SYMBOL(rtl_ps_enable_nic); | 60 | EXPORT_SYMBOL(rtl_ps_enable_nic); |
63 | 61 | ||
@@ -192,12 +190,13 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) | |||
192 | 190 | ||
193 | ppsc->swrf_processing = true; | 191 | ppsc->swrf_processing = true; |
194 | 192 | ||
195 | if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) { | 193 | if (ppsc->inactive_pwrstate == ERFOFF && |
194 | rtlhal->interface == INTF_PCI) { | ||
196 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && | 195 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && |
197 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM) && | 196 | RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && |
198 | rtlhal->interface == INTF_PCI) { | 197 | rtlhal->interface == INTF_PCI) { |
199 | rtlpriv->intf_ops->disable_aspm(hw); | 198 | rtlpriv->intf_ops->disable_aspm(hw); |
200 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); | 199 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); |
201 | } | 200 | } |
202 | } | 201 | } |
203 | 202 | ||
@@ -206,9 +205,10 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) | |||
206 | 205 | ||
207 | if (ppsc->inactive_pwrstate == ERFOFF && | 206 | if (ppsc->inactive_pwrstate == ERFOFF && |
208 | rtlhal->interface == INTF_PCI) { | 207 | rtlhal->interface == INTF_PCI) { |
209 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { | 208 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && |
209 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { | ||
210 | rtlpriv->intf_ops->enable_aspm(hw); | 210 | rtlpriv->intf_ops->enable_aspm(hw); |
211 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); | 211 | RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); |
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
@@ -232,6 +232,9 @@ void rtl_ips_nic_off_wq_callback(void *data) | |||
232 | return; | 232 | return; |
233 | } | 233 | } |
234 | 234 | ||
235 | if (mac->link_state > MAC80211_NOLINK) | ||
236 | return; | ||
237 | |||
235 | if (is_hal_stop(rtlhal)) | 238 | if (is_hal_stop(rtlhal)) |
236 | return; | 239 | return; |
237 | 240 | ||
@@ -283,10 +286,14 @@ void rtl_ips_nic_off(struct ieee80211_hw *hw) | |||
283 | void rtl_ips_nic_on(struct ieee80211_hw *hw) | 286 | void rtl_ips_nic_on(struct ieee80211_hw *hw) |
284 | { | 287 | { |
285 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 288 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
289 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
286 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 290 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
287 | enum rf_pwrstate rtstate; | 291 | enum rf_pwrstate rtstate; |
288 | unsigned long flags; | 292 | unsigned long flags; |
289 | 293 | ||
294 | if (mac->opmode != NL80211_IFTYPE_STATION) | ||
295 | return; | ||
296 | |||
290 | spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags); | 297 | spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags); |
291 | 298 | ||
292 | if (ppsc->inactiveps) { | 299 | if (ppsc->inactiveps) { |
@@ -369,8 +376,7 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) | |||
369 | * mode and set RPWM to turn RF on. | 376 | * mode and set RPWM to turn RF on. |
370 | */ | 377 | */ |
371 | 378 | ||
372 | if ((ppsc->fwctrl_lps) && (ppsc->leisure_ps) && | 379 | if ((ppsc->fwctrl_lps) && ppsc->report_linked) { |
373 | ppsc->report_linked) { | ||
374 | bool fw_current_inps; | 380 | bool fw_current_inps; |
375 | if (ppsc->dot11_psmode == EACTIVE) { | 381 | if (ppsc->dot11_psmode == EACTIVE) { |
376 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | 382 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, |
@@ -424,7 +430,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
424 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 430 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
425 | unsigned long flag; | 431 | unsigned long flag; |
426 | 432 | ||
427 | if (!(ppsc->fwctrl_lps && ppsc->leisure_ps)) | 433 | if (!ppsc->fwctrl_lps) |
428 | return; | 434 | return; |
429 | 435 | ||
430 | if (rtlpriv->sec.being_setkey) | 436 | if (rtlpriv->sec.being_setkey) |
@@ -445,17 +451,16 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
445 | 451 | ||
446 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 452 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); |
447 | 453 | ||
448 | if (ppsc->leisure_ps) { | 454 | /* Idle for a while if we connect to AP a while ago. */ |
449 | /* Idle for a while if we connect to AP a while ago. */ | 455 | if (mac->cnt_after_linked >= 2) { |
450 | if (mac->cnt_after_linked >= 2) { | 456 | if (ppsc->dot11_psmode == EACTIVE) { |
451 | if (ppsc->dot11_psmode == EACTIVE) { | 457 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
452 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
453 | ("Enter 802.11 power save mode...\n")); | 458 | ("Enter 802.11 power save mode...\n")); |
454 | 459 | ||
455 | rtl_lps_set_psmode(hw, EAUTOPS); | 460 | rtl_lps_set_psmode(hw, EAUTOPS); |
456 | } | ||
457 | } | 461 | } |
458 | } | 462 | } |
463 | |||
459 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 464 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); |
460 | } | 465 | } |
461 | 466 | ||
@@ -469,17 +474,17 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
469 | 474 | ||
470 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 475 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); |
471 | 476 | ||
472 | if (ppsc->fwctrl_lps && ppsc->leisure_ps) { | 477 | if (ppsc->fwctrl_lps) { |
473 | if (ppsc->dot11_psmode != EACTIVE) { | 478 | if (ppsc->dot11_psmode != EACTIVE) { |
474 | 479 | ||
475 | /*FIX ME */ | 480 | /*FIX ME */ |
476 | rtlpriv->cfg->ops->enable_interrupt(hw); | 481 | rtlpriv->cfg->ops->enable_interrupt(hw); |
477 | 482 | ||
478 | if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && | 483 | if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && |
479 | RT_IN_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM) && | 484 | RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && |
480 | rtlhal->interface == INTF_PCI) { | 485 | rtlhal->interface == INTF_PCI) { |
481 | rtlpriv->intf_ops->disable_aspm(hw); | 486 | rtlpriv->intf_ops->disable_aspm(hw); |
482 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM); | 487 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); |
483 | } | 488 | } |
484 | 489 | ||
485 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 490 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
@@ -490,3 +495,214 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
490 | } | 495 | } |
491 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 496 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); |
492 | } | 497 | } |
498 | |||
499 | /* For sw LPS*/ | ||
500 | void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) | ||
501 | { | ||
502 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
503 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
504 | struct ieee80211_hdr *hdr = (void *) data; | ||
505 | struct ieee80211_tim_ie *tim_ie; | ||
506 | u8 *tim; | ||
507 | u8 tim_len; | ||
508 | bool u_buffed; | ||
509 | bool m_buffed; | ||
510 | |||
511 | if (mac->opmode != NL80211_IFTYPE_STATION) | ||
512 | return; | ||
513 | |||
514 | if (!rtlpriv->psc.swctrl_lps) | ||
515 | return; | ||
516 | |||
517 | if (rtlpriv->mac80211.link_state != MAC80211_LINKED) | ||
518 | return; | ||
519 | |||
520 | if (!rtlpriv->psc.sw_ps_enabled) | ||
521 | return; | ||
522 | |||
523 | if (rtlpriv->psc.fwctrl_lps) | ||
524 | return; | ||
525 | |||
526 | if (likely(!(hw->conf.flags & IEEE80211_CONF_PS))) | ||
527 | return; | ||
528 | |||
529 | /* check if this really is a beacon */ | ||
530 | if (!ieee80211_is_beacon(hdr->frame_control)) | ||
531 | return; | ||
532 | |||
533 | /* min. beacon length + FCS_LEN */ | ||
534 | if (len <= 40 + FCS_LEN) | ||
535 | return; | ||
536 | |||
537 | /* and only beacons from the associated BSSID, please */ | ||
538 | if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid)) | ||
539 | return; | ||
540 | |||
541 | rtlpriv->psc.last_beacon = jiffies; | ||
542 | |||
543 | tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); | ||
544 | if (!tim) | ||
545 | return; | ||
546 | |||
547 | if (tim[1] < sizeof(*tim_ie)) | ||
548 | return; | ||
549 | |||
550 | tim_len = tim[1]; | ||
551 | tim_ie = (struct ieee80211_tim_ie *) &tim[2]; | ||
552 | |||
553 | if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period)) | ||
554 | rtlpriv->psc.dtim_counter = tim_ie->dtim_count; | ||
555 | |||
556 | /* Check whenever the PHY can be turned off again. */ | ||
557 | |||
558 | /* 1. What about buffered unicast traffic for our AID? */ | ||
559 | u_buffed = ieee80211_check_tim(tim_ie, tim_len, | ||
560 | rtlpriv->mac80211.assoc_id); | ||
561 | |||
562 | /* 2. Maybe the AP wants to send multicast/broadcast data? */ | ||
563 | m_buffed = tim_ie->bitmap_ctrl & 0x01; | ||
564 | rtlpriv->psc.multi_buffered = m_buffed; | ||
565 | |||
566 | /* unicast will process by mac80211 through | ||
567 | * set ~IEEE80211_CONF_PS, So we just check | ||
568 | * multicast frames here */ | ||
569 | if (!m_buffed) { | ||
570 | /* back to low-power land. and delay is | ||
571 | * prevent null power save frame tx fail */ | ||
572 | queue_delayed_work(rtlpriv->works.rtl_wq, | ||
573 | &rtlpriv->works.ps_work, MSECS(5)); | ||
574 | } else { | ||
575 | RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, " | ||
576 | "m_buffered: %x\n", u_buffed, m_buffed)); | ||
577 | } | ||
578 | } | ||
579 | |||
580 | void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | ||
581 | { | ||
582 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
583 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
584 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
585 | unsigned long flag; | ||
586 | |||
587 | if (!rtlpriv->psc.swctrl_lps) | ||
588 | return; | ||
589 | if (mac->link_state != MAC80211_LINKED) | ||
590 | return; | ||
591 | |||
592 | if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && | ||
593 | RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { | ||
594 | rtlpriv->intf_ops->disable_aspm(hw); | ||
595 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); | ||
596 | } | ||
597 | |||
598 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | ||
599 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false); | ||
600 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | ||
601 | } | ||
602 | |||
603 | void rtl_swlps_rfon_wq_callback(void *data) | ||
604 | { | ||
605 | struct rtl_works *rtlworks = | ||
606 | container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq); | ||
607 | struct ieee80211_hw *hw = rtlworks->hw; | ||
608 | |||
609 | rtl_swlps_rf_awake(hw); | ||
610 | } | ||
611 | |||
612 | void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | ||
613 | { | ||
614 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
615 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
616 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
617 | unsigned long flag; | ||
618 | u8 sleep_intv; | ||
619 | |||
620 | if (!rtlpriv->psc.sw_ps_enabled) | ||
621 | return; | ||
622 | |||
623 | if ((rtlpriv->sec.being_setkey) || | ||
624 | (mac->opmode == NL80211_IFTYPE_ADHOC)) | ||
625 | return; | ||
626 | |||
627 | /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ | ||
628 | if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5)) | ||
629 | return; | ||
630 | |||
631 | if (rtlpriv->link_info.busytraffic) | ||
632 | return; | ||
633 | |||
634 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | ||
635 | if (rtlpriv->psc.rfchange_inprogress) { | ||
636 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
637 | return; | ||
638 | } | ||
639 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
640 | |||
641 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | ||
642 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false); | ||
643 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | ||
644 | |||
645 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && | ||
646 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { | ||
647 | rtlpriv->intf_ops->enable_aspm(hw); | ||
648 | RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); | ||
649 | } | ||
650 | |||
651 | /* here is power save alg, when this beacon is DTIM | ||
652 | * we will set sleep time to dtim_period * n; | ||
653 | * when this beacon is not DTIM, we will set sleep | ||
654 | * time to sleep_intv = rtlpriv->psc.dtim_counter or | ||
655 | * MAX_SW_LPS_SLEEP_INTV(default set to 5) */ | ||
656 | |||
657 | if (rtlpriv->psc.dtim_counter == 0) { | ||
658 | if (hw->conf.ps_dtim_period == 1) | ||
659 | sleep_intv = hw->conf.ps_dtim_period * 2; | ||
660 | else | ||
661 | sleep_intv = hw->conf.ps_dtim_period; | ||
662 | } else { | ||
663 | sleep_intv = rtlpriv->psc.dtim_counter; | ||
664 | } | ||
665 | |||
666 | if (sleep_intv > MAX_SW_LPS_SLEEP_INTV) | ||
667 | sleep_intv = MAX_SW_LPS_SLEEP_INTV; | ||
668 | |||
669 | /* this print should always be dtim_conter = 0 & | ||
670 | * sleep = dtim_period, that meaons, we should | ||
671 | * awake before every dtim */ | ||
672 | RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, | ||
673 | ("dtim_counter:%x will sleep :%d" | ||
674 | " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv)); | ||
675 | |||
676 | /* we tested that 40ms is enough for sw & hw sw delay */ | ||
677 | queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, | ||
678 | MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40)); | ||
679 | } | ||
680 | |||
681 | |||
682 | void rtl_swlps_wq_callback(void *data) | ||
683 | { | ||
684 | struct rtl_works *rtlworks = container_of_dwork_rtl(data, | ||
685 | struct rtl_works, | ||
686 | ps_work); | ||
687 | struct ieee80211_hw *hw = rtlworks->hw; | ||
688 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
689 | bool ps = false; | ||
690 | |||
691 | ps = (hw->conf.flags & IEEE80211_CONF_PS); | ||
692 | |||
693 | /* we can sleep after ps null send ok */ | ||
694 | if (rtlpriv->psc.state_inap) { | ||
695 | rtl_swlps_rf_sleep(hw); | ||
696 | |||
697 | if (rtlpriv->psc.state && !ps) { | ||
698 | rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies - | ||
699 | rtlpriv->psc.last_action); | ||
700 | } | ||
701 | |||
702 | if (ps) | ||
703 | rtlpriv->psc.last_slept = jiffies; | ||
704 | |||
705 | rtlpriv->psc.last_action = jiffies; | ||
706 | rtlpriv->psc.state = ps; | ||
707 | } | ||
708 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index ae56da801a23..e3bf89840370 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h | |||
@@ -30,6 +30,8 @@ | |||
30 | #ifndef __REALTEK_RTL_PCI_PS_H__ | 30 | #ifndef __REALTEK_RTL_PCI_PS_H__ |
31 | #define __REALTEK_RTL_PCI_PS_H__ | 31 | #define __REALTEK_RTL_PCI_PS_H__ |
32 | 32 | ||
33 | #define MAX_SW_LPS_SLEEP_INTV 5 | ||
34 | |||
33 | bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, | 35 | bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, |
34 | enum rf_pwrstate state_toset, u32 changesource, | 36 | enum rf_pwrstate state_toset, u32 changesource, |
35 | bool protect_or_not); | 37 | bool protect_or_not); |
@@ -40,4 +42,11 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw); | |||
40 | void rtl_ips_nic_off_wq_callback(void *data); | 42 | void rtl_ips_nic_off_wq_callback(void *data); |
41 | void rtl_lps_enter(struct ieee80211_hw *hw); | 43 | void rtl_lps_enter(struct ieee80211_hw *hw); |
42 | void rtl_lps_leave(struct ieee80211_hw *hw); | 44 | void rtl_lps_leave(struct ieee80211_hw *hw); |
45 | |||
46 | void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len); | ||
47 | void rtl_swlps_wq_callback(void *data); | ||
48 | void rtl_swlps_rfon_wq_callback(void *data); | ||
49 | void rtl_swlps_rf_awake(struct ieee80211_hw *hw); | ||
50 | void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); | ||
51 | |||
43 | #endif | 52 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 91634107434a..30da68a77786 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c | |||
@@ -38,17 +38,14 @@ | |||
38 | *CCK11M or OFDM_54M based on wireless mode. | 38 | *CCK11M or OFDM_54M based on wireless mode. |
39 | */ | 39 | */ |
40 | static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, | 40 | static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, |
41 | struct ieee80211_sta *sta, | ||
41 | struct sk_buff *skb, bool not_data) | 42 | struct sk_buff *skb, bool not_data) |
42 | { | 43 | { |
43 | struct rtl_mac *rtlmac = rtl_mac(rtlpriv); | 44 | struct rtl_mac *rtlmac = rtl_mac(rtlpriv); |
44 | 45 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | |
45 | /* | 46 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
46 | *mgt use 1M, although we have check it | 47 | struct rtl_sta_info *sta_entry = NULL; |
47 | *before this function use rate_control_send_low, | 48 | u8 wireless_mode = 0; |
48 | *we still check it here | ||
49 | */ | ||
50 | if (not_data) | ||
51 | return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; | ||
52 | 49 | ||
53 | /* | 50 | /* |
54 | *this rate is no use for true rate, firmware | 51 | *this rate is no use for true rate, firmware |
@@ -57,35 +54,78 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, | |||
57 | *2.in rtl_get_tcb_desc when we check rate is | 54 | *2.in rtl_get_tcb_desc when we check rate is |
58 | * 1M we will not use FW rate but user rate. | 55 | * 1M we will not use FW rate but user rate. |
59 | */ | 56 | */ |
60 | if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) { | 57 | if (rtlmac->opmode == NL80211_IFTYPE_AP || |
61 | return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; | 58 | rtlmac->opmode == NL80211_IFTYPE_ADHOC) { |
59 | if (sta) { | ||
60 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
61 | wireless_mode = sta_entry->wireless_mode; | ||
62 | } else { | ||
63 | return 0; | ||
64 | } | ||
65 | } else { | ||
66 | wireless_mode = rtlmac->mode; | ||
67 | } | ||
68 | |||
69 | if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) || | ||
70 | not_data) { | ||
71 | return 0; | ||
62 | } else { | 72 | } else { |
63 | if (rtlmac->mode == WIRELESS_MODE_B) | 73 | if (rtlhal->current_bandtype == BAND_ON_2_4G) { |
64 | return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]; | 74 | if (wireless_mode == WIRELESS_MODE_B) { |
65 | else | 75 | return B_MODE_MAX_RIX; |
66 | return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]; | 76 | } else if (wireless_mode == WIRELESS_MODE_G) { |
77 | return G_MODE_MAX_RIX; | ||
78 | } else { | ||
79 | if (get_rf_type(rtlphy) != RF_2T2R) | ||
80 | return N_MODE_MCS7_RIX; | ||
81 | else | ||
82 | return N_MODE_MCS15_RIX; | ||
83 | } | ||
84 | } else { | ||
85 | if (wireless_mode == WIRELESS_MODE_A) { | ||
86 | return A_MODE_MAX_RIX; | ||
87 | } else { | ||
88 | if (get_rf_type(rtlphy) != RF_2T2R) | ||
89 | return N_MODE_MCS7_RIX; | ||
90 | else | ||
91 | return N_MODE_MCS15_RIX; | ||
92 | } | ||
93 | } | ||
67 | } | 94 | } |
68 | } | 95 | } |
69 | 96 | ||
70 | static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, | 97 | static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, |
98 | struct ieee80211_sta *sta, | ||
71 | struct ieee80211_tx_rate *rate, | 99 | struct ieee80211_tx_rate *rate, |
72 | struct ieee80211_tx_rate_control *txrc, | 100 | struct ieee80211_tx_rate_control *txrc, |
73 | u8 tries, u8 rix, int rtsctsenable, | 101 | u8 tries, char rix, int rtsctsenable, |
74 | bool not_data) | 102 | bool not_data) |
75 | { | 103 | { |
76 | struct rtl_mac *mac = rtl_mac(rtlpriv); | 104 | struct rtl_mac *mac = rtl_mac(rtlpriv); |
105 | u8 sgi_20 = 0, sgi_40 = 0; | ||
77 | 106 | ||
107 | if (sta) { | ||
108 | sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; | ||
109 | sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; | ||
110 | } | ||
78 | rate->count = tries; | 111 | rate->count = tries; |
79 | rate->idx = (rix > 0x2) ? rix : 0x2; | 112 | rate->idx = rix >= 0x00 ? rix : 0x00; |
80 | 113 | ||
81 | if (!not_data) { | 114 | if (!not_data) { |
82 | if (txrc->short_preamble) | 115 | if (txrc->short_preamble) |
83 | rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; | 116 | rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; |
84 | if (mac->bw_40) | 117 | if (mac->opmode == NL80211_IFTYPE_AP || |
85 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | 118 | mac->opmode == NL80211_IFTYPE_ADHOC) { |
86 | if (mac->sgi_20 || mac->sgi_40) | 119 | if (sta && (sta->ht_cap.cap & |
120 | IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | ||
121 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | ||
122 | } else { | ||
123 | if (mac->bw_40) | ||
124 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | ||
125 | } | ||
126 | if (sgi_20 || sgi_40) | ||
87 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | 127 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; |
88 | if (mac->ht_enable) | 128 | if (sta && sta->ht_cap.ht_supported) |
89 | rate->flags |= IEEE80211_TX_RC_MCS; | 129 | rate->flags |= IEEE80211_TX_RC_MCS; |
90 | } | 130 | } |
91 | } | 131 | } |
@@ -97,39 +137,39 @@ static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta, | |||
97 | struct sk_buff *skb = txrc->skb; | 137 | struct sk_buff *skb = txrc->skb; |
98 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 138 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
99 | struct ieee80211_tx_rate *rates = tx_info->control.rates; | 139 | struct ieee80211_tx_rate *rates = tx_info->control.rates; |
100 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 140 | __le16 fc = rtl_get_fc(skb); |
101 | __le16 fc = hdr->frame_control; | ||
102 | u8 try_per_rate, i, rix; | 141 | u8 try_per_rate, i, rix; |
103 | bool not_data = !ieee80211_is_data(fc); | 142 | bool not_data = !ieee80211_is_data(fc); |
104 | 143 | ||
105 | if (rate_control_send_low(sta, priv_sta, txrc)) | 144 | if (rate_control_send_low(sta, priv_sta, txrc)) |
106 | return; | 145 | return; |
107 | 146 | ||
108 | rix = _rtl_rc_get_highest_rix(rtlpriv, skb, not_data); | 147 | rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data); |
109 | |||
110 | try_per_rate = 1; | 148 | try_per_rate = 1; |
111 | _rtl_rc_rate_set_series(rtlpriv, &rates[0], txrc, | 149 | _rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc, |
112 | try_per_rate, rix, 1, not_data); | 150 | try_per_rate, rix, 1, not_data); |
113 | 151 | ||
114 | if (!not_data) { | 152 | if (!not_data) { |
115 | for (i = 1; i < 4; i++) | 153 | for (i = 1; i < 4; i++) |
116 | _rtl_rc_rate_set_series(rtlpriv, &rates[i], | 154 | _rtl_rc_rate_set_series(rtlpriv, sta, &rates[i], |
117 | txrc, i, (rix - i), 1, | 155 | txrc, i, (rix - i), 1, |
118 | not_data); | 156 | not_data); |
119 | } | 157 | } |
120 | } | 158 | } |
121 | 159 | ||
122 | static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, u16 tid) | 160 | static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, |
161 | struct rtl_sta_info *sta_entry, u16 tid) | ||
123 | { | 162 | { |
124 | struct rtl_mac *mac = rtl_mac(rtlpriv); | 163 | struct rtl_mac *mac = rtl_mac(rtlpriv); |
125 | 164 | ||
126 | if (mac->act_scanning) | 165 | if (mac->act_scanning) |
127 | return false; | 166 | return false; |
128 | 167 | ||
129 | if (mac->cnt_after_linked < 3) | 168 | if (mac->opmode == NL80211_IFTYPE_STATION && |
169 | mac->cnt_after_linked < 3) | ||
130 | return false; | 170 | return false; |
131 | 171 | ||
132 | if (mac->tids[tid].agg.agg_state == RTL_AGG_OFF) | 172 | if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP) |
133 | return true; | 173 | return true; |
134 | 174 | ||
135 | return false; | 175 | return false; |
@@ -143,11 +183,9 @@ static void rtl_tx_status(void *ppriv, | |||
143 | { | 183 | { |
144 | struct rtl_priv *rtlpriv = ppriv; | 184 | struct rtl_priv *rtlpriv = ppriv; |
145 | struct rtl_mac *mac = rtl_mac(rtlpriv); | 185 | struct rtl_mac *mac = rtl_mac(rtlpriv); |
146 | struct ieee80211_hdr *hdr; | 186 | struct ieee80211_hdr *hdr = rtl_get_hdr(skb); |
147 | __le16 fc; | 187 | __le16 fc = rtl_get_fc(skb); |
148 | 188 | struct rtl_sta_info *sta_entry; | |
149 | hdr = (struct ieee80211_hdr *)skb->data; | ||
150 | fc = hdr->frame_control; | ||
151 | 189 | ||
152 | if (!priv_sta || !ieee80211_is_data(fc)) | 190 | if (!priv_sta || !ieee80211_is_data(fc)) |
153 | return; | 191 | return; |
@@ -159,17 +197,21 @@ static void rtl_tx_status(void *ppriv, | |||
159 | || is_broadcast_ether_addr(ieee80211_get_DA(hdr))) | 197 | || is_broadcast_ether_addr(ieee80211_get_DA(hdr))) |
160 | return; | 198 | return; |
161 | 199 | ||
162 | /* Check if aggregation has to be enabled for this tid */ | 200 | if (sta) { |
163 | if (conf_is_ht(&mac->hw->conf) && | 201 | /* Check if aggregation has to be enabled for this tid */ |
164 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | 202 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; |
165 | if (ieee80211_is_data_qos(fc)) { | 203 | if ((sta->ht_cap.ht_supported == true) && |
166 | u8 *qc, tid; | 204 | !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { |
167 | 205 | if (ieee80211_is_data_qos(fc)) { | |
168 | qc = ieee80211_get_qos_ctl(hdr); | 206 | u8 tid = rtl_get_tid(skb); |
169 | tid = qc[0] & 0xf; | 207 | if (_rtl_tx_aggr_check(rtlpriv, sta_entry, |
170 | 208 | tid)) { | |
171 | if (_rtl_tx_aggr_check(rtlpriv, tid)) | 209 | sta_entry->tids[tid].agg.agg_state = |
172 | ieee80211_start_tx_ba_session(sta, tid, 5000); | 210 | RTL_AGG_PROGRESS; |
211 | ieee80211_start_tx_ba_session(sta, | ||
212 | tid, 5000); | ||
213 | } | ||
214 | } | ||
173 | } | 215 | } |
174 | } | 216 | } |
175 | } | 217 | } |
@@ -178,43 +220,6 @@ static void rtl_rate_init(void *ppriv, | |||
178 | struct ieee80211_supported_band *sband, | 220 | struct ieee80211_supported_band *sband, |
179 | struct ieee80211_sta *sta, void *priv_sta) | 221 | struct ieee80211_sta *sta, void *priv_sta) |
180 | { | 222 | { |
181 | struct rtl_priv *rtlpriv = ppriv; | ||
182 | struct rtl_mac *mac = rtl_mac(rtlpriv); | ||
183 | u8 is_ht = conf_is_ht(&mac->hw->conf); | ||
184 | |||
185 | if ((mac->opmode == NL80211_IFTYPE_STATION) || | ||
186 | (mac->opmode == NL80211_IFTYPE_MESH_POINT) || | ||
187 | (mac->opmode == NL80211_IFTYPE_ADHOC)) { | ||
188 | |||
189 | switch (sband->band) { | ||
190 | case IEEE80211_BAND_2GHZ: | ||
191 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
192 | RATR_INX_WIRELESS_G; | ||
193 | if (is_ht) | ||
194 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
195 | RATR_INX_WIRELESS_NGB; | ||
196 | break; | ||
197 | case IEEE80211_BAND_5GHZ: | ||
198 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
199 | RATR_INX_WIRELESS_A; | ||
200 | if (is_ht) | ||
201 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
202 | RATR_INX_WIRELESS_NGB; | ||
203 | break; | ||
204 | default: | ||
205 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
206 | ("Invalid band\n")); | ||
207 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
208 | RATR_INX_WIRELESS_NGB; | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | RT_TRACE(rtlpriv, COMP_RATE, DBG_DMESG, | ||
213 | ("Choosing rate table index: %d\n", | ||
214 | rtlpriv->rate_priv->cur_ratetab_idx)); | ||
215 | |||
216 | } | ||
217 | |||
218 | } | 223 | } |
219 | 224 | ||
220 | static void rtl_rate_update(void *ppriv, | 225 | static void rtl_rate_update(void *ppriv, |
@@ -223,49 +228,6 @@ static void rtl_rate_update(void *ppriv, | |||
223 | u32 changed, | 228 | u32 changed, |
224 | enum nl80211_channel_type oper_chan_type) | 229 | enum nl80211_channel_type oper_chan_type) |
225 | { | 230 | { |
226 | struct rtl_priv *rtlpriv = ppriv; | ||
227 | struct rtl_mac *mac = rtl_mac(rtlpriv); | ||
228 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
229 | bool oper_cw40 = false, oper_sgi40; | ||
230 | bool local_cw40 = mac->bw_40; | ||
231 | bool local_sgi40 = mac->sgi_40; | ||
232 | u8 is_ht = conf_is_ht(&mac->hw->conf); | ||
233 | |||
234 | if (changed & IEEE80211_RC_HT_CHANGED) { | ||
235 | if (mac->opmode != NL80211_IFTYPE_STATION) | ||
236 | return; | ||
237 | |||
238 | if (rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40MINUS || | ||
239 | rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40PLUS) | ||
240 | oper_cw40 = true; | ||
241 | |||
242 | oper_sgi40 = mac->sgi_40; | ||
243 | |||
244 | if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) { | ||
245 | switch (sband->band) { | ||
246 | case IEEE80211_BAND_2GHZ: | ||
247 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
248 | RATR_INX_WIRELESS_G; | ||
249 | if (is_ht) | ||
250 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
251 | RATR_INX_WIRELESS_NGB; | ||
252 | break; | ||
253 | case IEEE80211_BAND_5GHZ: | ||
254 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
255 | RATR_INX_WIRELESS_A; | ||
256 | if (is_ht) | ||
257 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
258 | RATR_INX_WIRELESS_NGB; | ||
259 | break; | ||
260 | default: | ||
261 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
262 | ("Invalid band\n")); | ||
263 | rtlpriv->rate_priv->cur_ratetab_idx = | ||
264 | RATR_INX_WIRELESS_NGB; | ||
265 | break; | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | } | 231 | } |
270 | 232 | ||
271 | static void *rtl_rate_alloc(struct ieee80211_hw *hw, | 233 | static void *rtl_rate_alloc(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h index b4667c035f0b..4afa2c20adcf 100644 --- a/drivers/net/wireless/rtlwifi/rc.h +++ b/drivers/net/wireless/rtlwifi/rc.h | |||
@@ -30,8 +30,15 @@ | |||
30 | #ifndef __RTL_RC_H__ | 30 | #ifndef __RTL_RC_H__ |
31 | #define __RTL_RC_H__ | 31 | #define __RTL_RC_H__ |
32 | 32 | ||
33 | #define B_MODE_MAX_RIX 3 | ||
34 | #define G_MODE_MAX_RIX 11 | ||
35 | #define A_MODE_MAX_RIX 7 | ||
36 | |||
37 | /* in mac80211 mcs0-mcs15 is idx0-idx15*/ | ||
38 | #define N_MODE_MCS7_RIX 7 | ||
39 | #define N_MODE_MCS15_RIX 15 | ||
40 | |||
33 | struct rtl_rate_priv { | 41 | struct rtl_rate_priv { |
34 | u8 cur_ratetab_idx; | ||
35 | u8 ht_cap; | 42 | u8 ht_cap; |
36 | }; | 43 | }; |
37 | 44 | ||
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index d26f957981ad..8f6718f163e5 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c | |||
@@ -66,31 +66,83 @@ static struct country_code_to_enum_rd allCountries[] = { | |||
66 | NL80211_RRF_PASSIVE_SCAN | \ | 66 | NL80211_RRF_PASSIVE_SCAN | \ |
67 | NL80211_RRF_NO_OFDM) | 67 | NL80211_RRF_NO_OFDM) |
68 | 68 | ||
69 | /* 5G chan 36 - chan 64*/ | ||
70 | #define RTL819x_5GHZ_5150_5350 \ | ||
71 | REG_RULE(5150-10, 5350+10, 40, 0, 30, \ | ||
72 | NL80211_RRF_PASSIVE_SCAN | \ | ||
73 | NL80211_RRF_NO_IBSS) | ||
74 | |||
75 | /* 5G chan 100 - chan 165*/ | ||
76 | #define RTL819x_5GHZ_5470_5850 \ | ||
77 | REG_RULE(5470-10, 5850+10, 40, 0, 30, \ | ||
78 | NL80211_RRF_PASSIVE_SCAN | \ | ||
79 | NL80211_RRF_NO_IBSS) | ||
80 | |||
81 | /* 5G chan 149 - chan 165*/ | ||
82 | #define RTL819x_5GHZ_5725_5850 \ | ||
83 | REG_RULE(5725-10, 5850+10, 40, 0, 30, \ | ||
84 | NL80211_RRF_PASSIVE_SCAN | \ | ||
85 | NL80211_RRF_NO_IBSS) | ||
86 | |||
87 | #define RTL819x_5GHZ_ALL \ | ||
88 | (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) | ||
89 | |||
69 | static const struct ieee80211_regdomain rtl_regdom_11 = { | 90 | static const struct ieee80211_regdomain rtl_regdom_11 = { |
70 | .n_reg_rules = 1, | 91 | .n_reg_rules = 1, |
71 | .alpha2 = "99", | 92 | .alpha2 = "99", |
72 | .reg_rules = { | 93 | .reg_rules = { |
73 | RTL819x_2GHZ_CH01_11, | 94 | RTL819x_2GHZ_CH01_11, |
74 | } | 95 | } |
96 | }; | ||
97 | |||
98 | static const struct ieee80211_regdomain rtl_regdom_12_13 = { | ||
99 | .n_reg_rules = 2, | ||
100 | .alpha2 = "99", | ||
101 | .reg_rules = { | ||
102 | RTL819x_2GHZ_CH01_11, | ||
103 | RTL819x_2GHZ_CH12_13, | ||
104 | } | ||
75 | }; | 105 | }; |
76 | 106 | ||
77 | static const struct ieee80211_regdomain rtl_regdom_global = { | 107 | static const struct ieee80211_regdomain rtl_regdom_no_midband = { |
78 | .n_reg_rules = 3, | 108 | .n_reg_rules = 3, |
79 | .alpha2 = "99", | 109 | .alpha2 = "99", |
80 | .reg_rules = { | 110 | .reg_rules = { |
81 | RTL819x_2GHZ_CH01_11, | 111 | RTL819x_2GHZ_CH01_11, |
82 | RTL819x_2GHZ_CH12_13, | 112 | RTL819x_5GHZ_5150_5350, |
83 | RTL819x_2GHZ_CH14, | 113 | RTL819x_5GHZ_5725_5850, |
84 | } | 114 | } |
85 | }; | 115 | }; |
86 | 116 | ||
87 | static const struct ieee80211_regdomain rtl_regdom_world = { | 117 | static const struct ieee80211_regdomain rtl_regdom_60_64 = { |
88 | .n_reg_rules = 2, | 118 | .n_reg_rules = 3, |
89 | .alpha2 = "99", | 119 | .alpha2 = "99", |
90 | .reg_rules = { | 120 | .reg_rules = { |
91 | RTL819x_2GHZ_CH01_11, | 121 | RTL819x_2GHZ_CH01_11, |
92 | RTL819x_2GHZ_CH12_13, | 122 | RTL819x_2GHZ_CH12_13, |
93 | } | 123 | RTL819x_5GHZ_5725_5850, |
124 | } | ||
125 | }; | ||
126 | |||
127 | static const struct ieee80211_regdomain rtl_regdom_14_60_64 = { | ||
128 | .n_reg_rules = 4, | ||
129 | .alpha2 = "99", | ||
130 | .reg_rules = { | ||
131 | RTL819x_2GHZ_CH01_11, | ||
132 | RTL819x_2GHZ_CH12_13, | ||
133 | RTL819x_2GHZ_CH14, | ||
134 | RTL819x_5GHZ_5725_5850, | ||
135 | } | ||
136 | }; | ||
137 | |||
138 | static const struct ieee80211_regdomain rtl_regdom_14 = { | ||
139 | .n_reg_rules = 3, | ||
140 | .alpha2 = "99", | ||
141 | .reg_rules = { | ||
142 | RTL819x_2GHZ_CH01_11, | ||
143 | RTL819x_2GHZ_CH12_13, | ||
144 | RTL819x_2GHZ_CH14, | ||
145 | } | ||
94 | }; | 146 | }; |
95 | 147 | ||
96 | static bool _rtl_is_radar_freq(u16 center_freq) | 148 | static bool _rtl_is_radar_freq(u16 center_freq) |
@@ -162,6 +214,8 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, | |||
162 | u32 bandwidth = 0; | 214 | u32 bandwidth = 0; |
163 | int r; | 215 | int r; |
164 | 216 | ||
217 | if (!wiphy->bands[IEEE80211_BAND_2GHZ]) | ||
218 | return; | ||
165 | sband = wiphy->bands[IEEE80211_BAND_2GHZ]; | 219 | sband = wiphy->bands[IEEE80211_BAND_2GHZ]; |
166 | 220 | ||
167 | /* | 221 | /* |
@@ -292,25 +346,26 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select( | |||
292 | { | 346 | { |
293 | switch (reg->country_code) { | 347 | switch (reg->country_code) { |
294 | case COUNTRY_CODE_FCC: | 348 | case COUNTRY_CODE_FCC: |
349 | return &rtl_regdom_no_midband; | ||
295 | case COUNTRY_CODE_IC: | 350 | case COUNTRY_CODE_IC: |
296 | return &rtl_regdom_11; | 351 | return &rtl_regdom_11; |
297 | case COUNTRY_CODE_ETSI: | 352 | case COUNTRY_CODE_ETSI: |
353 | case COUNTRY_CODE_TELEC_NETGEAR: | ||
354 | return &rtl_regdom_60_64; | ||
298 | case COUNTRY_CODE_SPAIN: | 355 | case COUNTRY_CODE_SPAIN: |
299 | case COUNTRY_CODE_FRANCE: | 356 | case COUNTRY_CODE_FRANCE: |
300 | case COUNTRY_CODE_ISRAEL: | 357 | case COUNTRY_CODE_ISRAEL: |
301 | case COUNTRY_CODE_TELEC_NETGEAR: | 358 | case COUNTRY_CODE_WORLD_WIDE_13: |
302 | return &rtl_regdom_world; | 359 | return &rtl_regdom_12_13; |
303 | case COUNTRY_CODE_MKK: | 360 | case COUNTRY_CODE_MKK: |
304 | case COUNTRY_CODE_MKK1: | 361 | case COUNTRY_CODE_MKK1: |
305 | case COUNTRY_CODE_TELEC: | 362 | case COUNTRY_CODE_TELEC: |
306 | case COUNTRY_CODE_MIC: | 363 | case COUNTRY_CODE_MIC: |
307 | return &rtl_regdom_global; | 364 | return &rtl_regdom_14_60_64; |
308 | case COUNTRY_CODE_GLOBAL_DOMAIN: | 365 | case COUNTRY_CODE_GLOBAL_DOMAIN: |
309 | return &rtl_regdom_global; | 366 | return &rtl_regdom_14; |
310 | case COUNTRY_CODE_WORLD_WIDE_13: | ||
311 | return &rtl_regdom_world; | ||
312 | default: | 367 | default: |
313 | return &rtl_regdom_world; | 368 | return &rtl_regdom_no_midband; |
314 | } | 369 | } |
315 | } | 370 | } |
316 | 371 | ||
@@ -323,9 +378,11 @@ static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, | |||
323 | const struct ieee80211_regdomain *regd; | 378 | const struct ieee80211_regdomain *regd; |
324 | 379 | ||
325 | wiphy->reg_notifier = reg_notifier; | 380 | wiphy->reg_notifier = reg_notifier; |
381 | |||
326 | wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; | 382 | wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; |
327 | wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; | 383 | wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; |
328 | wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; | 384 | wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; |
385 | |||
329 | regd = _rtl_regdomain_select(reg); | 386 | regd = _rtl_regdomain_select(reg); |
330 | wiphy_apply_custom_regulatory(wiphy, regd); | 387 | wiphy_apply_custom_regulatory(wiphy, regd); |
331 | _rtl_reg_apply_radar_flags(wiphy); | 388 | _rtl_reg_apply_radar_flags(wiphy); |
@@ -355,8 +412,8 @@ int rtl_regd_init(struct ieee80211_hw *hw, | |||
355 | if (wiphy == NULL || &rtlpriv->regd == NULL) | 412 | if (wiphy == NULL || &rtlpriv->regd == NULL) |
356 | return -EINVAL; | 413 | return -EINVAL; |
357 | 414 | ||
358 | /* force the channel plan to world wide 13 */ | 415 | /* init country_code from efuse channel plan */ |
359 | rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; | 416 | rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan; |
360 | 417 | ||
361 | RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, | 418 | RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, |
362 | (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n", | 419 | (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n", |
@@ -373,8 +430,8 @@ int rtl_regd_init(struct ieee80211_hw *hw, | |||
373 | country = _rtl_regd_find_country(rtlpriv->regd.country_code); | 430 | country = _rtl_regd_find_country(rtlpriv->regd.country_code); |
374 | 431 | ||
375 | if (country) { | 432 | if (country) { |
376 | rtlpriv->regd.alpha2[0] = country->isoName[0]; | 433 | rtlpriv->regd.alpha2[0] = country->iso_name[0]; |
377 | rtlpriv->regd.alpha2[1] = country->isoName[1]; | 434 | rtlpriv->regd.alpha2[1] = country->iso_name[1]; |
378 | } else { | 435 | } else { |
379 | rtlpriv->regd.alpha2[0] = '0'; | 436 | rtlpriv->regd.alpha2[0] = '0'; |
380 | rtlpriv->regd.alpha2[1] = '0'; | 437 | rtlpriv->regd.alpha2[1] = '0'; |
diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h index 4cdbc4ae76d4..d23118938fac 100644 --- a/drivers/net/wireless/rtlwifi/regd.h +++ b/drivers/net/wireless/rtlwifi/regd.h | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | struct country_code_to_enum_rd { | 33 | struct country_code_to_enum_rd { |
34 | u16 countrycode; | 34 | u16 countrycode; |
35 | const char *isoName; | 35 | const char *iso_name; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | enum country_code_type_t { | 38 | enum country_code_type_t { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index c228b9ee3711..97183829b9be 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
@@ -28,10 +28,26 @@ | |||
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #include "dm_common.h" | 30 | #include "dm_common.h" |
31 | #include "phy_common.h" | ||
32 | #include "../pci.h" | ||
33 | #include "../base.h" | ||
31 | 34 | ||
32 | struct dig_t dm_digtable; | 35 | struct dig_t dm_digtable; |
33 | static struct ps_t dm_pstable; | 36 | static struct ps_t dm_pstable; |
34 | 37 | ||
38 | #define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1) | ||
39 | #define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1) | ||
40 | #define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1) | ||
41 | #define BT_RSSI_STATE_BG_EDCA_LOW BIT_OFFSET_LEN_MASK_32(3, 1) | ||
42 | #define BT_RSSI_STATE_TXPOWER_LOW BIT_OFFSET_LEN_MASK_32(4, 1) | ||
43 | |||
44 | #define RTLPRIV (struct rtl_priv *) | ||
45 | #define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ | ||
46 | ((RTLPRIV(_priv))->mac80211.opmode == \ | ||
47 | NL80211_IFTYPE_ADHOC) ? \ | ||
48 | ((RTLPRIV(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) : \ | ||
49 | ((RTLPRIV(_priv))->dm.undecorated_smoothed_pwdb) | ||
50 | |||
35 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { | 51 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { |
36 | 0x7f8001fe, | 52 | 0x7f8001fe, |
37 | 0x788001e2, | 53 | 0x788001e2, |
@@ -304,7 +320,7 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) | |||
304 | 320 | ||
305 | static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) | 321 | static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) |
306 | { | 322 | { |
307 | static u8 binitialized; /* initialized to false */ | 323 | static u8 initialized; /* initialized to false */ |
308 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 324 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
309 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 325 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
310 | long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | 326 | long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; |
@@ -315,11 +331,11 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) | |||
315 | 331 | ||
316 | if ((multi_sta == false) || (dm_digtable.cursta_connectctate != | 332 | if ((multi_sta == false) || (dm_digtable.cursta_connectctate != |
317 | DIG_STA_DISCONNECT)) { | 333 | DIG_STA_DISCONNECT)) { |
318 | binitialized = false; | 334 | initialized = false; |
319 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | 335 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; |
320 | return; | 336 | return; |
321 | } else if (binitialized == false) { | 337 | } else if (initialized == false) { |
322 | binitialized = true; | 338 | initialized = true; |
323 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; | 339 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; |
324 | dm_digtable.cur_igvalue = 0x20; | 340 | dm_digtable.cur_igvalue = 0x20; |
325 | rtl92c_dm_write_dig(hw); | 341 | rtl92c_dm_write_dig(hw); |
@@ -461,10 +477,7 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) | |||
461 | if (mac->act_scanning == true) | 477 | if (mac->act_scanning == true) |
462 | return; | 478 | return; |
463 | 479 | ||
464 | if ((mac->link_state > MAC80211_NOLINK) && | 480 | if (mac->link_state >= MAC80211_LINKED) |
465 | (mac->link_state < MAC80211_LINKED)) | ||
466 | dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; | ||
467 | else if (mac->link_state >= MAC80211_LINKED) | ||
468 | dm_digtable.cursta_connectctate = DIG_STA_CONNECT; | 481 | dm_digtable.cursta_connectctate = DIG_STA_CONNECT; |
469 | else | 482 | else |
470 | dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; | 483 | dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; |
@@ -562,23 +575,42 @@ EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo); | |||
562 | static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) | 575 | static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) |
563 | { | 576 | { |
564 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 577 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
578 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
565 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 579 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
580 | |||
566 | static u64 last_txok_cnt; | 581 | static u64 last_txok_cnt; |
567 | static u64 last_rxok_cnt; | 582 | static u64 last_rxok_cnt; |
568 | u64 cur_txok_cnt; | 583 | static u32 last_bt_edca_ul; |
569 | u64 cur_rxok_cnt; | 584 | static u32 last_bt_edca_dl; |
585 | u64 cur_txok_cnt = 0; | ||
586 | u64 cur_rxok_cnt = 0; | ||
570 | u32 edca_be_ul = 0x5ea42b; | 587 | u32 edca_be_ul = 0x5ea42b; |
571 | u32 edca_be_dl = 0x5ea42b; | 588 | u32 edca_be_dl = 0x5ea42b; |
589 | bool bt_change_edca = false; | ||
572 | 590 | ||
573 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | 591 | if ((last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) || |
574 | goto dm_checkedcaturbo_exit; | 592 | (last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) { |
593 | rtlpriv->dm.current_turbo_edca = false; | ||
594 | last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul; | ||
595 | last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl; | ||
596 | } | ||
597 | |||
598 | if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) { | ||
599 | edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul; | ||
600 | bt_change_edca = true; | ||
601 | } | ||
602 | |||
603 | if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) { | ||
604 | edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl; | ||
605 | bt_change_edca = true; | ||
606 | } | ||
575 | 607 | ||
576 | if (mac->link_state != MAC80211_LINKED) { | 608 | if (mac->link_state != MAC80211_LINKED) { |
577 | rtlpriv->dm.current_turbo_edca = false; | 609 | rtlpriv->dm.current_turbo_edca = false; |
578 | return; | 610 | return; |
579 | } | 611 | } |
580 | 612 | ||
581 | if (!mac->ht_enable) { /*FIX MERGE */ | 613 | if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) { |
582 | if (!(edca_be_ul & 0xffff0000)) | 614 | if (!(edca_be_ul & 0xffff0000)) |
583 | edca_be_ul |= 0x005e0000; | 615 | edca_be_ul |= 0x005e0000; |
584 | 616 | ||
@@ -586,10 +618,12 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
586 | edca_be_dl |= 0x005e0000; | 618 | edca_be_dl |= 0x005e0000; |
587 | } | 619 | } |
588 | 620 | ||
589 | if ((!rtlpriv->dm.is_any_nonbepkts) && | 621 | if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && |
590 | (!rtlpriv->dm.disable_framebursting)) { | 622 | (!rtlpriv->dm.disable_framebursting))) { |
623 | |||
591 | cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; | 624 | cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; |
592 | cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; | 625 | cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; |
626 | |||
593 | if (cur_rxok_cnt > 4 * cur_txok_cnt) { | 627 | if (cur_rxok_cnt > 4 * cur_txok_cnt) { |
594 | if (!rtlpriv->dm.is_cur_rdlstate || | 628 | if (!rtlpriv->dm.is_cur_rdlstate || |
595 | !rtlpriv->dm.current_turbo_edca) { | 629 | !rtlpriv->dm.current_turbo_edca) { |
@@ -618,7 +652,6 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
618 | } | 652 | } |
619 | } | 653 | } |
620 | 654 | ||
621 | dm_checkedcaturbo_exit: | ||
622 | rtlpriv->dm.is_any_nonbepkts = false; | 655 | rtlpriv->dm.is_any_nonbepkts = false; |
623 | last_txok_cnt = rtlpriv->stats.txbytesunicast; | 656 | last_txok_cnt = rtlpriv->stats.txbytesunicast; |
624 | last_rxok_cnt = rtlpriv->stats.rxbytesunicast; | 657 | last_rxok_cnt = rtlpriv->stats.rxbytesunicast; |
@@ -633,14 +666,14 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | |||
633 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 666 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
634 | u8 thermalvalue, delta, delta_lck, delta_iqk; | 667 | u8 thermalvalue, delta, delta_lck, delta_iqk; |
635 | long ele_a, ele_d, temp_cck, val_x, value32; | 668 | long ele_a, ele_d, temp_cck, val_x, value32; |
636 | long val_y, ele_c; | 669 | long val_y, ele_c = 0; |
637 | u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; | 670 | u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; |
638 | int i; | 671 | int i; |
639 | bool is2t = IS_92C_SERIAL(rtlhal->version); | 672 | bool is2t = IS_92C_SERIAL(rtlhal->version); |
640 | u8 txpwr_level[2] = {0, 0}; | 673 | u8 txpwr_level[2] = {0, 0}; |
641 | u8 ofdm_min_index = 6, rf; | 674 | u8 ofdm_min_index = 6, rf; |
642 | 675 | ||
643 | rtlpriv->dm.txpower_trackingInit = true; | 676 | rtlpriv->dm.txpower_trackinginit = true; |
644 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 677 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
645 | ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); | 678 | ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); |
646 | 679 | ||
@@ -683,7 +716,6 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | |||
683 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { | 716 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { |
684 | if (ele_d == (ofdmswing_table[i] & | 717 | if (ele_d == (ofdmswing_table[i] & |
685 | MASKOFDM_D)) { | 718 | MASKOFDM_D)) { |
686 | ofdm_index_old[1] = (u8) i; | ||
687 | 719 | ||
688 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, | 720 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, |
689 | DBG_LOUD, | 721 | DBG_LOUD, |
@@ -1062,7 +1094,7 @@ static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( | |||
1062 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1094 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1063 | 1095 | ||
1064 | rtlpriv->dm.txpower_tracking = true; | 1096 | rtlpriv->dm.txpower_tracking = true; |
1065 | rtlpriv->dm.txpower_trackingInit = false; | 1097 | rtlpriv->dm.txpower_trackinginit = false; |
1066 | 1098 | ||
1067 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | 1099 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, |
1068 | ("pMgntInfo->txpower_tracking = %d\n", | 1100 | ("pMgntInfo->txpower_tracking = %d\n", |
@@ -1132,6 +1164,7 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | |||
1132 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1164 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
1133 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | 1165 | struct rate_adaptive *p_ra = &(rtlpriv->ra); |
1134 | u32 low_rssithresh_for_ra, high_rssithresh_for_ra; | 1166 | u32 low_rssithresh_for_ra, high_rssithresh_for_ra; |
1167 | struct ieee80211_sta *sta = NULL; | ||
1135 | 1168 | ||
1136 | if (is_hal_stop(rtlhal)) { | 1169 | if (is_hal_stop(rtlhal)) { |
1137 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | 1170 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, |
@@ -1145,8 +1178,8 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | |||
1145 | return; | 1178 | return; |
1146 | } | 1179 | } |
1147 | 1180 | ||
1148 | if (mac->link_state == MAC80211_LINKED) { | 1181 | if (mac->link_state == MAC80211_LINKED && |
1149 | 1182 | mac->opmode == NL80211_IFTYPE_STATION) { | |
1150 | switch (p_ra->pre_ratr_state) { | 1183 | switch (p_ra->pre_ratr_state) { |
1151 | case DM_RATR_STA_HIGH: | 1184 | case DM_RATR_STA_HIGH: |
1152 | high_rssithresh_for_ra = 50; | 1185 | high_rssithresh_for_ra = 50; |
@@ -1185,10 +1218,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | |||
1185 | ("PreState = %d, CurState = %d\n", | 1218 | ("PreState = %d, CurState = %d\n", |
1186 | p_ra->pre_ratr_state, p_ra->ratr_state)); | 1219 | p_ra->pre_ratr_state, p_ra->ratr_state)); |
1187 | 1220 | ||
1188 | rtlpriv->cfg->ops->update_rate_mask(hw, | 1221 | rcu_read_lock(); |
1222 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | ||
1223 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, | ||
1189 | p_ra->ratr_state); | 1224 | p_ra->ratr_state); |
1190 | 1225 | ||
1191 | p_ra->pre_ratr_state = p_ra->ratr_state; | 1226 | p_ra->pre_ratr_state = p_ra->ratr_state; |
1227 | rcu_read_unlock(); | ||
1192 | } | 1228 | } |
1193 | } | 1229 | } |
1194 | } | 1230 | } |
@@ -1202,51 +1238,6 @@ static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) | |||
1202 | dm_pstable.rssi_val_min = 0; | 1238 | dm_pstable.rssi_val_min = 0; |
1203 | } | 1239 | } |
1204 | 1240 | ||
1205 | static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) | ||
1206 | { | ||
1207 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1208 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1209 | |||
1210 | if (dm_pstable.rssi_val_min != 0) { | ||
1211 | if (dm_pstable.pre_ccastate == CCA_2R) { | ||
1212 | if (dm_pstable.rssi_val_min >= 35) | ||
1213 | dm_pstable.cur_ccasate = CCA_1R; | ||
1214 | else | ||
1215 | dm_pstable.cur_ccasate = CCA_2R; | ||
1216 | } else { | ||
1217 | if (dm_pstable.rssi_val_min <= 30) | ||
1218 | dm_pstable.cur_ccasate = CCA_2R; | ||
1219 | else | ||
1220 | dm_pstable.cur_ccasate = CCA_1R; | ||
1221 | } | ||
1222 | } else { | ||
1223 | dm_pstable.cur_ccasate = CCA_MAX; | ||
1224 | } | ||
1225 | |||
1226 | if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { | ||
1227 | if (dm_pstable.cur_ccasate == CCA_1R) { | ||
1228 | if (get_rf_type(rtlphy) == RF_2T2R) { | ||
1229 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
1230 | MASKBYTE0, 0x13); | ||
1231 | rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); | ||
1232 | } else { | ||
1233 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
1234 | MASKBYTE0, 0x23); | ||
1235 | rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); | ||
1236 | } | ||
1237 | } else { | ||
1238 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, | ||
1239 | 0x33); | ||
1240 | rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); | ||
1241 | } | ||
1242 | dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; | ||
1243 | } | ||
1244 | |||
1245 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", | ||
1246 | (dm_pstable.cur_ccasate == | ||
1247 | 0) ? "1RCCA" : "2RCCA")); | ||
1248 | } | ||
1249 | |||
1250 | void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) | 1241 | void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) |
1251 | { | 1242 | { |
1252 | static u8 initialize; | 1243 | static u8 initialize; |
@@ -1352,7 +1343,9 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) | |||
1352 | } | 1343 | } |
1353 | 1344 | ||
1354 | if (IS_92C_SERIAL(rtlhal->version)) | 1345 | if (IS_92C_SERIAL(rtlhal->version)) |
1355 | rtl92c_dm_1r_cca(hw); | 1346 | ;/* rtl92c_dm_1r_cca(hw); */ |
1347 | else | ||
1348 | rtl92c_dm_rf_saving(hw, false); | ||
1356 | } | 1349 | } |
1357 | 1350 | ||
1358 | void rtl92c_dm_init(struct ieee80211_hw *hw) | 1351 | void rtl92c_dm_init(struct ieee80211_hw *hw) |
@@ -1369,6 +1362,84 @@ void rtl92c_dm_init(struct ieee80211_hw *hw) | |||
1369 | } | 1362 | } |
1370 | EXPORT_SYMBOL(rtl92c_dm_init); | 1363 | EXPORT_SYMBOL(rtl92c_dm_init); |
1371 | 1364 | ||
1365 | void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) | ||
1366 | { | ||
1367 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1368 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1369 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1370 | long undecorated_smoothed_pwdb; | ||
1371 | |||
1372 | if (!rtlpriv->dm.dynamic_txpower_enable) | ||
1373 | return; | ||
1374 | |||
1375 | if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { | ||
1376 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
1377 | return; | ||
1378 | } | ||
1379 | |||
1380 | if ((mac->link_state < MAC80211_LINKED) && | ||
1381 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | ||
1382 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
1383 | ("Not connected to any\n")); | ||
1384 | |||
1385 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
1386 | |||
1387 | rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
1388 | return; | ||
1389 | } | ||
1390 | |||
1391 | if (mac->link_state >= MAC80211_LINKED) { | ||
1392 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
1393 | undecorated_smoothed_pwdb = | ||
1394 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1395 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1396 | ("AP Client PWDB = 0x%lx\n", | ||
1397 | undecorated_smoothed_pwdb)); | ||
1398 | } else { | ||
1399 | undecorated_smoothed_pwdb = | ||
1400 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
1401 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1402 | ("STA Default Port PWDB = 0x%lx\n", | ||
1403 | undecorated_smoothed_pwdb)); | ||
1404 | } | ||
1405 | } else { | ||
1406 | undecorated_smoothed_pwdb = | ||
1407 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1408 | |||
1409 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1410 | ("AP Ext Port PWDB = 0x%lx\n", | ||
1411 | undecorated_smoothed_pwdb)); | ||
1412 | } | ||
1413 | |||
1414 | if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { | ||
1415 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
1416 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1417 | ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); | ||
1418 | } else if ((undecorated_smoothed_pwdb < | ||
1419 | (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && | ||
1420 | (undecorated_smoothed_pwdb >= | ||
1421 | TX_POWER_NEAR_FIELD_THRESH_LVL1)) { | ||
1422 | |||
1423 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
1424 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1425 | ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); | ||
1426 | } else if (undecorated_smoothed_pwdb < | ||
1427 | (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { | ||
1428 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
1429 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1430 | ("TXHIGHPWRLEVEL_NORMAL\n")); | ||
1431 | } | ||
1432 | |||
1433 | if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { | ||
1434 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1435 | ("PHY_SetTxPowerLevel8192S() Channel = %d\n", | ||
1436 | rtlphy->current_channel)); | ||
1437 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
1438 | } | ||
1439 | |||
1440 | rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; | ||
1441 | } | ||
1442 | |||
1372 | void rtl92c_dm_watchdog(struct ieee80211_hw *hw) | 1443 | void rtl92c_dm_watchdog(struct ieee80211_hw *hw) |
1373 | { | 1444 | { |
1374 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1445 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -1388,11 +1459,321 @@ void rtl92c_dm_watchdog(struct ieee80211_hw *hw) | |||
1388 | rtl92c_dm_dig(hw); | 1459 | rtl92c_dm_dig(hw); |
1389 | rtl92c_dm_false_alarm_counter_statistics(hw); | 1460 | rtl92c_dm_false_alarm_counter_statistics(hw); |
1390 | rtl92c_dm_dynamic_bb_powersaving(hw); | 1461 | rtl92c_dm_dynamic_bb_powersaving(hw); |
1391 | rtlpriv->cfg->ops->dm_dynamic_txpower(hw); | 1462 | rtl92c_dm_dynamic_txpower(hw); |
1392 | rtl92c_dm_check_txpower_tracking(hw); | 1463 | rtl92c_dm_check_txpower_tracking(hw); |
1393 | rtl92c_dm_refresh_rate_adaptive_mask(hw); | 1464 | rtl92c_dm_refresh_rate_adaptive_mask(hw); |
1465 | rtl92c_dm_bt_coexist(hw); | ||
1394 | rtl92c_dm_check_edca_turbo(hw); | 1466 | rtl92c_dm_check_edca_turbo(hw); |
1395 | |||
1396 | } | 1467 | } |
1397 | } | 1468 | } |
1398 | EXPORT_SYMBOL(rtl92c_dm_watchdog); | 1469 | EXPORT_SYMBOL(rtl92c_dm_watchdog); |
1470 | |||
1471 | u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw) | ||
1472 | { | ||
1473 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1474 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1475 | long undecorated_smoothed_pwdb; | ||
1476 | u8 curr_bt_rssi_state = 0x00; | ||
1477 | |||
1478 | if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { | ||
1479 | undecorated_smoothed_pwdb = | ||
1480 | GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); | ||
1481 | } else { | ||
1482 | if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0) | ||
1483 | undecorated_smoothed_pwdb = 100; | ||
1484 | else | ||
1485 | undecorated_smoothed_pwdb = | ||
1486 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1487 | } | ||
1488 | |||
1489 | /* Check RSSI to determine HighPower/NormalPower state for | ||
1490 | * BT coexistence. */ | ||
1491 | if (undecorated_smoothed_pwdb >= 67) | ||
1492 | curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER); | ||
1493 | else if (undecorated_smoothed_pwdb < 62) | ||
1494 | curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER; | ||
1495 | |||
1496 | /* Check RSSI to determine AMPDU setting for BT coexistence. */ | ||
1497 | if (undecorated_smoothed_pwdb >= 40) | ||
1498 | curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF); | ||
1499 | else if (undecorated_smoothed_pwdb <= 32) | ||
1500 | curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF; | ||
1501 | |||
1502 | /* Marked RSSI state. It will be used to determine BT coexistence | ||
1503 | * setting later. */ | ||
1504 | if (undecorated_smoothed_pwdb < 35) | ||
1505 | curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW; | ||
1506 | else | ||
1507 | curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); | ||
1508 | |||
1509 | /* Set Tx Power according to BT status. */ | ||
1510 | if (undecorated_smoothed_pwdb >= 30) | ||
1511 | curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW; | ||
1512 | else if (undecorated_smoothed_pwdb < 25) | ||
1513 | curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW); | ||
1514 | |||
1515 | /* Check BT state related to BT_Idle in B/G mode. */ | ||
1516 | if (undecorated_smoothed_pwdb < 15) | ||
1517 | curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW; | ||
1518 | else | ||
1519 | curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW); | ||
1520 | |||
1521 | if (curr_bt_rssi_state != rtlpcipriv->bt_coexist.bt_rssi_state) { | ||
1522 | rtlpcipriv->bt_coexist.bt_rssi_state = curr_bt_rssi_state; | ||
1523 | return true; | ||
1524 | } else { | ||
1525 | return false; | ||
1526 | } | ||
1527 | } | ||
1528 | EXPORT_SYMBOL(rtl92c_bt_rssi_state_change); | ||
1529 | |||
1530 | static bool rtl92c_bt_state_change(struct ieee80211_hw *hw) | ||
1531 | { | ||
1532 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1533 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1534 | |||
1535 | u32 polling, ratio_tx, ratio_pri; | ||
1536 | u32 bt_tx, bt_pri; | ||
1537 | u8 bt_state; | ||
1538 | u8 cur_service_type; | ||
1539 | |||
1540 | if (rtlpriv->mac80211.link_state < MAC80211_LINKED) | ||
1541 | return false; | ||
1542 | |||
1543 | bt_state = rtl_read_byte(rtlpriv, 0x4fd); | ||
1544 | bt_tx = rtl_read_dword(rtlpriv, 0x488); | ||
1545 | bt_tx = bt_tx & 0x00ffffff; | ||
1546 | bt_pri = rtl_read_dword(rtlpriv, 0x48c); | ||
1547 | bt_pri = bt_pri & 0x00ffffff; | ||
1548 | polling = rtl_read_dword(rtlpriv, 0x490); | ||
1549 | |||
1550 | if (bt_tx == 0xffffffff && bt_pri == 0xffffffff && | ||
1551 | polling == 0xffffffff && bt_state == 0xff) | ||
1552 | return false; | ||
1553 | |||
1554 | bt_state &= BIT_OFFSET_LEN_MASK_32(0, 1); | ||
1555 | if (bt_state != rtlpcipriv->bt_coexist.bt_cur_state) { | ||
1556 | rtlpcipriv->bt_coexist.bt_cur_state = bt_state; | ||
1557 | |||
1558 | if (rtlpcipriv->bt_coexist.reg_bt_sco == 3) { | ||
1559 | rtlpcipriv->bt_coexist.bt_service = BT_IDLE; | ||
1560 | |||
1561 | bt_state = bt_state | | ||
1562 | ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ? | ||
1563 | 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) | | ||
1564 | BIT_OFFSET_LEN_MASK_32(2, 1); | ||
1565 | rtl_write_byte(rtlpriv, 0x4fd, bt_state); | ||
1566 | } | ||
1567 | return true; | ||
1568 | } | ||
1569 | |||
1570 | ratio_tx = bt_tx * 1000 / polling; | ||
1571 | ratio_pri = bt_pri * 1000 / polling; | ||
1572 | rtlpcipriv->bt_coexist.ratio_tx = ratio_tx; | ||
1573 | rtlpcipriv->bt_coexist.ratio_pri = ratio_pri; | ||
1574 | |||
1575 | if (bt_state && rtlpcipriv->bt_coexist.reg_bt_sco == 3) { | ||
1576 | |||
1577 | if ((ratio_tx < 30) && (ratio_pri < 30)) | ||
1578 | cur_service_type = BT_IDLE; | ||
1579 | else if ((ratio_pri > 110) && (ratio_pri < 250)) | ||
1580 | cur_service_type = BT_SCO; | ||
1581 | else if ((ratio_tx >= 200) && (ratio_pri >= 200)) | ||
1582 | cur_service_type = BT_BUSY; | ||
1583 | else if ((ratio_tx >= 350) && (ratio_tx < 500)) | ||
1584 | cur_service_type = BT_OTHERBUSY; | ||
1585 | else if (ratio_tx >= 500) | ||
1586 | cur_service_type = BT_PAN; | ||
1587 | else | ||
1588 | cur_service_type = BT_OTHER_ACTION; | ||
1589 | |||
1590 | if (cur_service_type != rtlpcipriv->bt_coexist.bt_service) { | ||
1591 | rtlpcipriv->bt_coexist.bt_service = cur_service_type; | ||
1592 | bt_state = bt_state | | ||
1593 | ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ? | ||
1594 | 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) | | ||
1595 | ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) ? | ||
1596 | 0 : BIT_OFFSET_LEN_MASK_32(2, 1)); | ||
1597 | |||
1598 | /* Add interrupt migration when bt is not ini | ||
1599 | * idle state (no traffic). */ | ||
1600 | if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) { | ||
1601 | rtl_write_word(rtlpriv, 0x504, 0x0ccc); | ||
1602 | rtl_write_byte(rtlpriv, 0x506, 0x54); | ||
1603 | rtl_write_byte(rtlpriv, 0x507, 0x54); | ||
1604 | } else { | ||
1605 | rtl_write_byte(rtlpriv, 0x506, 0x00); | ||
1606 | rtl_write_byte(rtlpriv, 0x507, 0x00); | ||
1607 | } | ||
1608 | |||
1609 | rtl_write_byte(rtlpriv, 0x4fd, bt_state); | ||
1610 | return true; | ||
1611 | } | ||
1612 | } | ||
1613 | |||
1614 | return false; | ||
1615 | |||
1616 | } | ||
1617 | |||
1618 | static bool rtl92c_bt_wifi_connect_change(struct ieee80211_hw *hw) | ||
1619 | { | ||
1620 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1621 | static bool media_connect; | ||
1622 | |||
1623 | if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { | ||
1624 | media_connect = false; | ||
1625 | } else { | ||
1626 | if (!media_connect) { | ||
1627 | media_connect = true; | ||
1628 | return true; | ||
1629 | } | ||
1630 | media_connect = true; | ||
1631 | } | ||
1632 | |||
1633 | return false; | ||
1634 | } | ||
1635 | |||
1636 | static void rtl92c_bt_set_normal(struct ieee80211_hw *hw) | ||
1637 | { | ||
1638 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1639 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1640 | |||
1641 | |||
1642 | if (rtlpcipriv->bt_coexist.bt_service == BT_OTHERBUSY) { | ||
1643 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72b; | ||
1644 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72b; | ||
1645 | } else if (rtlpcipriv->bt_coexist.bt_service == BT_BUSY) { | ||
1646 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82f; | ||
1647 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82f; | ||
1648 | } else if (rtlpcipriv->bt_coexist.bt_service == BT_SCO) { | ||
1649 | if (rtlpcipriv->bt_coexist.ratio_tx > 160) { | ||
1650 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72f; | ||
1651 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72f; | ||
1652 | } else { | ||
1653 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea32b; | ||
1654 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea42b; | ||
1655 | } | ||
1656 | } else { | ||
1657 | rtlpcipriv->bt_coexist.bt_edca_ul = 0; | ||
1658 | rtlpcipriv->bt_coexist.bt_edca_dl = 0; | ||
1659 | } | ||
1660 | |||
1661 | if ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) && | ||
1662 | (rtlpriv->mac80211.mode == WIRELESS_MODE_G || | ||
1663 | (rtlpriv->mac80211.mode == (WIRELESS_MODE_G | WIRELESS_MODE_B))) && | ||
1664 | (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1665 | BT_RSSI_STATE_BG_EDCA_LOW)) { | ||
1666 | rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82b; | ||
1667 | rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82b; | ||
1668 | } | ||
1669 | } | ||
1670 | |||
1671 | static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw) | ||
1672 | { | ||
1673 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1674 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1675 | |||
1676 | |||
1677 | /* Only enable HW BT coexist when BT in "Busy" state. */ | ||
1678 | if (rtlpriv->mac80211.vendor == PEER_CISCO && | ||
1679 | rtlpcipriv->bt_coexist.bt_service == BT_OTHER_ACTION) { | ||
1680 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); | ||
1681 | } else { | ||
1682 | if ((rtlpcipriv->bt_coexist.bt_service == BT_BUSY) && | ||
1683 | (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1684 | BT_RSSI_STATE_NORMAL_POWER)) { | ||
1685 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); | ||
1686 | } else if ((rtlpcipriv->bt_coexist.bt_service == | ||
1687 | BT_OTHER_ACTION) && (rtlpriv->mac80211.mode < | ||
1688 | WIRELESS_MODE_N_24G) && | ||
1689 | (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1690 | BT_RSSI_STATE_SPECIAL_LOW)) { | ||
1691 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); | ||
1692 | } else if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) { | ||
1693 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); | ||
1694 | } else { | ||
1695 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); | ||
1696 | } | ||
1697 | } | ||
1698 | |||
1699 | if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) | ||
1700 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x10100); | ||
1701 | else | ||
1702 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x0); | ||
1703 | |||
1704 | if (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1705 | BT_RSSI_STATE_NORMAL_POWER) { | ||
1706 | rtl92c_bt_set_normal(hw); | ||
1707 | } else { | ||
1708 | rtlpcipriv->bt_coexist.bt_edca_ul = 0; | ||
1709 | rtlpcipriv->bt_coexist.bt_edca_dl = 0; | ||
1710 | } | ||
1711 | |||
1712 | if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) { | ||
1713 | rtlpriv->cfg->ops->set_rfreg(hw, | ||
1714 | RF90_PATH_A, | ||
1715 | 0x1e, | ||
1716 | 0xf0, 0xf); | ||
1717 | } else { | ||
1718 | rtlpriv->cfg->ops->set_rfreg(hw, | ||
1719 | RF90_PATH_A, 0x1e, 0xf0, | ||
1720 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); | ||
1721 | } | ||
1722 | |||
1723 | if (!rtlpriv->dm.dynamic_txpower_enable) { | ||
1724 | if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) { | ||
1725 | if (rtlpcipriv->bt_coexist.bt_rssi_state & | ||
1726 | BT_RSSI_STATE_TXPOWER_LOW) { | ||
1727 | rtlpriv->dm.dynamic_txhighpower_lvl = | ||
1728 | TXHIGHPWRLEVEL_BT2; | ||
1729 | } else { | ||
1730 | rtlpriv->dm.dynamic_txhighpower_lvl = | ||
1731 | TXHIGHPWRLEVEL_BT1; | ||
1732 | } | ||
1733 | } else { | ||
1734 | rtlpriv->dm.dynamic_txhighpower_lvl = | ||
1735 | TXHIGHPWRLEVEL_NORMAL; | ||
1736 | } | ||
1737 | rtl92c_phy_set_txpower_level(hw, | ||
1738 | rtlpriv->phy.current_channel); | ||
1739 | } | ||
1740 | } | ||
1741 | |||
1742 | static void rtl92c_check_bt_change(struct ieee80211_hw *hw) | ||
1743 | { | ||
1744 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1745 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1746 | |||
1747 | if (rtlpcipriv->bt_coexist.bt_cur_state) { | ||
1748 | if (rtlpcipriv->bt_coexist.bt_ant_isolation) | ||
1749 | rtl92c_bt_ant_isolation(hw); | ||
1750 | } else { | ||
1751 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); | ||
1752 | rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0, | ||
1753 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); | ||
1754 | |||
1755 | rtlpcipriv->bt_coexist.bt_edca_ul = 0; | ||
1756 | rtlpcipriv->bt_coexist.bt_edca_dl = 0; | ||
1757 | } | ||
1758 | } | ||
1759 | |||
1760 | void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw) | ||
1761 | { | ||
1762 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1763 | |||
1764 | bool wifi_connect_change; | ||
1765 | bool bt_state_change; | ||
1766 | bool rssi_state_change; | ||
1767 | |||
1768 | if ((rtlpcipriv->bt_coexist.bt_coexistence) && | ||
1769 | (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) { | ||
1770 | |||
1771 | wifi_connect_change = rtl92c_bt_wifi_connect_change(hw); | ||
1772 | bt_state_change = rtl92c_bt_state_change(hw); | ||
1773 | rssi_state_change = rtl92c_bt_rssi_state_change(hw); | ||
1774 | |||
1775 | if (wifi_connect_change || bt_state_change || rssi_state_change) | ||
1776 | rtl92c_check_bt_change(hw); | ||
1777 | } | ||
1778 | } | ||
1779 | EXPORT_SYMBOL(rtl92c_dm_bt_coexist); | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h index b9cbb0a3c03f..b9736d3e9a39 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h | |||
@@ -200,5 +200,7 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); | |||
200 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); | 200 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); |
201 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); | 201 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); |
202 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); | 202 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); |
203 | void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); | ||
204 | void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw); | ||
203 | 205 | ||
204 | #endif | 206 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index bc9d24134ac4..50303e1adff1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | |||
@@ -223,29 +223,15 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) | |||
223 | u8 *pfwdata; | 223 | u8 *pfwdata; |
224 | u32 fwsize; | 224 | u32 fwsize; |
225 | enum version_8192c version = rtlhal->version; | 225 | enum version_8192c version = rtlhal->version; |
226 | const struct firmware *firmware; | ||
227 | 226 | ||
228 | printk(KERN_INFO "rtl8192c: Loading firmware file %s\n", | 227 | printk(KERN_INFO "rtl8192c: Loading firmware file %s\n", |
229 | rtlpriv->cfg->fw_name); | 228 | rtlpriv->cfg->fw_name); |
230 | if (request_firmware(&firmware, rtlpriv->cfg->fw_name, | 229 | if (!rtlhal->pfirmware) |
231 | rtlpriv->io.dev)) { | ||
232 | printk(KERN_ERR "rtl8192c: Firmware loading failed\n"); | ||
233 | return 1; | 230 | return 1; |
234 | } | ||
235 | |||
236 | if (firmware->size > 0x4000) { | ||
237 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
238 | ("Firmware is too big!\n")); | ||
239 | release_firmware(firmware); | ||
240 | return 1; | ||
241 | } | ||
242 | |||
243 | memcpy(rtlhal->pfirmware, firmware->data, firmware->size); | ||
244 | fwsize = firmware->size; | ||
245 | release_firmware(firmware); | ||
246 | 231 | ||
247 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; | 232 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; |
248 | pfwdata = (u8 *) rtlhal->pfirmware; | 233 | pfwdata = (u8 *) rtlhal->pfirmware; |
234 | fwsize = rtlhal->fwsize; | ||
249 | 235 | ||
250 | if (IS_FW_HEADER_EXIST(pfwheader)) { | 236 | if (IS_FW_HEADER_EXIST(pfwheader)) { |
251 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, | 237 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, |
@@ -553,6 +539,39 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) | |||
553 | } | 539 | } |
554 | EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd); | 540 | EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd); |
555 | 541 | ||
542 | static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, | ||
543 | struct sk_buff *skb) | ||
544 | { | ||
545 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
546 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
547 | struct rtl8192_tx_ring *ring; | ||
548 | struct rtl_tx_desc *pdesc; | ||
549 | u8 own; | ||
550 | unsigned long flags; | ||
551 | struct sk_buff *pskb = NULL; | ||
552 | |||
553 | ring = &rtlpci->tx_ring[BEACON_QUEUE]; | ||
554 | |||
555 | pskb = __skb_dequeue(&ring->queue); | ||
556 | if (pskb) | ||
557 | kfree_skb(pskb); | ||
558 | |||
559 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); | ||
560 | |||
561 | pdesc = &ring->desc[0]; | ||
562 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); | ||
563 | |||
564 | rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); | ||
565 | |||
566 | __skb_queue_tail(&ring->queue, skb); | ||
567 | |||
568 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | ||
569 | |||
570 | rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); | ||
571 | |||
572 | return true; | ||
573 | } | ||
574 | |||
556 | #define BEACON_PG 0 /*->1*/ | 575 | #define BEACON_PG 0 /*->1*/ |
557 | #define PSPOLL_PG 2 | 576 | #define PSPOLL_PG 2 |
558 | #define NULL_PG 3 | 577 | #define NULL_PG 3 |
@@ -670,7 +689,7 @@ static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { | |||
670 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 689 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
671 | }; | 690 | }; |
672 | 691 | ||
673 | void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) | 692 | void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) |
674 | { | 693 | { |
675 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 694 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
676 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 695 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
@@ -679,12 +698,12 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) | |||
679 | u32 totalpacketlen; | 698 | u32 totalpacketlen; |
680 | bool rtstatus; | 699 | bool rtstatus; |
681 | u8 u1RsvdPageLoc[3] = {0}; | 700 | u8 u1RsvdPageLoc[3] = {0}; |
682 | bool b_dlok = false; | 701 | bool dlok = false; |
683 | 702 | ||
684 | u8 *beacon; | 703 | u8 *beacon; |
685 | u8 *p_pspoll; | 704 | u8 *pspoll; |
686 | u8 *nullfunc; | 705 | u8 *nullfunc; |
687 | u8 *p_probersp; | 706 | u8 *probersp; |
688 | /*--------------------------------------------------------- | 707 | /*--------------------------------------------------------- |
689 | (1) beacon | 708 | (1) beacon |
690 | ---------------------------------------------------------*/ | 709 | ---------------------------------------------------------*/ |
@@ -695,10 +714,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) | |||
695 | /*------------------------------------------------------- | 714 | /*------------------------------------------------------- |
696 | (2) ps-poll | 715 | (2) ps-poll |
697 | --------------------------------------------------------*/ | 716 | --------------------------------------------------------*/ |
698 | p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; | 717 | pspoll = &reserved_page_packet[PSPOLL_PG * 128]; |
699 | SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); | 718 | SET_80211_PS_POLL_AID(pspoll, (mac->assoc_id | 0xc000)); |
700 | SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); | 719 | SET_80211_PS_POLL_BSSID(pspoll, mac->bssid); |
701 | SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); | 720 | SET_80211_PS_POLL_TA(pspoll, mac->mac_addr); |
702 | 721 | ||
703 | SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); | 722 | SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); |
704 | 723 | ||
@@ -715,10 +734,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) | |||
715 | /*--------------------------------------------------------- | 734 | /*--------------------------------------------------------- |
716 | (4) probe response | 735 | (4) probe response |
717 | ----------------------------------------------------------*/ | 736 | ----------------------------------------------------------*/ |
718 | p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; | 737 | probersp = &reserved_page_packet[PROBERSP_PG * 128]; |
719 | SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); | 738 | SET_80211_HDR_ADDRESS1(probersp, mac->bssid); |
720 | SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); | 739 | SET_80211_HDR_ADDRESS2(probersp, mac->mac_addr); |
721 | SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); | 740 | SET_80211_HDR_ADDRESS3(probersp, mac->bssid); |
722 | 741 | ||
723 | SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); | 742 | SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); |
724 | 743 | ||
@@ -736,12 +755,12 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) | |||
736 | memcpy((u8 *) skb_put(skb, totalpacketlen), | 755 | memcpy((u8 *) skb_put(skb, totalpacketlen), |
737 | &reserved_page_packet, totalpacketlen); | 756 | &reserved_page_packet, totalpacketlen); |
738 | 757 | ||
739 | rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb); | 758 | rtstatus = _rtl92c_cmd_send_packet(hw, skb); |
740 | 759 | ||
741 | if (rtstatus) | 760 | if (rtstatus) |
742 | b_dlok = true; | 761 | dlok = true; |
743 | 762 | ||
744 | if (b_dlok) { | 763 | if (dlok) { |
745 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 764 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
746 | ("Set RSVD page location to Fw.\n")); | 765 | ("Set RSVD page location to Fw.\n")); |
747 | RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, | 766 | RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h index 3db33bd14666..3d5823c12621 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h | |||
@@ -27,8 +27,8 @@ | |||
27 | * | 27 | * |
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #ifndef __RTL92C__FW__H__ | 30 | #ifndef __RTL92C__FW__COMMON__H__ |
31 | #define __RTL92C__FW__H__ | 31 | #define __RTL92C__FW__COMMON__H__ |
32 | 32 | ||
33 | #define FW_8192C_SIZE 0x3000 | 33 | #define FW_8192C_SIZE 0x3000 |
34 | #define FW_8192C_START_ADDRESS 0x1000 | 34 | #define FW_8192C_START_ADDRESS 0x1000 |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index a70228278398..c5424cad43cb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | |||
@@ -78,27 +78,29 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, | |||
78 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | 78 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," |
79 | " data(%#x)\n", regaddr, bitmask, | 79 | " data(%#x)\n", regaddr, bitmask, |
80 | data)); | 80 | data)); |
81 | |||
81 | } | 82 | } |
82 | EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); | 83 | EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); |
83 | 84 | ||
84 | u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | 85 | u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, |
85 | enum radio_path rfpath, u32 offset) | 86 | enum radio_path rfpath, u32 offset) |
86 | { | 87 | { |
87 | RT_ASSERT(false, ("deprecated!\n")); | 88 | RT_ASSERT(false, ("deprecated!\n")); |
88 | return 0; | 89 | return 0; |
90 | |||
89 | } | 91 | } |
90 | EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read); | 92 | EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read); |
91 | 93 | ||
92 | void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | 94 | void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, |
93 | enum radio_path rfpath, u32 offset, | 95 | enum radio_path rfpath, u32 offset, |
94 | u32 data) | 96 | u32 data) |
95 | { | 97 | { |
96 | RT_ASSERT(false, ("deprecated!\n")); | 98 | RT_ASSERT(false, ("deprecated!\n")); |
97 | } | 99 | } |
98 | EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write); | 100 | EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write); |
99 | 101 | ||
100 | u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | 102 | u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, |
101 | enum radio_path rfpath, u32 offset) | 103 | enum radio_path rfpath, u32 offset) |
102 | { | 104 | { |
103 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 105 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
104 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 106 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -149,8 +151,8 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | |||
149 | EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); | 151 | EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); |
150 | 152 | ||
151 | void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | 153 | void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, |
152 | enum radio_path rfpath, u32 offset, | 154 | enum radio_path rfpath, u32 offset, |
153 | u32 data) | 155 | u32 data) |
154 | { | 156 | { |
155 | u32 data_and_addr; | 157 | u32 data_and_addr; |
156 | u32 newoffset; | 158 | u32 newoffset; |
@@ -197,6 +199,7 @@ static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) | |||
197 | rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); | 199 | rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); |
198 | rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); | 200 | rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); |
199 | } | 201 | } |
202 | |||
200 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) | 203 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) |
201 | { | 204 | { |
202 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 205 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -241,13 +244,14 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) | |||
241 | rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, | 244 | rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, |
242 | RFPGA0_XA_HSSIPARAMETER2, | 245 | RFPGA0_XA_HSSIPARAMETER2, |
243 | 0x200)); | 246 | 0x200)); |
247 | |||
244 | return true; | 248 | return true; |
245 | } | 249 | } |
246 | EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile); | 250 | EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile); |
247 | 251 | ||
248 | void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, | 252 | void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, |
249 | u32 regaddr, u32 bitmask, | 253 | u32 regaddr, u32 bitmask, |
250 | u32 data) | 254 | u32 data) |
251 | { | 255 | { |
252 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 256 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
253 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 257 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -317,61 +321,48 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, | |||
317 | } | 321 | } |
318 | if (regaddr == RTXAGC_B_RATE54_24) { | 322 | if (regaddr == RTXAGC_B_RATE54_24) { |
319 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; | 323 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; |
320 | |||
321 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 324 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
322 | ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", | 325 | ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", |
323 | rtlphy->pwrgroup_cnt, | 326 | rtlphy->pwrgroup_cnt, |
324 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); | 327 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); |
325 | } | 328 | } |
326 | |||
327 | if (regaddr == RTXAGC_B_CCK1_55_MCS32) { | 329 | if (regaddr == RTXAGC_B_CCK1_55_MCS32) { |
328 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; | 330 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; |
329 | |||
330 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 331 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
331 | ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", | 332 | ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", |
332 | rtlphy->pwrgroup_cnt, | 333 | rtlphy->pwrgroup_cnt, |
333 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); | 334 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); |
334 | } | 335 | } |
335 | |||
336 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { | 336 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { |
337 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; | 337 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; |
338 | |||
339 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 338 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
340 | ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", | 339 | ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", |
341 | rtlphy->pwrgroup_cnt, | 340 | rtlphy->pwrgroup_cnt, |
342 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); | 341 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); |
343 | } | 342 | } |
344 | |||
345 | if (regaddr == RTXAGC_B_MCS03_MCS00) { | 343 | if (regaddr == RTXAGC_B_MCS03_MCS00) { |
346 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; | 344 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; |
347 | |||
348 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 345 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
349 | ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", | 346 | ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", |
350 | rtlphy->pwrgroup_cnt, | 347 | rtlphy->pwrgroup_cnt, |
351 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); | 348 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); |
352 | } | 349 | } |
353 | |||
354 | if (regaddr == RTXAGC_B_MCS07_MCS04) { | 350 | if (regaddr == RTXAGC_B_MCS07_MCS04) { |
355 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; | 351 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; |
356 | |||
357 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 352 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
358 | ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", | 353 | ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", |
359 | rtlphy->pwrgroup_cnt, | 354 | rtlphy->pwrgroup_cnt, |
360 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); | 355 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); |
361 | } | 356 | } |
362 | |||
363 | if (regaddr == RTXAGC_B_MCS11_MCS08) { | 357 | if (regaddr == RTXAGC_B_MCS11_MCS08) { |
364 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; | 358 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; |
365 | |||
366 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 359 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
367 | ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", | 360 | ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", |
368 | rtlphy->pwrgroup_cnt, | 361 | rtlphy->pwrgroup_cnt, |
369 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); | 362 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); |
370 | } | 363 | } |
371 | |||
372 | if (regaddr == RTXAGC_B_MCS15_MCS12) { | 364 | if (regaddr == RTXAGC_B_MCS15_MCS12) { |
373 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; | 365 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; |
374 | |||
375 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 366 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
376 | ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", | 367 | ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", |
377 | rtlphy->pwrgroup_cnt, | 368 | rtlphy->pwrgroup_cnt, |
@@ -583,6 +574,7 @@ static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, | |||
583 | 574 | ||
584 | rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; | 575 | rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; |
585 | rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; | 576 | rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; |
577 | |||
586 | } | 578 | } |
587 | 579 | ||
588 | void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) | 580 | void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) |
@@ -611,7 +603,6 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) | |||
611 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 603 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
612 | u8 idx; | 604 | u8 idx; |
613 | u8 rf_path; | 605 | u8 rf_path; |
614 | |||
615 | u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, | 606 | u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, |
616 | WIRELESS_MODE_B, | 607 | WIRELESS_MODE_B, |
617 | power_indbm); | 608 | power_indbm); |
@@ -639,11 +630,6 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) | |||
639 | } | 630 | } |
640 | EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm); | 631 | EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm); |
641 | 632 | ||
642 | void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) | ||
643 | { | ||
644 | } | ||
645 | EXPORT_SYMBOL(rtl92c_phy_set_beacon_hw_reg); | ||
646 | |||
647 | u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | 633 | u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, |
648 | enum wireless_mode wirelessmode, | 634 | enum wireless_mode wirelessmode, |
649 | long power_indbm) | 635 | long power_indbm) |
@@ -741,9 +727,9 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, | |||
741 | if (rtlphy->set_bwmode_inprogress) | 727 | if (rtlphy->set_bwmode_inprogress) |
742 | return; | 728 | return; |
743 | rtlphy->set_bwmode_inprogress = true; | 729 | rtlphy->set_bwmode_inprogress = true; |
744 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) | 730 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { |
745 | rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); | 731 | rtlphy->set_bwmode_inprogress = false; |
746 | else { | 732 | } else { |
747 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 733 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
748 | ("FALSE driver sleep or unload\n")); | 734 | ("FALSE driver sleep or unload\n")); |
749 | rtlphy->set_bwmode_inprogress = false; | 735 | rtlphy->set_bwmode_inprogress = false; |
@@ -773,8 +759,9 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) | |||
773 | mdelay(delay); | 759 | mdelay(delay); |
774 | else | 760 | else |
775 | continue; | 761 | continue; |
776 | } else | 762 | } else { |
777 | rtlphy->sw_chnl_inprogress = false; | 763 | rtlphy->sw_chnl_inprogress = false; |
764 | } | ||
778 | break; | 765 | break; |
779 | } while (true); | 766 | } while (true); |
780 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | 767 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); |
@@ -811,9 +798,32 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) | |||
811 | } | 798 | } |
812 | EXPORT_SYMBOL(rtl92c_phy_sw_chnl); | 799 | EXPORT_SYMBOL(rtl92c_phy_sw_chnl); |
813 | 800 | ||
814 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | 801 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, |
815 | u8 channel, u8 *stage, u8 *step, | 802 | u32 cmdtableidx, u32 cmdtablesz, |
816 | u32 *delay) | 803 | enum swchnlcmd_id cmdid, |
804 | u32 para1, u32 para2, u32 msdelay) | ||
805 | { | ||
806 | struct swchnlcmd *pcmd; | ||
807 | |||
808 | if (cmdtable == NULL) { | ||
809 | RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); | ||
810 | return false; | ||
811 | } | ||
812 | |||
813 | if (cmdtableidx >= cmdtablesz) | ||
814 | return false; | ||
815 | |||
816 | pcmd = cmdtable + cmdtableidx; | ||
817 | pcmd->cmdid = cmdid; | ||
818 | pcmd->para1 = para1; | ||
819 | pcmd->para2 = para2; | ||
820 | pcmd->msdelay = msdelay; | ||
821 | return true; | ||
822 | } | ||
823 | |||
824 | bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
825 | u8 channel, u8 *stage, u8 *step, | ||
826 | u32 *delay) | ||
817 | { | 827 | { |
818 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 828 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
819 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 829 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -917,29 +927,6 @@ static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | |||
917 | return false; | 927 | return false; |
918 | } | 928 | } |
919 | 929 | ||
920 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
921 | u32 cmdtableidx, u32 cmdtablesz, | ||
922 | enum swchnlcmd_id cmdid, | ||
923 | u32 para1, u32 para2, u32 msdelay) | ||
924 | { | ||
925 | struct swchnlcmd *pcmd; | ||
926 | |||
927 | if (cmdtable == NULL) { | ||
928 | RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); | ||
929 | return false; | ||
930 | } | ||
931 | |||
932 | if (cmdtableidx >= cmdtablesz) | ||
933 | return false; | ||
934 | |||
935 | pcmd = cmdtable + cmdtableidx; | ||
936 | pcmd->cmdid = cmdid; | ||
937 | pcmd->para1 = para1; | ||
938 | pcmd->para2 = para2; | ||
939 | pcmd->msdelay = msdelay; | ||
940 | return true; | ||
941 | } | ||
942 | |||
943 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) | 930 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) |
944 | { | 931 | { |
945 | return true; | 932 | return true; |
@@ -1002,13 +989,13 @@ static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) | |||
1002 | reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); | 989 | reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); |
1003 | reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); | 990 | reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); |
1004 | reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); | 991 | reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); |
992 | |||
1005 | if (!(reg_eac & BIT(31)) && | 993 | if (!(reg_eac & BIT(31)) && |
1006 | (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && | 994 | (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && |
1007 | (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) | 995 | (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) |
1008 | result |= 0x01; | 996 | result |= 0x01; |
1009 | else | 997 | else |
1010 | return result; | 998 | return result; |
1011 | |||
1012 | if (!(reg_eac & BIT(30)) && | 999 | if (!(reg_eac & BIT(30)) && |
1013 | (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && | 1000 | (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && |
1014 | (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) | 1001 | (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) |
@@ -1023,9 +1010,9 @@ static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, | |||
1023 | u32 oldval_0, x, tx0_a, reg; | 1010 | u32 oldval_0, x, tx0_a, reg; |
1024 | long y, tx0_c; | 1011 | long y, tx0_c; |
1025 | 1012 | ||
1026 | if (final_candidate == 0xFF) | 1013 | if (final_candidate == 0xFF) { |
1027 | return; | 1014 | return; |
1028 | else if (iqk_ok) { | 1015 | } else if (iqk_ok) { |
1029 | oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | 1016 | oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, |
1030 | MASKDWORD) >> 22) & 0x3FF; | 1017 | MASKDWORD) >> 22) & 0x3FF; |
1031 | x = result[final_candidate][0]; | 1018 | x = result[final_candidate][0]; |
@@ -1063,9 +1050,9 @@ static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, | |||
1063 | u32 oldval_1, x, tx1_a, reg; | 1050 | u32 oldval_1, x, tx1_a, reg; |
1064 | long y, tx1_c; | 1051 | long y, tx1_c; |
1065 | 1052 | ||
1066 | if (final_candidate == 0xFF) | 1053 | if (final_candidate == 0xFF) { |
1067 | return; | 1054 | return; |
1068 | else if (iqk_ok) { | 1055 | } else if (iqk_ok) { |
1069 | oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, | 1056 | oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, |
1070 | MASKDWORD) >> 22) & 0x3FF; | 1057 | MASKDWORD) >> 22) & 0x3FF; |
1071 | x = result[final_candidate][4]; | 1058 | x = result[final_candidate][4]; |
@@ -1282,6 +1269,7 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, | |||
1282 | RFPGA0_XA_HSSIPARAMETER1, | 1269 | RFPGA0_XA_HSSIPARAMETER1, |
1283 | BIT(8)); | 1270 | BIT(8)); |
1284 | } | 1271 | } |
1272 | |||
1285 | if (!rtlphy->rfpi_enable) | 1273 | if (!rtlphy->rfpi_enable) |
1286 | _rtl92c_phy_pi_mode_switch(hw, true); | 1274 | _rtl92c_phy_pi_mode_switch(hw, true); |
1287 | if (t == 0) { | 1275 | if (t == 0) { |
@@ -1317,9 +1305,10 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, | |||
1317 | 0x3FF0000) >> 16; | 1305 | 0x3FF0000) >> 16; |
1318 | break; | 1306 | break; |
1319 | } else if (i == (retrycount - 1) && patha_ok == 0x01) | 1307 | } else if (i == (retrycount - 1) && patha_ok == 0x01) |
1308 | |||
1320 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, | 1309 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, |
1321 | MASKDWORD) & 0x3FF0000) >> | 1310 | MASKDWORD) & 0x3FF0000) >> |
1322 | 16; | 1311 | 16; |
1323 | result[t][1] = | 1312 | result[t][1] = |
1324 | (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; | 1313 | (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; |
1325 | 1314 | ||
@@ -1375,8 +1364,7 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, | |||
1375 | static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, | 1364 | static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, |
1376 | char delta, bool is2t) | 1365 | char delta, bool is2t) |
1377 | { | 1366 | { |
1378 | /* This routine is deliberately dummied out for later fixes */ | 1367 | #if 0 /* This routine is deliberately dummied out for later fixes */ |
1379 | #if 0 | ||
1380 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1368 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1381 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 1369 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
1382 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | 1370 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
@@ -1434,7 +1422,7 @@ static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, | |||
1434 | 0x04db25a4, 0x0b1b25a4 | 1422 | 0x04db25a4, 0x0b1b25a4 |
1435 | }; | 1423 | }; |
1436 | 1424 | ||
1437 | u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; | 1425 | const u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; |
1438 | 1426 | ||
1439 | u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; | 1427 | u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; |
1440 | 1428 | ||
@@ -1463,13 +1451,15 @@ static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, | |||
1463 | 0x00050006 | 1451 | 0x00050006 |
1464 | }; | 1452 | }; |
1465 | 1453 | ||
1466 | const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; | 1454 | u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; |
1467 | 1455 | ||
1468 | long bb_offset, delta_v, delta_offset; | 1456 | long bb_offset, delta_v, delta_offset; |
1469 | 1457 | ||
1470 | if (!is2t) | 1458 | if (!is2t) |
1471 | pathbound = 1; | 1459 | pathbound = 1; |
1472 | 1460 | ||
1461 | return; | ||
1462 | |||
1473 | for (index = 0; index < PATH_NUM; index++) { | 1463 | for (index = 0; index < PATH_NUM; index++) { |
1474 | apk_offset[index] = apk_normal_offset[index]; | 1464 | apk_offset[index] = apk_normal_offset[index]; |
1475 | apk_value[index] = apk_normal_value[index]; | 1465 | apk_value[index] = apk_normal_value[index]; |
@@ -1730,8 +1720,7 @@ static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, | |||
1730 | 0x08)); | 1720 | 0x08)); |
1731 | 1721 | ||
1732 | } | 1722 | } |
1733 | 1723 | rtlphy->b_apk_done = true; | |
1734 | rtlphy->apk_done = true; | ||
1735 | #endif | 1724 | #endif |
1736 | } | 1725 | } |
1737 | 1726 | ||
@@ -1758,6 +1747,7 @@ static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, | |||
1758 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); | 1747 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); |
1759 | 1748 | ||
1760 | } | 1749 | } |
1750 | |||
1761 | } | 1751 | } |
1762 | 1752 | ||
1763 | #undef IQK_ADDA_REG_NUM | 1753 | #undef IQK_ADDA_REG_NUM |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h index 53ffb0981586..9a264c0d6127 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h | |||
@@ -27,8 +27,8 @@ | |||
27 | * | 27 | * |
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #ifndef __RTL92C_PHY_H__ | 30 | #ifndef __RTL92C_PHY_COMMON_H__ |
31 | #define __RTL92C_PHY_H__ | 31 | #define __RTL92C_PHY_COMMON_H__ |
32 | 32 | ||
33 | #define MAX_PRECMD_CNT 16 | 33 | #define MAX_PRECMD_CNT 16 |
34 | #define MAX_RFDEPENDCMD_CNT 16 | 34 | #define MAX_RFDEPENDCMD_CNT 16 |
@@ -39,6 +39,7 @@ | |||
39 | #define RT_CANNOT_IO(hw) false | 39 | #define RT_CANNOT_IO(hw) false |
40 | #define HIGHPOWER_RADIOA_ARRAYLEN 22 | 40 | #define HIGHPOWER_RADIOA_ARRAYLEN 22 |
41 | 41 | ||
42 | #define IQK_ADDA_REG_NUM 16 | ||
42 | #define MAX_TOLERANCE 5 | 43 | #define MAX_TOLERANCE 5 |
43 | #define IQK_DELAY_TIME 1 | 44 | #define IQK_DELAY_TIME 1 |
44 | 45 | ||
@@ -56,6 +57,7 @@ | |||
56 | #define IQK_ADDA_REG_NUM 16 | 57 | #define IQK_ADDA_REG_NUM 16 |
57 | #define IQK_MAC_REG_NUM 4 | 58 | #define IQK_MAC_REG_NUM 4 |
58 | 59 | ||
60 | #define IQK_DELAY_TIME 1 | ||
59 | #define RF90_PATH_MAX 2 | 61 | #define RF90_PATH_MAX 2 |
60 | 62 | ||
61 | #define CT_OFFSET_MAC_ADDR 0X16 | 63 | #define CT_OFFSET_MAC_ADDR 0X16 |
@@ -77,6 +79,7 @@ | |||
77 | 79 | ||
78 | #define RTL92C_MAX_PATH_NUM 2 | 80 | #define RTL92C_MAX_PATH_NUM 2 |
79 | #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 | 81 | #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 |
82 | |||
80 | enum swchnlcmd_id { | 83 | enum swchnlcmd_id { |
81 | CMDID_END, | 84 | CMDID_END, |
82 | CMDID_SET_TXPOWEROWER_LEVEL, | 85 | CMDID_SET_TXPOWEROWER_LEVEL, |
@@ -184,45 +187,41 @@ struct tx_power_struct { | |||
184 | u32 mcs_original_offset[4][16]; | 187 | u32 mcs_original_offset[4][16]; |
185 | }; | 188 | }; |
186 | 189 | ||
187 | extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, | 190 | u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, |
188 | u32 regaddr, u32 bitmask); | 191 | u32 regaddr, u32 bitmask); |
189 | extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, | 192 | void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, |
190 | u32 regaddr, u32 bitmask, u32 data); | 193 | u32 regaddr, u32 bitmask, u32 data); |
191 | extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, | 194 | u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, |
192 | enum radio_path rfpath, u32 regaddr, | 195 | enum radio_path rfpath, u32 regaddr, |
193 | u32 bitmask); | 196 | u32 bitmask); |
194 | extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, | 197 | bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); |
195 | enum radio_path rfpath, u32 regaddr, | 198 | bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); |
196 | u32 bitmask, u32 data); | 199 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); |
197 | extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); | 200 | bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, |
198 | extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); | ||
199 | extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); | ||
200 | extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, | ||
201 | enum radio_path rfpath); | 201 | enum radio_path rfpath); |
202 | extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); | 202 | void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); |
203 | extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, | 203 | void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, |
204 | long *powerlevel); | 204 | long *powerlevel); |
205 | extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); | 205 | void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); |
206 | extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, | 206 | bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, |
207 | long power_indbm); | 207 | long power_indbm); |
208 | extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, | 208 | void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, |
209 | u8 operation); | 209 | u8 operation); |
210 | extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw); | 210 | void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, |
211 | extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
212 | enum nl80211_channel_type ch_type); | 211 | enum nl80211_channel_type ch_type); |
213 | extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); | 212 | void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); |
214 | extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); | 213 | u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); |
215 | extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); | 214 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); |
216 | extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, | 215 | void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, |
217 | u16 beaconinterval); | 216 | u16 beaconinterval); |
218 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); | 217 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); |
219 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); | 218 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); |
220 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); | 219 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); |
221 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | 220 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, |
222 | enum radio_path rfpath); | 221 | enum radio_path rfpath); |
223 | extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, | 222 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, |
224 | u32 rfpath); | 223 | u32 rfpath); |
225 | extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, | 224 | bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, |
226 | enum rf_pwrstate rfpwr_state); | 225 | enum rf_pwrstate rfpwr_state); |
227 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); | 226 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); |
228 | void rtl92c_phy_set_io(struct ieee80211_hw *hw); | 227 | void rtl92c_phy_set_io(struct ieee80211_hw *hw); |
@@ -235,12 +234,25 @@ u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | |||
235 | enum wireless_mode wirelessmode, | 234 | enum wireless_mode wirelessmode, |
236 | long power_indbm); | 235 | long power_indbm); |
237 | void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); | 236 | void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); |
238 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | 237 | void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw); |
239 | u32 cmdtableidx, u32 cmdtablesz, | 238 | bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, |
240 | enum swchnlcmd_id cmdid, u32 para1, | 239 | u8 channel, u8 *stage, u8 *step, |
241 | u32 para2, u32 msdelay); | 240 | u32 *delay); |
242 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | 241 | u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw); |
243 | u8 channel, u8 *stage, u8 *step, | 242 | u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, |
244 | u32 *delay); | 243 | enum radio_path rfpath, u32 offset); |
244 | void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
245 | enum radio_path rfpath, u32 offset, | ||
246 | u32 data); | ||
247 | u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
248 | enum radio_path rfpath, u32 offset); | ||
249 | void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
250 | enum radio_path rfpath, u32 offset, | ||
251 | u32 data); | ||
252 | bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); | ||
253 | void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, | ||
254 | u32 regaddr, u32 bitmask, | ||
255 | u32 data); | ||
256 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); | ||
245 | 257 | ||
246 | #endif | 258 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 2f577c8828fc..35ff7df41a1d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h | |||
@@ -121,19 +121,6 @@ | |||
121 | #define CHIP_92C 0x01 | 121 | #define CHIP_92C 0x01 |
122 | #define CHIP_88C 0x00 | 122 | #define CHIP_88C 0x00 |
123 | 123 | ||
124 | /* Add vendor information into chip version definition. | ||
125 | * Add UMC B-Cut and RTL8723 chip info definition. | ||
126 | * | ||
127 | * BIT 7 Reserved | ||
128 | * BIT 6 UMC BCut | ||
129 | * BIT 5 Manufacturer(TSMC/UMC) | ||
130 | * BIT 4 TEST/NORMAL | ||
131 | * BIT 3 8723 Version | ||
132 | * BIT 2 8723? | ||
133 | * BIT 1 1T2R? | ||
134 | * BIT 0 88C/92C | ||
135 | */ | ||
136 | |||
137 | enum version_8192c { | 124 | enum version_8192c { |
138 | VERSION_A_CHIP_92C = 0x01, | 125 | VERSION_A_CHIP_92C = 0x01, |
139 | VERSION_A_CHIP_88C = 0x00, | 126 | VERSION_A_CHIP_88C = 0x00, |
@@ -280,20 +267,6 @@ struct h2c_cmd_8192c { | |||
280 | u8 *p_cmdbuffer; | 267 | u8 *p_cmdbuffer; |
281 | }; | 268 | }; |
282 | 269 | ||
283 | static inline u8 _rtl92c_get_chnl_group(u8 chnl) | ||
284 | { | ||
285 | u8 group = 0; | ||
286 | |||
287 | if (chnl < 3) | ||
288 | group = 0; | ||
289 | else if (chnl < 9) | ||
290 | group = 1; | ||
291 | else | ||
292 | group = 2; | ||
293 | |||
294 | return group; | ||
295 | } | ||
296 | |||
297 | /* NOTE: reference to rtl8192c_rates struct */ | 270 | /* NOTE: reference to rtl8192c_rates struct */ |
298 | static inline int _rtl92c_rate_mapping(struct ieee80211_hw *hw, bool isHT, | 271 | static inline int _rtl92c_rate_mapping(struct ieee80211_hw *hw, bool isHT, |
299 | u8 desc_rate, bool first_ampdu) | 272 | u8 desc_rate, bool first_ampdu) |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 7d76504df4d1..2df33e53e15a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | |||
@@ -29,10 +29,12 @@ | |||
29 | 29 | ||
30 | #include "../wifi.h" | 30 | #include "../wifi.h" |
31 | #include "../base.h" | 31 | #include "../base.h" |
32 | #include "../pci.h" | ||
32 | #include "reg.h" | 33 | #include "reg.h" |
33 | #include "def.h" | 34 | #include "def.h" |
34 | #include "phy.h" | 35 | #include "phy.h" |
35 | #include "dm.h" | 36 | #include "dm.h" |
37 | #include "../rtl8192c/fw_common.h" | ||
36 | 38 | ||
37 | void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) | 39 | void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) |
38 | { | 40 | { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h index 36302ebae4a3..07dd9552e82f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h | |||
@@ -192,6 +192,7 @@ void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); | |||
192 | void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); | 192 | void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); |
193 | void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); | 193 | void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); |
194 | void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); | 194 | void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); |
195 | void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw); | ||
195 | void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw); | 196 | void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw); |
196 | 197 | ||
197 | #endif | 198 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 05477f465a75..4a56138eb33c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
@@ -30,12 +30,14 @@ | |||
30 | #include "../wifi.h" | 30 | #include "../wifi.h" |
31 | #include "../efuse.h" | 31 | #include "../efuse.h" |
32 | #include "../base.h" | 32 | #include "../base.h" |
33 | #include "../regd.h" | ||
33 | #include "../cam.h" | 34 | #include "../cam.h" |
34 | #include "../ps.h" | 35 | #include "../ps.h" |
35 | #include "../pci.h" | 36 | #include "../pci.h" |
36 | #include "reg.h" | 37 | #include "reg.h" |
37 | #include "def.h" | 38 | #include "def.h" |
38 | #include "phy.h" | 39 | #include "phy.h" |
40 | #include "../rtl8192c/fw_common.h" | ||
39 | #include "dm.h" | 41 | #include "dm.h" |
40 | #include "led.h" | 42 | #include "led.h" |
41 | #include "hw.h" | 43 | #include "hw.h" |
@@ -137,15 +139,6 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
137 | 139 | ||
138 | break; | 140 | break; |
139 | } | 141 | } |
140 | case HW_VAR_MGT_FILTER: | ||
141 | *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); | ||
142 | break; | ||
143 | case HW_VAR_CTRL_FILTER: | ||
144 | *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); | ||
145 | break; | ||
146 | case HW_VAR_DATA_FILTER: | ||
147 | *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); | ||
148 | break; | ||
149 | default: | 142 | default: |
150 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 143 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
151 | ("switch case not process\n")); | 144 | ("switch case not process\n")); |
@@ -156,6 +149,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
156 | void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | 149 | void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) |
157 | { | 150 | { |
158 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 151 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
152 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
159 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 153 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
160 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 154 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
161 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 155 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
@@ -178,7 +172,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
178 | rate_cfg |= 0x01; | 172 | rate_cfg |= 0x01; |
179 | rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); | 173 | rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); |
180 | rtl_write_byte(rtlpriv, REG_RRSR + 1, | 174 | rtl_write_byte(rtlpriv, REG_RRSR + 1, |
181 | (rate_cfg >> 8)&0xff); | 175 | (rate_cfg >> 8) & 0xff); |
182 | while (rate_cfg > 0x1) { | 176 | while (rate_cfg > 0x1) { |
183 | rate_cfg = (rate_cfg >> 1); | 177 | rate_cfg = (rate_cfg >> 1); |
184 | rate_index++; | 178 | rate_index++; |
@@ -276,13 +270,19 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
276 | break; | 270 | break; |
277 | } | 271 | } |
278 | case HW_VAR_AMPDU_FACTOR:{ | 272 | case HW_VAR_AMPDU_FACTOR:{ |
279 | u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; | 273 | u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; |
274 | u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97}; | ||
280 | 275 | ||
281 | u8 factor_toset; | 276 | u8 factor_toset; |
282 | u8 *p_regtoset = NULL; | 277 | u8 *p_regtoset = NULL; |
283 | u8 index = 0; | 278 | u8 index = 0; |
284 | 279 | ||
285 | p_regtoset = regtoset_normal; | 280 | if ((rtlpcipriv->bt_coexist.bt_coexistence) && |
281 | (rtlpcipriv->bt_coexist.bt_coexist_type == | ||
282 | BT_CSR_BC4)) | ||
283 | p_regtoset = regtoset_bt; | ||
284 | else | ||
285 | p_regtoset = regtoset_normal; | ||
286 | 286 | ||
287 | factor_toset = *((u8 *) val); | 287 | factor_toset = *((u8 *) val); |
288 | if (factor_toset <= 3) { | 288 | if (factor_toset <= 3) { |
@@ -317,45 +317,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
317 | } | 317 | } |
318 | case HW_VAR_AC_PARAM:{ | 318 | case HW_VAR_AC_PARAM:{ |
319 | u8 e_aci = *((u8 *) val); | 319 | u8 e_aci = *((u8 *) val); |
320 | u32 u4b_ac_param; | 320 | rtl92c_dm_init_edca_turbo(hw); |
321 | u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); | ||
322 | u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); | ||
323 | u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op); | ||
324 | |||
325 | u4b_ac_param = (u32) mac->ac[e_aci].aifs; | ||
326 | u4b_ac_param |= ((u32)cw_min | ||
327 | & 0xF) << AC_PARAM_ECW_MIN_OFFSET; | ||
328 | u4b_ac_param |= ((u32)cw_max & | ||
329 | 0xF) << AC_PARAM_ECW_MAX_OFFSET; | ||
330 | u4b_ac_param |= (u32)tx_op << AC_PARAM_TXOP_OFFSET; | ||
331 | |||
332 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
333 | ("queue:%x, ac_param:%x\n", e_aci, | ||
334 | u4b_ac_param)); | ||
335 | |||
336 | switch (e_aci) { | ||
337 | case AC1_BK: | ||
338 | rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, | ||
339 | u4b_ac_param); | ||
340 | break; | ||
341 | case AC0_BE: | ||
342 | rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, | ||
343 | u4b_ac_param); | ||
344 | break; | ||
345 | case AC2_VI: | ||
346 | rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, | ||
347 | u4b_ac_param); | ||
348 | break; | ||
349 | case AC3_VO: | ||
350 | rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, | ||
351 | u4b_ac_param); | ||
352 | break; | ||
353 | default: | ||
354 | RT_ASSERT(false, | ||
355 | ("SetHwReg8185(): invalid aci: %d !\n", | ||
356 | e_aci)); | ||
357 | break; | ||
358 | } | ||
359 | 321 | ||
360 | if (rtlpci->acm_method != eAcmWay2_SW) | 322 | if (rtlpci->acm_method != eAcmWay2_SW) |
361 | rtlpriv->cfg->ops->set_hw_reg(hw, | 323 | rtlpriv->cfg->ops->set_hw_reg(hw, |
@@ -526,9 +488,6 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
526 | case HW_VAR_CORRECT_TSF:{ | 488 | case HW_VAR_CORRECT_TSF:{ |
527 | u8 btype_ibss = ((u8 *) (val))[0]; | 489 | u8 btype_ibss = ((u8 *) (val))[0]; |
528 | 490 | ||
529 | /*btype_ibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? | ||
530 | 1 : 0;*/ | ||
531 | |||
532 | if (btype_ibss == true) | 491 | if (btype_ibss == true) |
533 | _rtl92ce_stop_tx_beacon(hw); | 492 | _rtl92ce_stop_tx_beacon(hw); |
534 | 493 | ||
@@ -537,7 +496,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
537 | rtl_write_dword(rtlpriv, REG_TSFTR, | 496 | rtl_write_dword(rtlpriv, REG_TSFTR, |
538 | (u32) (mac->tsf & 0xffffffff)); | 497 | (u32) (mac->tsf & 0xffffffff)); |
539 | rtl_write_dword(rtlpriv, REG_TSFTR + 4, | 498 | rtl_write_dword(rtlpriv, REG_TSFTR + 4, |
540 | (u32) ((mac->tsf >> 32)&0xffffffff)); | 499 | (u32) ((mac->tsf >> 32) & 0xffffffff)); |
541 | 500 | ||
542 | _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); | 501 | _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); |
543 | 502 | ||
@@ -547,15 +506,6 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
547 | break; | 506 | break; |
548 | 507 | ||
549 | } | 508 | } |
550 | case HW_VAR_MGT_FILTER: | ||
551 | rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *) val); | ||
552 | break; | ||
553 | case HW_VAR_CTRL_FILTER: | ||
554 | rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *) val); | ||
555 | break; | ||
556 | case HW_VAR_DATA_FILTER: | ||
557 | rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *) val); | ||
558 | break; | ||
559 | default: | 509 | default: |
560 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " | 510 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " |
561 | "not process\n")); | 511 | "not process\n")); |
@@ -679,12 +629,12 @@ static void _rtl92ce_gen_refresh_led_state(struct ieee80211_hw *hw) | |||
679 | rtl92ce_sw_led_on(hw, pLed0); | 629 | rtl92ce_sw_led_on(hw, pLed0); |
680 | else | 630 | else |
681 | rtl92ce_sw_led_off(hw, pLed0); | 631 | rtl92ce_sw_led_off(hw, pLed0); |
682 | |||
683 | } | 632 | } |
684 | 633 | ||
685 | static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) | 634 | static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) |
686 | { | 635 | { |
687 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 636 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
637 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
688 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 638 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
689 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 639 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
690 | 640 | ||
@@ -693,9 +643,22 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) | |||
693 | u16 retry; | 643 | u16 retry; |
694 | 644 | ||
695 | rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); | 645 | rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); |
646 | if (rtlpcipriv->bt_coexist.bt_coexistence) { | ||
647 | u32 value32; | ||
648 | value32 = rtl_read_dword(rtlpriv, REG_APS_FSMCO); | ||
649 | value32 |= (SOP_ABG | SOP_AMB | XOP_BTCK); | ||
650 | rtl_write_dword(rtlpriv, REG_APS_FSMCO, value32); | ||
651 | } | ||
696 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); | 652 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); |
697 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); | 653 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); |
698 | 654 | ||
655 | if (rtlpcipriv->bt_coexist.bt_coexistence) { | ||
656 | u32 u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); | ||
657 | |||
658 | u4b_tmp &= (~0x00024800); | ||
659 | rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp); | ||
660 | } | ||
661 | |||
699 | bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0); | 662 | bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0); |
700 | udelay(2); | 663 | udelay(2); |
701 | 664 | ||
@@ -726,6 +689,11 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) | |||
726 | rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82); | 689 | rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82); |
727 | udelay(2); | 690 | udelay(2); |
728 | 691 | ||
692 | if (rtlpcipriv->bt_coexist.bt_coexistence) { | ||
693 | bytetmp = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2) & 0xfd; | ||
694 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, bytetmp); | ||
695 | } | ||
696 | |||
729 | rtl_write_word(rtlpriv, REG_CR, 0x2ff); | 697 | rtl_write_word(rtlpriv, REG_CR, 0x2ff); |
730 | 698 | ||
731 | if (_rtl92ce_llt_table_init(hw) == false) | 699 | if (_rtl92ce_llt_table_init(hw) == false) |
@@ -793,6 +761,7 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) | |||
793 | { | 761 | { |
794 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 762 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
795 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 763 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
764 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
796 | u8 reg_bw_opmode; | 765 | u8 reg_bw_opmode; |
797 | u32 reg_ratr, reg_prsr; | 766 | u32 reg_ratr, reg_prsr; |
798 | 767 | ||
@@ -824,7 +793,11 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) | |||
824 | rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); | 793 | rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); |
825 | rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); | 794 | rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); |
826 | 795 | ||
827 | rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); | 796 | if ((rtlpcipriv->bt_coexist.bt_coexistence) && |
797 | (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) | ||
798 | rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431); | ||
799 | else | ||
800 | rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); | ||
828 | 801 | ||
829 | rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); | 802 | rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); |
830 | 803 | ||
@@ -840,11 +813,20 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) | |||
840 | rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); | 813 | rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); |
841 | rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); | 814 | rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); |
842 | 815 | ||
843 | rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); | 816 | if ((rtlpcipriv->bt_coexist.bt_coexistence) && |
844 | 817 | (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) { | |
845 | rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); | 818 | rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); |
819 | rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402); | ||
820 | } else { | ||
821 | rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); | ||
822 | rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); | ||
823 | } | ||
846 | 824 | ||
847 | rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); | 825 | if ((rtlpcipriv->bt_coexist.bt_coexistence) && |
826 | (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) | ||
827 | rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); | ||
828 | else | ||
829 | rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); | ||
848 | 830 | ||
849 | rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); | 831 | rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); |
850 | 832 | ||
@@ -948,8 +930,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
948 | } | 930 | } |
949 | 931 | ||
950 | rtlhal->last_hmeboxnum = 0; | 932 | rtlhal->last_hmeboxnum = 0; |
951 | rtl92ce_phy_mac_config(hw); | 933 | rtl92c_phy_mac_config(hw); |
952 | rtl92ce_phy_bb_config(hw); | 934 | rtl92c_phy_bb_config(hw); |
953 | rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; | 935 | rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; |
954 | rtl92c_phy_rf_config(hw); | 936 | rtl92c_phy_rf_config(hw); |
955 | rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, | 937 | rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, |
@@ -962,15 +944,20 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
962 | _rtl92ce_hw_configure(hw); | 944 | _rtl92ce_hw_configure(hw); |
963 | rtl_cam_reset_all_entry(hw); | 945 | rtl_cam_reset_all_entry(hw); |
964 | rtl92ce_enable_hw_security_config(hw); | 946 | rtl92ce_enable_hw_security_config(hw); |
947 | |||
965 | ppsc->rfpwr_state = ERFON; | 948 | ppsc->rfpwr_state = ERFON; |
949 | |||
966 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); | 950 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); |
967 | _rtl92ce_enable_aspm_back_door(hw); | 951 | _rtl92ce_enable_aspm_back_door(hw); |
968 | rtlpriv->intf_ops->enable_aspm(hw); | 952 | rtlpriv->intf_ops->enable_aspm(hw); |
953 | |||
954 | rtl8192ce_bt_hw_init(hw); | ||
955 | |||
969 | if (ppsc->rfpwr_state == ERFON) { | 956 | if (ppsc->rfpwr_state == ERFON) { |
970 | rtl92c_phy_set_rfpath_switch(hw, 1); | 957 | rtl92c_phy_set_rfpath_switch(hw, 1); |
971 | if (iqk_initialized) | 958 | if (iqk_initialized) { |
972 | rtl92c_phy_iq_calibrate(hw, true); | 959 | rtl92c_phy_iq_calibrate(hw, true); |
973 | else { | 960 | } else { |
974 | rtl92c_phy_iq_calibrate(hw, false); | 961 | rtl92c_phy_iq_calibrate(hw, false); |
975 | iqk_initialized = true; | 962 | iqk_initialized = true; |
976 | } | 963 | } |
@@ -1128,75 +1115,62 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, | |||
1128 | return 0; | 1115 | return 0; |
1129 | } | 1116 | } |
1130 | 1117 | ||
1131 | static void _rtl92ce_set_check_bssid(struct ieee80211_hw *hw, | 1118 | void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) |
1132 | enum nl80211_iftype type) | ||
1133 | { | 1119 | { |
1134 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1120 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1135 | u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); | 1121 | u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); |
1136 | u8 filterout_non_associated_bssid = false; | ||
1137 | 1122 | ||
1138 | switch (type) { | 1123 | if (rtlpriv->psc.rfpwr_state != ERFON) |
1139 | case NL80211_IFTYPE_ADHOC: | 1124 | return; |
1140 | case NL80211_IFTYPE_STATION: | ||
1141 | filterout_non_associated_bssid = true; | ||
1142 | break; | ||
1143 | case NL80211_IFTYPE_UNSPECIFIED: | ||
1144 | case NL80211_IFTYPE_AP: | ||
1145 | default: | ||
1146 | break; | ||
1147 | } | ||
1148 | 1125 | ||
1149 | if (filterout_non_associated_bssid == true) { | 1126 | if (check_bssid == true) { |
1150 | reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); | 1127 | reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); |
1151 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, | 1128 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, |
1152 | (u8 *) (®_rcr)); | 1129 | (u8 *) (®_rcr)); |
1153 | _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); | 1130 | _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); |
1154 | } else if (filterout_non_associated_bssid == false) { | 1131 | } else if (check_bssid == false) { |
1155 | reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); | 1132 | reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); |
1156 | _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); | 1133 | _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); |
1157 | rtlpriv->cfg->ops->set_hw_reg(hw, | 1134 | rtlpriv->cfg->ops->set_hw_reg(hw, |
1158 | HW_VAR_RCR, (u8 *) (®_rcr)); | 1135 | HW_VAR_RCR, (u8 *) (®_rcr)); |
1159 | } | 1136 | } |
1137 | |||
1160 | } | 1138 | } |
1161 | 1139 | ||
1162 | int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) | 1140 | int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) |
1163 | { | 1141 | { |
1142 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1143 | |||
1164 | if (_rtl92ce_set_media_status(hw, type)) | 1144 | if (_rtl92ce_set_media_status(hw, type)) |
1165 | return -EOPNOTSUPP; | 1145 | return -EOPNOTSUPP; |
1166 | _rtl92ce_set_check_bssid(hw, type); | 1146 | |
1147 | if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { | ||
1148 | if (type != NL80211_IFTYPE_AP) | ||
1149 | rtl92ce_set_check_bssid(hw, true); | ||
1150 | } else { | ||
1151 | rtl92ce_set_check_bssid(hw, false); | ||
1152 | } | ||
1153 | |||
1167 | return 0; | 1154 | return 0; |
1168 | } | 1155 | } |
1169 | 1156 | ||
1157 | /* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ | ||
1170 | void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) | 1158 | void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) |
1171 | { | 1159 | { |
1172 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1160 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1173 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1174 | u32 u4b_ac_param; | ||
1175 | u16 cw_min = le16_to_cpu(mac->ac[aci].cw_min); | ||
1176 | u16 cw_max = le16_to_cpu(mac->ac[aci].cw_max); | ||
1177 | u16 tx_op = le16_to_cpu(mac->ac[aci].tx_op); | ||
1178 | |||
1179 | rtl92c_dm_init_edca_turbo(hw); | 1161 | rtl92c_dm_init_edca_turbo(hw); |
1180 | u4b_ac_param = (u32) mac->ac[aci].aifs; | ||
1181 | u4b_ac_param |= (u32) ((cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET); | ||
1182 | u4b_ac_param |= (u32) ((cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET); | ||
1183 | u4b_ac_param |= (u32) (tx_op << AC_PARAM_TXOP_OFFSET); | ||
1184 | RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG, | ||
1185 | ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n", | ||
1186 | aci, u4b_ac_param, mac->ac[aci].aifs, cw_min, | ||
1187 | cw_max, tx_op)); | ||
1188 | switch (aci) { | 1162 | switch (aci) { |
1189 | case AC1_BK: | 1163 | case AC1_BK: |
1190 | rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); | 1164 | rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); |
1191 | break; | 1165 | break; |
1192 | case AC0_BE: | 1166 | case AC0_BE: |
1193 | rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); | 1167 | /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */ |
1194 | break; | 1168 | break; |
1195 | case AC2_VI: | 1169 | case AC2_VI: |
1196 | rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param); | 1170 | rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); |
1197 | break; | 1171 | break; |
1198 | case AC3_VO: | 1172 | case AC3_VO: |
1199 | rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); | 1173 | rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); |
1200 | break; | 1174 | break; |
1201 | default: | 1175 | default: |
1202 | RT_ASSERT(false, ("invalid aci: %d !\n", aci)); | 1176 | RT_ASSERT(false, ("invalid aci: %d !\n", aci)); |
@@ -1227,8 +1201,10 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw) | |||
1227 | static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) | 1201 | static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) |
1228 | { | 1202 | { |
1229 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1203 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1204 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1230 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 1205 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
1231 | u8 u1b_tmp; | 1206 | u8 u1b_tmp; |
1207 | u32 u4b_tmp; | ||
1232 | 1208 | ||
1233 | rtlpriv->intf_ops->enable_aspm(hw); | 1209 | rtlpriv->intf_ops->enable_aspm(hw); |
1234 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | 1210 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); |
@@ -1243,13 +1219,27 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) | |||
1243 | rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); | 1219 | rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); |
1244 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000); | 1220 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000); |
1245 | u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); | 1221 | u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); |
1246 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 | | 1222 | if ((rtlpcipriv->bt_coexist.bt_coexistence) && |
1247 | (u1b_tmp << 8)); | 1223 | ((rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) || |
1224 | (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC8))) { | ||
1225 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00F30000 | | ||
1226 | (u1b_tmp << 8)); | ||
1227 | } else { | ||
1228 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 | | ||
1229 | (u1b_tmp << 8)); | ||
1230 | } | ||
1248 | rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); | 1231 | rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); |
1249 | rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); | 1232 | rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); |
1250 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); | 1233 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); |
1251 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); | 1234 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); |
1252 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); | 1235 | if (rtlpcipriv->bt_coexist.bt_coexistence) { |
1236 | u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); | ||
1237 | u4b_tmp |= 0x03824800; | ||
1238 | rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp); | ||
1239 | } else { | ||
1240 | rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); | ||
1241 | } | ||
1242 | |||
1253 | rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); | 1243 | rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); |
1254 | rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); | 1244 | rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); |
1255 | } | 1245 | } |
@@ -1327,6 +1317,7 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, | |||
1327 | 1317 | ||
1328 | RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, | 1318 | RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, |
1329 | ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); | 1319 | ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); |
1320 | |||
1330 | if (add_msr) | 1321 | if (add_msr) |
1331 | rtlpci->irq_mask[0] |= add_msr; | 1322 | rtlpci->irq_mask[0] |= add_msr; |
1332 | if (rm_msr) | 1323 | if (rm_msr) |
@@ -1582,7 +1573,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) | |||
1582 | ("RTL819X Not boot from eeprom, check it !!")); | 1573 | ("RTL819X Not boot from eeprom, check it !!")); |
1583 | } | 1574 | } |
1584 | 1575 | ||
1585 | RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), | 1576 | RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), |
1586 | hwinfo, HWSET_MAX_SIZE); | 1577 | hwinfo, HWSET_MAX_SIZE); |
1587 | 1578 | ||
1588 | eeprom_id = *((u16 *)&hwinfo[0]); | 1579 | eeprom_id = *((u16 *)&hwinfo[0]); |
@@ -1610,6 +1601,10 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) | |||
1610 | rtlefuse->autoload_failflag, | 1601 | rtlefuse->autoload_failflag, |
1611 | hwinfo); | 1602 | hwinfo); |
1612 | 1603 | ||
1604 | rtl8192ce_read_bt_coexist_info_from_hwpg(hw, | ||
1605 | rtlefuse->autoload_failflag, | ||
1606 | hwinfo); | ||
1607 | |||
1613 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | 1608 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; |
1614 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; | 1609 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; |
1615 | rtlefuse->txpwr_fromeprom = true; | 1610 | rtlefuse->txpwr_fromeprom = true; |
@@ -1618,6 +1613,9 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) | |||
1618 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | 1613 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, |
1619 | ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); | 1614 | ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); |
1620 | 1615 | ||
1616 | /* set channel paln to world wide 13 */ | ||
1617 | rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; | ||
1618 | |||
1621 | if (rtlhal->oem_id == RT_CID_DEFAULT) { | 1619 | if (rtlhal->oem_id == RT_CID_DEFAULT) { |
1622 | switch (rtlefuse->eeprom_oemid) { | 1620 | switch (rtlefuse->eeprom_oemid) { |
1623 | case EEPROM_CID_DEFAULT: | 1621 | case EEPROM_CID_DEFAULT: |
@@ -1701,30 +1699,36 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) | |||
1701 | } else { | 1699 | } else { |
1702 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); | 1700 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); |
1703 | } | 1701 | } |
1704 | |||
1705 | _rtl92ce_hal_customized_behavior(hw); | 1702 | _rtl92ce_hal_customized_behavior(hw); |
1706 | } | 1703 | } |
1707 | 1704 | ||
1708 | void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) | 1705 | static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw, |
1706 | struct ieee80211_sta *sta) | ||
1709 | { | 1707 | { |
1710 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1708 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1709 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1711 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 1710 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
1712 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1711 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
1713 | 1712 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
1714 | u32 ratr_value = (u32) mac->basic_rates; | 1713 | u32 ratr_value; |
1715 | u8 *mcsrate = mac->mcs; | ||
1716 | u8 ratr_index = 0; | 1714 | u8 ratr_index = 0; |
1717 | u8 nmode = mac->ht_enable; | 1715 | u8 nmode = mac->ht_enable; |
1718 | u8 mimo_ps = 1; | 1716 | u8 mimo_ps = IEEE80211_SMPS_OFF; |
1719 | u16 shortgi_rate; | 1717 | u16 shortgi_rate; |
1720 | u32 tmp_ratr_value; | 1718 | u32 tmp_ratr_value; |
1721 | u8 curtxbw_40mhz = mac->bw_40; | 1719 | u8 curtxbw_40mhz = mac->bw_40; |
1722 | u8 curshortgi_40mhz = mac->sgi_40; | 1720 | u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? |
1723 | u8 curshortgi_20mhz = mac->sgi_20; | 1721 | 1 : 0; |
1722 | u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? | ||
1723 | 1 : 0; | ||
1724 | enum wireless_mode wirelessmode = mac->mode; | 1724 | enum wireless_mode wirelessmode = mac->mode; |
1725 | 1725 | ||
1726 | ratr_value |= ((*(u16 *) (mcsrate))) << 12; | 1726 | if (rtlhal->current_bandtype == BAND_ON_5G) |
1727 | 1727 | ratr_value = sta->supp_rates[1] << 4; | |
1728 | else | ||
1729 | ratr_value = sta->supp_rates[0]; | ||
1730 | ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | | ||
1731 | sta->ht_cap.mcs.rx_mask[0] << 12); | ||
1728 | switch (wirelessmode) { | 1732 | switch (wirelessmode) { |
1729 | case WIRELESS_MODE_B: | 1733 | case WIRELESS_MODE_B: |
1730 | if (ratr_value & 0x0000000c) | 1734 | if (ratr_value & 0x0000000c) |
@@ -1738,7 +1742,7 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) | |||
1738 | case WIRELESS_MODE_N_24G: | 1742 | case WIRELESS_MODE_N_24G: |
1739 | case WIRELESS_MODE_N_5G: | 1743 | case WIRELESS_MODE_N_5G: |
1740 | nmode = 1; | 1744 | nmode = 1; |
1741 | if (mimo_ps == 0) { | 1745 | if (mimo_ps == IEEE80211_SMPS_STATIC) { |
1742 | ratr_value &= 0x0007F005; | 1746 | ratr_value &= 0x0007F005; |
1743 | } else { | 1747 | } else { |
1744 | u32 ratr_mask; | 1748 | u32 ratr_mask; |
@@ -1761,10 +1765,19 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) | |||
1761 | break; | 1765 | break; |
1762 | } | 1766 | } |
1763 | 1767 | ||
1764 | ratr_value &= 0x0FFFFFFF; | 1768 | if ((rtlpcipriv->bt_coexist.bt_coexistence) && |
1769 | (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) && | ||
1770 | (rtlpcipriv->bt_coexist.bt_cur_state) && | ||
1771 | (rtlpcipriv->bt_coexist.bt_ant_isolation) && | ||
1772 | ((rtlpcipriv->bt_coexist.bt_service == BT_SCO) || | ||
1773 | (rtlpcipriv->bt_coexist.bt_service == BT_BUSY))) | ||
1774 | ratr_value &= 0x0fffcfc0; | ||
1775 | else | ||
1776 | ratr_value &= 0x0FFFFFFF; | ||
1765 | 1777 | ||
1766 | if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || (!curtxbw_40mhz && | 1778 | if (nmode && ((curtxbw_40mhz && |
1767 | curshortgi_20mhz))) { | 1779 | curshortgi_40mhz) || (!curtxbw_40mhz && |
1780 | curshortgi_20mhz))) { | ||
1768 | 1781 | ||
1769 | ratr_value |= 0x10000000; | 1782 | ratr_value |= 0x10000000; |
1770 | tmp_ratr_value = (ratr_value >> 12); | 1783 | tmp_ratr_value = (ratr_value >> 12); |
@@ -1784,24 +1797,42 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) | |||
1784 | ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); | 1797 | ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); |
1785 | } | 1798 | } |
1786 | 1799 | ||
1787 | void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | 1800 | static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, |
1801 | struct ieee80211_sta *sta, u8 rssi_level) | ||
1788 | { | 1802 | { |
1789 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1803 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1790 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 1804 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
1791 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1805 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
1792 | u32 ratr_bitmap = (u32) mac->basic_rates; | 1806 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
1793 | u8 *p_mcsrate = mac->mcs; | 1807 | struct rtl_sta_info *sta_entry = NULL; |
1808 | u32 ratr_bitmap; | ||
1794 | u8 ratr_index; | 1809 | u8 ratr_index; |
1795 | u8 curtxbw_40mhz = mac->bw_40; | 1810 | u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) |
1796 | u8 curshortgi_40mhz = mac->sgi_40; | 1811 | ? 1 : 0; |
1797 | u8 curshortgi_20mhz = mac->sgi_20; | 1812 | u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? |
1798 | enum wireless_mode wirelessmode = mac->mode; | 1813 | 1 : 0; |
1814 | u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? | ||
1815 | 1 : 0; | ||
1816 | enum wireless_mode wirelessmode = 0; | ||
1799 | bool shortgi = false; | 1817 | bool shortgi = false; |
1800 | u8 rate_mask[5]; | 1818 | u8 rate_mask[5]; |
1801 | u8 macid = 0; | 1819 | u8 macid = 0; |
1802 | u8 mimops = 1; | 1820 | u8 mimo_ps = IEEE80211_SMPS_OFF; |
1803 | 1821 | ||
1804 | ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); | 1822 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; |
1823 | wirelessmode = sta_entry->wireless_mode; | ||
1824 | if (mac->opmode == NL80211_IFTYPE_STATION) | ||
1825 | curtxbw_40mhz = mac->bw_40; | ||
1826 | else if (mac->opmode == NL80211_IFTYPE_AP || | ||
1827 | mac->opmode == NL80211_IFTYPE_ADHOC) | ||
1828 | macid = sta->aid + 1; | ||
1829 | |||
1830 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
1831 | ratr_bitmap = sta->supp_rates[1] << 4; | ||
1832 | else | ||
1833 | ratr_bitmap = sta->supp_rates[0]; | ||
1834 | ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | | ||
1835 | sta->ht_cap.mcs.rx_mask[0] << 12); | ||
1805 | switch (wirelessmode) { | 1836 | switch (wirelessmode) { |
1806 | case WIRELESS_MODE_B: | 1837 | case WIRELESS_MODE_B: |
1807 | ratr_index = RATR_INX_WIRELESS_B; | 1838 | ratr_index = RATR_INX_WIRELESS_B; |
@@ -1828,7 +1859,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
1828 | case WIRELESS_MODE_N_5G: | 1859 | case WIRELESS_MODE_N_5G: |
1829 | ratr_index = RATR_INX_WIRELESS_NGB; | 1860 | ratr_index = RATR_INX_WIRELESS_NGB; |
1830 | 1861 | ||
1831 | if (mimops == 0) { | 1862 | if (mimo_ps == IEEE80211_SMPS_STATIC) { |
1832 | if (rssi_level == 1) | 1863 | if (rssi_level == 1) |
1833 | ratr_bitmap &= 0x00070000; | 1864 | ratr_bitmap &= 0x00070000; |
1834 | else if (rssi_level == 2) | 1865 | else if (rssi_level == 2) |
@@ -1892,8 +1923,8 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
1892 | } | 1923 | } |
1893 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | 1924 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, |
1894 | ("ratr_bitmap :%x\n", ratr_bitmap)); | 1925 | ("ratr_bitmap :%x\n", ratr_bitmap)); |
1895 | *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | | 1926 | *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | |
1896 | (ratr_index << 28); | 1927 | (ratr_index << 28)); |
1897 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; | 1928 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; |
1898 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " | 1929 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " |
1899 | "ratr_val:%x, %x:%x:%x:%x:%x\n", | 1930 | "ratr_val:%x, %x:%x:%x:%x:%x\n", |
@@ -1902,6 +1933,20 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
1902 | rate_mask[2], rate_mask[3], | 1933 | rate_mask[2], rate_mask[3], |
1903 | rate_mask[4])); | 1934 | rate_mask[4])); |
1904 | rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); | 1935 | rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); |
1936 | |||
1937 | if (macid != 0) | ||
1938 | sta_entry->ratr_index = ratr_index; | ||
1939 | } | ||
1940 | |||
1941 | void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw, | ||
1942 | struct ieee80211_sta *sta, u8 rssi_level) | ||
1943 | { | ||
1944 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1945 | |||
1946 | if (rtlpriv->dm.useramask) | ||
1947 | rtl92ce_update_hal_rate_mask(hw, sta, rssi_level); | ||
1948 | else | ||
1949 | rtl92ce_update_hal_rate_table(hw, sta); | ||
1905 | } | 1950 | } |
1906 | 1951 | ||
1907 | void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) | 1952 | void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) |
@@ -1919,7 +1964,7 @@ void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) | |||
1919 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); | 1964 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); |
1920 | } | 1965 | } |
1921 | 1966 | ||
1922 | bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) | 1967 | bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) |
1923 | { | 1968 | { |
1924 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1969 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1925 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 1970 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
@@ -1929,7 +1974,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) | |||
1929 | bool actuallyset = false; | 1974 | bool actuallyset = false; |
1930 | unsigned long flag; | 1975 | unsigned long flag; |
1931 | 1976 | ||
1932 | if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter)) | 1977 | if (rtlpci->being_init_adapter) |
1933 | return false; | 1978 | return false; |
1934 | 1979 | ||
1935 | if (ppsc->swrf_processing) | 1980 | if (ppsc->swrf_processing) |
@@ -1946,12 +1991,6 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) | |||
1946 | 1991 | ||
1947 | cur_rfstate = ppsc->rfpwr_state; | 1992 | cur_rfstate = ppsc->rfpwr_state; |
1948 | 1993 | ||
1949 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && | ||
1950 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { | ||
1951 | rtlpriv->intf_ops->disable_aspm(hw); | ||
1952 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); | ||
1953 | } | ||
1954 | |||
1955 | rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, | 1994 | rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, |
1956 | REG_MAC_PINMUX_CFG)&~(BIT(3))); | 1995 | REG_MAC_PINMUX_CFG)&~(BIT(3))); |
1957 | 1996 | ||
@@ -1976,38 +2015,13 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) | |||
1976 | } | 2015 | } |
1977 | 2016 | ||
1978 | if (actuallyset) { | 2017 | if (actuallyset) { |
1979 | if (e_rfpowerstate_toset == ERFON) { | ||
1980 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && | ||
1981 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { | ||
1982 | rtlpriv->intf_ops->disable_aspm(hw); | ||
1983 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); | ||
1984 | } | ||
1985 | } | ||
1986 | |||
1987 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | 2018 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); |
1988 | ppsc->rfchange_inprogress = false; | 2019 | ppsc->rfchange_inprogress = false; |
1989 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | 2020 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); |
1990 | 2021 | } else { | |
1991 | if (e_rfpowerstate_toset == ERFOFF) { | ||
1992 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { | ||
1993 | rtlpriv->intf_ops->enable_aspm(hw); | ||
1994 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); | ||
1995 | } | ||
1996 | } | ||
1997 | |||
1998 | } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { | ||
1999 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) | 2022 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) |
2000 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | 2023 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); |
2001 | 2024 | ||
2002 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { | ||
2003 | rtlpriv->intf_ops->enable_aspm(hw); | ||
2004 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); | ||
2005 | } | ||
2006 | |||
2007 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | ||
2008 | ppsc->rfchange_inprogress = false; | ||
2009 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2010 | } else { | ||
2011 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | 2025 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); |
2012 | ppsc->rfchange_inprogress = false; | 2026 | ppsc->rfchange_inprogress = false; |
2013 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | 2027 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); |
@@ -2086,15 +2100,31 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, | |||
2086 | macaddr = cam_const_broad; | 2100 | macaddr = cam_const_broad; |
2087 | entry_id = key_index; | 2101 | entry_id = key_index; |
2088 | } else { | 2102 | } else { |
2103 | if (mac->opmode == NL80211_IFTYPE_AP) { | ||
2104 | entry_id = rtl_cam_get_free_entry(hw, | ||
2105 | p_macaddr); | ||
2106 | if (entry_id >= TOTAL_CAM_ENTRY) { | ||
2107 | RT_TRACE(rtlpriv, COMP_SEC, | ||
2108 | DBG_EMERG, | ||
2109 | ("Can not find free hw" | ||
2110 | " security cam entry\n")); | ||
2111 | return; | ||
2112 | } | ||
2113 | } else { | ||
2114 | entry_id = CAM_PAIRWISE_KEY_POSITION; | ||
2115 | } | ||
2116 | |||
2089 | key_index = PAIRWISE_KEYIDX; | 2117 | key_index = PAIRWISE_KEYIDX; |
2090 | entry_id = CAM_PAIRWISE_KEY_POSITION; | ||
2091 | is_pairwise = true; | 2118 | is_pairwise = true; |
2092 | } | 2119 | } |
2093 | } | 2120 | } |
2094 | 2121 | ||
2095 | if (rtlpriv->sec.key_len[key_index] == 0) { | 2122 | if (rtlpriv->sec.key_len[key_index] == 0) { |
2096 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 2123 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, |
2097 | ("delete one entry\n")); | 2124 | ("delete one entry, entry_id is %d\n", |
2125 | entry_id)); | ||
2126 | if (mac->opmode == NL80211_IFTYPE_AP) | ||
2127 | rtl_cam_del_entry(hw, p_macaddr); | ||
2098 | rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); | 2128 | rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); |
2099 | } else { | 2129 | } else { |
2100 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, | 2130 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
@@ -2146,3 +2176,132 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, | |||
2146 | } | 2176 | } |
2147 | } | 2177 | } |
2148 | } | 2178 | } |
2179 | |||
2180 | static void rtl8192ce_bt_var_init(struct ieee80211_hw *hw) | ||
2181 | { | ||
2182 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
2183 | |||
2184 | rtlpcipriv->bt_coexist.bt_coexistence = | ||
2185 | rtlpcipriv->bt_coexist.eeprom_bt_coexist; | ||
2186 | rtlpcipriv->bt_coexist.bt_ant_num = | ||
2187 | rtlpcipriv->bt_coexist.eeprom_bt_ant_num; | ||
2188 | rtlpcipriv->bt_coexist.bt_coexist_type = | ||
2189 | rtlpcipriv->bt_coexist.eeprom_bt_type; | ||
2190 | |||
2191 | if (rtlpcipriv->bt_coexist.reg_bt_iso == 2) | ||
2192 | rtlpcipriv->bt_coexist.bt_ant_isolation = | ||
2193 | rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation; | ||
2194 | else | ||
2195 | rtlpcipriv->bt_coexist.bt_ant_isolation = | ||
2196 | rtlpcipriv->bt_coexist.reg_bt_iso; | ||
2197 | |||
2198 | rtlpcipriv->bt_coexist.bt_radio_shared_type = | ||
2199 | rtlpcipriv->bt_coexist.eeprom_bt_radio_shared; | ||
2200 | |||
2201 | if (rtlpcipriv->bt_coexist.bt_coexistence) { | ||
2202 | |||
2203 | if (rtlpcipriv->bt_coexist.reg_bt_sco == 1) | ||
2204 | rtlpcipriv->bt_coexist.bt_service = BT_OTHER_ACTION; | ||
2205 | else if (rtlpcipriv->bt_coexist.reg_bt_sco == 2) | ||
2206 | rtlpcipriv->bt_coexist.bt_service = BT_SCO; | ||
2207 | else if (rtlpcipriv->bt_coexist.reg_bt_sco == 4) | ||
2208 | rtlpcipriv->bt_coexist.bt_service = BT_BUSY; | ||
2209 | else if (rtlpcipriv->bt_coexist.reg_bt_sco == 5) | ||
2210 | rtlpcipriv->bt_coexist.bt_service = BT_OTHERBUSY; | ||
2211 | else | ||
2212 | rtlpcipriv->bt_coexist.bt_service = BT_IDLE; | ||
2213 | |||
2214 | rtlpcipriv->bt_coexist.bt_edca_ul = 0; | ||
2215 | rtlpcipriv->bt_coexist.bt_edca_dl = 0; | ||
2216 | rtlpcipriv->bt_coexist.bt_rssi_state = 0xff; | ||
2217 | } | ||
2218 | } | ||
2219 | |||
2220 | void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, | ||
2221 | bool auto_load_fail, u8 *hwinfo) | ||
2222 | { | ||
2223 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
2224 | u8 value; | ||
2225 | |||
2226 | if (!auto_load_fail) { | ||
2227 | rtlpcipriv->bt_coexist.eeprom_bt_coexist = | ||
2228 | ((hwinfo[RF_OPTION1] & 0xe0) >> 5); | ||
2229 | value = hwinfo[RF_OPTION4]; | ||
2230 | rtlpcipriv->bt_coexist.eeprom_bt_type = ((value & 0xe) >> 1); | ||
2231 | rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1); | ||
2232 | rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = | ||
2233 | ((value & 0x10) >> 4); | ||
2234 | rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = | ||
2235 | ((value & 0x20) >> 5); | ||
2236 | } else { | ||
2237 | rtlpcipriv->bt_coexist.eeprom_bt_coexist = 0; | ||
2238 | rtlpcipriv->bt_coexist.eeprom_bt_type = BT_2WIRE; | ||
2239 | rtlpcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2; | ||
2240 | rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = 0; | ||
2241 | rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; | ||
2242 | } | ||
2243 | |||
2244 | rtl8192ce_bt_var_init(hw); | ||
2245 | } | ||
2246 | |||
2247 | void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw) | ||
2248 | { | ||
2249 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
2250 | |||
2251 | /* 0:Low, 1:High, 2:From Efuse. */ | ||
2252 | rtlpcipriv->bt_coexist.reg_bt_iso = 2; | ||
2253 | /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ | ||
2254 | rtlpcipriv->bt_coexist.reg_bt_sco = 3; | ||
2255 | /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ | ||
2256 | rtlpcipriv->bt_coexist.reg_bt_sco = 0; | ||
2257 | } | ||
2258 | |||
2259 | |||
2260 | void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw) | ||
2261 | { | ||
2262 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2263 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2264 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
2265 | |||
2266 | u8 u1_tmp; | ||
2267 | |||
2268 | if (rtlpcipriv->bt_coexist.bt_coexistence && | ||
2269 | ((rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) || | ||
2270 | rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC8)) { | ||
2271 | |||
2272 | if (rtlpcipriv->bt_coexist.bt_ant_isolation) | ||
2273 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); | ||
2274 | |||
2275 | u1_tmp = rtl_read_byte(rtlpriv, 0x4fd) & | ||
2276 | BIT_OFFSET_LEN_MASK_32(0, 1); | ||
2277 | u1_tmp = u1_tmp | | ||
2278 | ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ? | ||
2279 | 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) | | ||
2280 | ((rtlpcipriv->bt_coexist.bt_service == BT_SCO) ? | ||
2281 | 0 : BIT_OFFSET_LEN_MASK_32(2, 1)); | ||
2282 | rtl_write_byte(rtlpriv, 0x4fd, u1_tmp); | ||
2283 | |||
2284 | rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+4, 0xaaaa9aaa); | ||
2285 | rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+8, 0xffbd0040); | ||
2286 | rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+0xc, 0x40000010); | ||
2287 | |||
2288 | /* Config to 1T1R. */ | ||
2289 | if (rtlphy->rf_type == RF_1T1R) { | ||
2290 | u1_tmp = rtl_read_byte(rtlpriv, ROFDM0_TRXPATHENABLE); | ||
2291 | u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1)); | ||
2292 | rtl_write_byte(rtlpriv, ROFDM0_TRXPATHENABLE, u1_tmp); | ||
2293 | |||
2294 | u1_tmp = rtl_read_byte(rtlpriv, ROFDM1_TRXPATHENABLE); | ||
2295 | u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1)); | ||
2296 | rtl_write_byte(rtlpriv, ROFDM1_TRXPATHENABLE, u1_tmp); | ||
2297 | } | ||
2298 | } | ||
2299 | } | ||
2300 | |||
2301 | void rtl92ce_suspend(struct ieee80211_hw *hw) | ||
2302 | { | ||
2303 | } | ||
2304 | |||
2305 | void rtl92ce_resume(struct ieee80211_hw *hw) | ||
2306 | { | ||
2307 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h index a3dfdb635168..07dbe3e340a5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h | |||
@@ -30,7 +30,18 @@ | |||
30 | #ifndef __RTL92CE_HW_H__ | 30 | #ifndef __RTL92CE_HW_H__ |
31 | #define __RTL92CE_HW_H__ | 31 | #define __RTL92CE_HW_H__ |
32 | 32 | ||
33 | #define H2C_RA_MASK 6 | 33 | static inline u8 _rtl92c_get_chnl_group(u8 chnl) |
34 | { | ||
35 | u8 group; | ||
36 | |||
37 | if (chnl < 3) | ||
38 | group = 0; | ||
39 | else if (chnl < 9) | ||
40 | group = 1; | ||
41 | else | ||
42 | group = 2; | ||
43 | return group; | ||
44 | } | ||
34 | 45 | ||
35 | void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | 46 | void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); |
36 | void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); | 47 | void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); |
@@ -41,28 +52,27 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw); | |||
41 | void rtl92ce_enable_interrupt(struct ieee80211_hw *hw); | 52 | void rtl92ce_enable_interrupt(struct ieee80211_hw *hw); |
42 | void rtl92ce_disable_interrupt(struct ieee80211_hw *hw); | 53 | void rtl92ce_disable_interrupt(struct ieee80211_hw *hw); |
43 | int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); | 54 | int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); |
55 | void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); | ||
44 | void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci); | 56 | void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci); |
45 | void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw); | 57 | void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw); |
46 | void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw); | 58 | void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw); |
47 | void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, | 59 | void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, |
48 | u32 add_msr, u32 rm_msr); | 60 | u32 add_msr, u32 rm_msr); |
49 | void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | 61 | void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); |
50 | void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw); | 62 | void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw, |
51 | void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); | 63 | struct ieee80211_sta *sta, u8 rssi_level); |
52 | void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw); | 64 | void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw); |
53 | bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); | 65 | bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); |
54 | void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw); | 66 | void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw); |
55 | void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, | 67 | void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, |
56 | u8 *p_macaddr, bool is_group, u8 enc_algo, | 68 | u8 *p_macaddr, bool is_group, u8 enc_algo, |
57 | bool is_wepkey, bool clear_all); | 69 | bool is_wepkey, bool clear_all); |
58 | bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); | 70 | |
59 | void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); | 71 | void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, |
60 | void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); | 72 | bool autoload_fail, u8 *hwinfo); |
61 | void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); | 73 | void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw); |
62 | int rtl92c_download_fw(struct ieee80211_hw *hw); | 74 | void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw); |
63 | void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); | 75 | void rtl92ce_suspend(struct ieee80211_hw *hw); |
64 | void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, | 76 | void rtl92ce_resume(struct ieee80211_hw *hw); |
65 | u8 element_id, u32 cmd_len, u8 *p_cmdbuffer); | ||
66 | bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw); | ||
67 | 77 | ||
68 | #endif | 78 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index d21b934b5c33..9dd1ed7b6422 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c | |||
@@ -106,12 +106,11 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | |||
106 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) | 106 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) |
107 | { | 107 | { |
108 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | 108 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); |
109 | |||
110 | _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); | 109 | _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); |
111 | _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); | 110 | _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); |
112 | } | 111 | } |
113 | 112 | ||
114 | void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, | 113 | static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, |
115 | enum led_ctl_mode ledaction) | 114 | enum led_ctl_mode ledaction) |
116 | { | 115 | { |
117 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | 116 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); |
@@ -146,7 +145,7 @@ void rtl92ce_led_control(struct ieee80211_hw *hw, | |||
146 | ledaction == LED_CTL_POWER_ON)) { | 145 | ledaction == LED_CTL_POWER_ON)) { |
147 | return; | 146 | return; |
148 | } | 147 | } |
149 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", | 148 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d.\n", |
150 | ledaction)); | 149 | ledaction)); |
151 | _rtl92ce_sw_led_control(hw, ledaction); | 150 | _rtl92ce_sw_led_control(hw, ledaction); |
152 | } | 151 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h index 94332b3af5b1..7dfccea2095b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h | |||
@@ -34,7 +34,5 @@ void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); | |||
34 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); | 34 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); |
35 | void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); | 35 | void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); |
36 | void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); | 36 | void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); |
37 | void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, | ||
38 | enum led_ctl_mode ledaction); | ||
39 | 37 | ||
40 | #endif | 38 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index d0541e8c6012..73ae8a431848 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | |||
@@ -38,7 +38,9 @@ | |||
38 | #include "dm.h" | 38 | #include "dm.h" |
39 | #include "table.h" | 39 | #include "table.h" |
40 | 40 | ||
41 | u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw, | 41 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); |
42 | |||
43 | u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, | ||
42 | enum radio_path rfpath, u32 regaddr, u32 bitmask) | 44 | enum radio_path rfpath, u32 regaddr, u32 bitmask) |
43 | { | 45 | { |
44 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 46 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -73,9 +75,47 @@ u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw, | |||
73 | return readback_value; | 75 | return readback_value; |
74 | } | 76 | } |
75 | 77 | ||
78 | bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) | ||
79 | { | ||
80 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
81 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
82 | bool is92c = IS_92C_SERIAL(rtlhal->version); | ||
83 | bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); | ||
84 | |||
85 | if (is92c) | ||
86 | rtl_write_byte(rtlpriv, 0x14, 0x71); | ||
87 | return rtstatus; | ||
88 | } | ||
89 | |||
90 | bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) | ||
91 | { | ||
92 | bool rtstatus = true; | ||
93 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
94 | u16 regval; | ||
95 | u32 regvaldw; | ||
96 | u8 reg_hwparafile = 1; | ||
97 | |||
98 | _rtl92c_phy_init_bb_rf_register_definition(hw); | ||
99 | regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); | ||
100 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, | ||
101 | regval | BIT(13) | BIT(0) | BIT(1)); | ||
102 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); | ||
103 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); | ||
104 | rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); | ||
105 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, | ||
106 | FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | | ||
107 | FEN_BB_GLB_RSTn | FEN_BBRSTB); | ||
108 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); | ||
109 | regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); | ||
110 | rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); | ||
111 | if (reg_hwparafile == 1) | ||
112 | rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); | ||
113 | return rtstatus; | ||
114 | } | ||
115 | |||
76 | void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, | 116 | void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, |
77 | enum radio_path rfpath, | 117 | enum radio_path rfpath, |
78 | u32 regaddr, u32 bitmask, u32 data) | 118 | u32 regaddr, u32 bitmask, u32 data) |
79 | { | 119 | { |
80 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 120 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
81 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 121 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -121,45 +161,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, | |||
121 | bitmask, data, rfpath)); | 161 | bitmask, data, rfpath)); |
122 | } | 162 | } |
123 | 163 | ||
124 | bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw) | 164 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) |
125 | { | ||
126 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
127 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
128 | bool is92c = IS_92C_SERIAL(rtlhal->version); | ||
129 | bool rtstatus = _rtl92ce_phy_config_mac_with_headerfile(hw); | ||
130 | |||
131 | if (is92c) | ||
132 | rtl_write_byte(rtlpriv, 0x14, 0x71); | ||
133 | return rtstatus; | ||
134 | } | ||
135 | |||
136 | bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw) | ||
137 | { | ||
138 | bool rtstatus = true; | ||
139 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
140 | u16 regval; | ||
141 | u32 regvaldw; | ||
142 | u8 reg_hwparafile = 1; | ||
143 | |||
144 | _rtl92c_phy_init_bb_rf_register_definition(hw); | ||
145 | regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); | ||
146 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, | ||
147 | regval | BIT(13) | BIT(0) | BIT(1)); | ||
148 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); | ||
149 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); | ||
150 | rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); | ||
151 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, | ||
152 | FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | | ||
153 | FEN_BB_GLB_RSTn | FEN_BBRSTB); | ||
154 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); | ||
155 | regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); | ||
156 | rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); | ||
157 | if (reg_hwparafile == 1) | ||
158 | rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); | ||
159 | return rtstatus; | ||
160 | } | ||
161 | |||
162 | bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) | ||
163 | { | 165 | { |
164 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 166 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
165 | u32 i; | 167 | u32 i; |
@@ -177,7 +179,7 @@ bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) | |||
177 | } | 179 | } |
178 | 180 | ||
179 | bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | 181 | bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, |
180 | u8 configtype) | 182 | u8 configtype) |
181 | { | 183 | { |
182 | int i; | 184 | int i; |
183 | u32 *phy_regarray_table; | 185 | u32 *phy_regarray_table; |
@@ -236,7 +238,7 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | |||
236 | } | 238 | } |
237 | 239 | ||
238 | bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | 240 | bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, |
239 | u8 configtype) | 241 | u8 configtype) |
240 | { | 242 | { |
241 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 243 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
242 | int i; | 244 | int i; |
@@ -274,7 +276,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | |||
274 | return true; | 276 | return true; |
275 | } | 277 | } |
276 | 278 | ||
277 | bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | 279 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, |
278 | enum radio_path rfpath) | 280 | enum radio_path rfpath) |
279 | { | 281 | { |
280 | 282 | ||
@@ -364,74 +366,6 @@ bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | |||
364 | return true; | 366 | return true; |
365 | } | 367 | } |
366 | 368 | ||
367 | void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) | ||
368 | { | ||
369 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
370 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
371 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
372 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
373 | u8 reg_bw_opmode; | ||
374 | u8 reg_prsr_rsc; | ||
375 | |||
376 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
377 | ("Switch to %s bandwidth\n", | ||
378 | rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? | ||
379 | "20MHz" : "40MHz")) | ||
380 | |||
381 | if (is_hal_stop(rtlhal)) | ||
382 | return; | ||
383 | |||
384 | reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); | ||
385 | reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); | ||
386 | |||
387 | switch (rtlphy->current_chan_bw) { | ||
388 | case HT_CHANNEL_WIDTH_20: | ||
389 | reg_bw_opmode |= BW_OPMODE_20MHZ; | ||
390 | rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); | ||
391 | break; | ||
392 | |||
393 | case HT_CHANNEL_WIDTH_20_40: | ||
394 | reg_bw_opmode &= ~BW_OPMODE_20MHZ; | ||
395 | rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); | ||
396 | |||
397 | reg_prsr_rsc = | ||
398 | (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); | ||
399 | rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); | ||
400 | break; | ||
401 | |||
402 | default: | ||
403 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
404 | ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); | ||
405 | break; | ||
406 | } | ||
407 | |||
408 | switch (rtlphy->current_chan_bw) { | ||
409 | case HT_CHANNEL_WIDTH_20: | ||
410 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); | ||
411 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); | ||
412 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); | ||
413 | break; | ||
414 | case HT_CHANNEL_WIDTH_20_40: | ||
415 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); | ||
416 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); | ||
417 | rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, | ||
418 | (mac->cur_40_prime_sc >> 1)); | ||
419 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); | ||
420 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); | ||
421 | rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), | ||
422 | (mac->cur_40_prime_sc == | ||
423 | HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); | ||
424 | break; | ||
425 | default: | ||
426 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
427 | ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); | ||
428 | break; | ||
429 | } | ||
430 | rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); | ||
431 | rtlphy->set_bwmode_inprogress = false; | ||
432 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | ||
433 | } | ||
434 | |||
435 | void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | 369 | void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) |
436 | { | 370 | { |
437 | u8 tmpreg; | 371 | u8 tmpreg; |
@@ -477,6 +411,36 @@ void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | |||
477 | } | 411 | } |
478 | } | 412 | } |
479 | 413 | ||
414 | static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) | ||
415 | { | ||
416 | u32 u4b_tmp; | ||
417 | u8 delay = 5; | ||
418 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
419 | |||
420 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | ||
421 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
422 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
423 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
424 | while (u4b_tmp != 0 && delay > 0) { | ||
425 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); | ||
426 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
427 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
428 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
429 | delay--; | ||
430 | } | ||
431 | if (delay == 0) { | ||
432 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
433 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
434 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
435 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
436 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
437 | ("Switch RF timeout !!!.\n")); | ||
438 | return; | ||
439 | } | ||
440 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
441 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); | ||
442 | } | ||
443 | |||
480 | static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | 444 | static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, |
481 | enum rf_pwrstate rfpwr_state) | 445 | enum rf_pwrstate rfpwr_state) |
482 | { | 446 | { |
@@ -523,33 +487,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
523 | break; | 487 | break; |
524 | } | 488 | } |
525 | case ERFOFF:{ | 489 | case ERFOFF:{ |
526 | for (queue_id = 0, i = 0; | ||
527 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | ||
528 | ring = &pcipriv->dev.tx_ring[queue_id]; | ||
529 | if (skb_queue_len(&ring->queue) == 0 || | ||
530 | queue_id == BEACON_QUEUE) { | ||
531 | queue_id++; | ||
532 | continue; | ||
533 | } else { | ||
534 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
535 | ("eRf Off/Sleep: %d times " | ||
536 | "TcbBusyQueue[%d] " | ||
537 | "=%d before doze!\n", (i + 1), | ||
538 | queue_id, | ||
539 | skb_queue_len(&ring->queue))); | ||
540 | udelay(10); | ||
541 | i++; | ||
542 | } | ||
543 | if (i >= MAX_DOZE_WAITING_TIMES_9x) { | ||
544 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
545 | ("\nERFOFF: %d times " | ||
546 | "TcbBusyQueue[%d] = %d !\n", | ||
547 | MAX_DOZE_WAITING_TIMES_9x, | ||
548 | queue_id, | ||
549 | skb_queue_len(&ring->queue))); | ||
550 | break; | ||
551 | } | ||
552 | } | ||
553 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { | 490 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { |
554 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | 491 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, |
555 | ("IPS Set eRf nic disable\n")); | 492 | ("IPS Set eRf nic disable\n")); |
@@ -581,6 +518,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
581 | "TcbBusyQueue[%d] =%d before " | 518 | "TcbBusyQueue[%d] =%d before " |
582 | "doze!\n", (i + 1), queue_id, | 519 | "doze!\n", (i + 1), queue_id, |
583 | skb_queue_len(&ring->queue))); | 520 | skb_queue_len(&ring->queue))); |
521 | |||
584 | udelay(10); | 522 | udelay(10); |
585 | i++; | 523 | i++; |
586 | } | 524 | } |
@@ -599,7 +537,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
599 | jiffies_to_msecs(jiffies - | 537 | jiffies_to_msecs(jiffies - |
600 | ppsc->last_awake_jiffies))); | 538 | ppsc->last_awake_jiffies))); |
601 | ppsc->last_sleep_jiffies = jiffies; | 539 | ppsc->last_sleep_jiffies = jiffies; |
602 | _rtl92c_phy_set_rf_sleep(hw); | 540 | _rtl92ce_phy_set_rf_sleep(hw); |
603 | break; | 541 | break; |
604 | } | 542 | } |
605 | default: | 543 | default: |
@@ -614,10 +552,11 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
614 | return bresult; | 552 | return bresult; |
615 | } | 553 | } |
616 | 554 | ||
617 | bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | 555 | bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, |
618 | enum rf_pwrstate rfpwr_state) | 556 | enum rf_pwrstate rfpwr_state) |
619 | { | 557 | { |
620 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 558 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
559 | |||
621 | bool bresult = false; | 560 | bool bresult = false; |
622 | 561 | ||
623 | if (rfpwr_state == ppsc->rfpwr_state) | 562 | if (rfpwr_state == ppsc->rfpwr_state) |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index a37267e3fc22..ad580852cc76 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define RT_CANNOT_IO(hw) false | 39 | #define RT_CANNOT_IO(hw) false |
40 | #define HIGHPOWER_RADIOA_ARRAYLEN 22 | 40 | #define HIGHPOWER_RADIOA_ARRAYLEN 22 |
41 | 41 | ||
42 | #define IQK_ADDA_REG_NUM 16 | ||
42 | #define MAX_TOLERANCE 5 | 43 | #define MAX_TOLERANCE 5 |
43 | #define IQK_DELAY_TIME 1 | 44 | #define IQK_DELAY_TIME 1 |
44 | 45 | ||
@@ -56,6 +57,8 @@ | |||
56 | #define IQK_ADDA_REG_NUM 16 | 57 | #define IQK_ADDA_REG_NUM 16 |
57 | #define IQK_MAC_REG_NUM 4 | 58 | #define IQK_MAC_REG_NUM 4 |
58 | 59 | ||
60 | #define IQK_DELAY_TIME 1 | ||
61 | |||
59 | #define RF90_PATH_MAX 2 | 62 | #define RF90_PATH_MAX 2 |
60 | 63 | ||
61 | #define CT_OFFSET_MAC_ADDR 0X16 | 64 | #define CT_OFFSET_MAC_ADDR 0X16 |
@@ -76,7 +79,7 @@ | |||
76 | #define CT_OFFSET_CUSTOMER_ID 0x7F | 79 | #define CT_OFFSET_CUSTOMER_ID 0x7F |
77 | 80 | ||
78 | #define RTL92C_MAX_PATH_NUM 2 | 81 | #define RTL92C_MAX_PATH_NUM 2 |
79 | #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 | 82 | |
80 | enum swchnlcmd_id { | 83 | enum swchnlcmd_id { |
81 | CMDID_END, | 84 | CMDID_END, |
82 | CMDID_SET_TXPOWEROWER_LEVEL, | 85 | CMDID_SET_TXPOWEROWER_LEVEL, |
@@ -184,43 +187,44 @@ struct tx_power_struct { | |||
184 | u32 mcs_original_offset[4][16]; | 187 | u32 mcs_original_offset[4][16]; |
185 | }; | 188 | }; |
186 | 189 | ||
187 | extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, | 190 | bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); |
191 | u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, | ||
188 | u32 regaddr, u32 bitmask); | 192 | u32 regaddr, u32 bitmask); |
189 | extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, | 193 | void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, |
190 | u32 regaddr, u32 bitmask, u32 data); | 194 | u32 regaddr, u32 bitmask, u32 data); |
191 | extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, | 195 | u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, |
192 | enum radio_path rfpath, u32 regaddr, | 196 | enum radio_path rfpath, u32 regaddr, |
193 | u32 bitmask); | 197 | u32 bitmask); |
194 | extern void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, | 198 | extern void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, |
195 | enum radio_path rfpath, u32 regaddr, | 199 | enum radio_path rfpath, u32 regaddr, |
196 | u32 bitmask, u32 data); | 200 | u32 bitmask, u32 data); |
197 | extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); | 201 | bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); |
198 | bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw); | 202 | bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw); |
199 | extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); | 203 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); |
200 | extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, | 204 | bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, |
201 | enum radio_path rfpath); | 205 | enum radio_path rfpath); |
202 | extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); | 206 | void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); |
203 | extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, | 207 | void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, |
204 | long *powerlevel); | 208 | long *powerlevel); |
205 | extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); | 209 | void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); |
206 | extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, | 210 | bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, |
207 | long power_indbm); | 211 | long power_indbm); |
208 | extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, | 212 | void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, |
209 | u8 operation); | 213 | u8 operation); |
210 | extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw); | 214 | void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, |
211 | extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
212 | enum nl80211_channel_type ch_type); | 215 | enum nl80211_channel_type ch_type); |
213 | extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); | 216 | void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); |
214 | extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); | 217 | u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); |
215 | extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); | 218 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); |
216 | extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, | 219 | void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, |
217 | u16 beaconinterval); | 220 | u16 beaconinterval); |
218 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); | 221 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); |
219 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); | 222 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); |
223 | void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); | ||
220 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); | 224 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); |
221 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | 225 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, |
222 | enum radio_path rfpath); | 226 | enum radio_path rfpath); |
223 | extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, | 227 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, |
224 | u32 rfpath); | 228 | u32 rfpath); |
225 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); | 229 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); |
226 | bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | 230 | bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, |
@@ -237,9 +241,6 @@ u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); | |||
237 | void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | 241 | void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, |
238 | enum radio_path rfpath, u32 offset, | 242 | enum radio_path rfpath, u32 offset, |
239 | u32 data); | 243 | u32 data); |
240 | void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, | ||
241 | u32 regaddr, u32 bitmask, | ||
242 | u32 data); | ||
243 | void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | 244 | void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, |
244 | enum radio_path rfpath, u32 offset, | 245 | enum radio_path rfpath, u32 offset, |
245 | u32 data); | 246 | u32 data); |
@@ -250,5 +251,11 @@ bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); | |||
250 | void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); | 251 | void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); |
251 | bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); | 252 | bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); |
252 | void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw); | 253 | void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw); |
254 | bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
255 | enum rf_pwrstate rfpwr_state); | ||
256 | bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | ||
257 | u8 configtype); | ||
258 | bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | ||
259 | u8 configtype); | ||
253 | 260 | ||
254 | #endif | 261 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index b0868a613841..598cecc63f41 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | |||
@@ -72,6 +72,7 @@ | |||
72 | #define REG_GPIO_IO_SEL_2 0x0062 | 72 | #define REG_GPIO_IO_SEL_2 0x0062 |
73 | /* RTL8723 WIFI/BT/GPS Multi-Function control source. */ | 73 | /* RTL8723 WIFI/BT/GPS Multi-Function control source. */ |
74 | #define REG_MULTI_FUNC_CTRL 0x0068 | 74 | #define REG_MULTI_FUNC_CTRL 0x0068 |
75 | |||
75 | #define REG_MCUFWDL 0x0080 | 76 | #define REG_MCUFWDL 0x0080 |
76 | 77 | ||
77 | #define REG_HMEBOX_EXT_0 0x0088 | 78 | #define REG_HMEBOX_EXT_0 0x0088 |
@@ -542,7 +543,7 @@ | |||
542 | #define IMR_OCPINT BIT(1) | 543 | #define IMR_OCPINT BIT(1) |
543 | #define IMR_WLANOFF BIT(0) | 544 | #define IMR_WLANOFF BIT(0) |
544 | 545 | ||
545 | #define HWSET_MAX_SIZE 128 | 546 | #define EFUSE_REAL_CONTENT_LEN 512 |
546 | 547 | ||
547 | #define EEPROM_DEFAULT_TSSI 0x0 | 548 | #define EEPROM_DEFAULT_TSSI 0x0 |
548 | #define EEPROM_DEFAULT_TXPOWERDIFF 0x0 | 549 | #define EEPROM_DEFAULT_TXPOWERDIFF 0x0 |
@@ -656,6 +657,7 @@ | |||
656 | #define STOPBE BIT(1) | 657 | #define STOPBE BIT(1) |
657 | #define STOPBK BIT(0) | 658 | #define STOPBK BIT(0) |
658 | 659 | ||
660 | #define RCR_APPFCS BIT(31) | ||
659 | #define RCR_APP_FCS BIT(31) | 661 | #define RCR_APP_FCS BIT(31) |
660 | #define RCR_APP_MIC BIT(30) | 662 | #define RCR_APP_MIC BIT(30) |
661 | #define RCR_APP_ICV BIT(29) | 663 | #define RCR_APP_ICV BIT(29) |
@@ -688,6 +690,7 @@ | |||
688 | 690 | ||
689 | #define REG_USB_INFO 0xFE17 | 691 | #define REG_USB_INFO 0xFE17 |
690 | #define REG_USB_SPECIAL_OPTION 0xFE55 | 692 | #define REG_USB_SPECIAL_OPTION 0xFE55 |
693 | |||
691 | #define REG_USB_DMA_AGG_TO 0xFE5B | 694 | #define REG_USB_DMA_AGG_TO 0xFE5B |
692 | #define REG_USB_AGG_TO 0xFE5C | 695 | #define REG_USB_AGG_TO 0xFE5C |
693 | #define REG_USB_AGG_TH 0xFE5D | 696 | #define REG_USB_AGG_TH 0xFE5D |
@@ -775,7 +778,6 @@ | |||
775 | 778 | ||
776 | #define BOOT_FROM_EEPROM BIT(4) | 779 | #define BOOT_FROM_EEPROM BIT(4) |
777 | #define EEPROM_EN BIT(5) | 780 | #define EEPROM_EN BIT(5) |
778 | #define EEPROMSEL BOOT_FROM_EEPROM | ||
779 | 781 | ||
780 | #define AFE_BGEN BIT(0) | 782 | #define AFE_BGEN BIT(0) |
781 | #define AFE_MBEN BIT(1) | 783 | #define AFE_MBEN BIT(1) |
@@ -901,28 +903,7 @@ | |||
901 | #define BD_PKG_SEL BIT(25) | 903 | #define BD_PKG_SEL BIT(25) |
902 | #define BD_HCI_SEL BIT(26) | 904 | #define BD_HCI_SEL BIT(26) |
903 | #define TYPE_ID BIT(27) | 905 | #define TYPE_ID BIT(27) |
904 | 906 | #define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28)) | |
905 | /* REG_GPIO_OUTSTS (For RTL8723 only) */ | ||
906 | #define EFS_HCI_SEL (BIT(0)|BIT(1)) | ||
907 | #define PAD_HCI_SEL (BIT(2)|BIT(3)) | ||
908 | #define HCI_SEL (BIT(4)|BIT(5)) | ||
909 | #define PKG_SEL_HCI BIT(6) | ||
910 | #define FEN_GPS BIT(7) | ||
911 | #define FEN_BT BIT(8) | ||
912 | #define FEN_WL BIT(9) | ||
913 | #define FEN_PCI BIT(10) | ||
914 | #define FEN_USB BIT(11) | ||
915 | #define BTRF_HWPDN_N BIT(12) | ||
916 | #define WLRF_HWPDN_N BIT(13) | ||
917 | #define PDN_BT_N BIT(14) | ||
918 | #define PDN_GPS_N BIT(15) | ||
919 | #define BT_CTL_HWPDN BIT(16) | ||
920 | #define GPS_CTL_HWPDN BIT(17) | ||
921 | #define PPHY_SUSB BIT(20) | ||
922 | #define UPHY_SUSB BIT(21) | ||
923 | #define PCI_SUSEN BIT(22) | ||
924 | #define USB_SUSEN BIT(23) | ||
925 | #define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28)) | ||
926 | 907 | ||
927 | #define CHIP_VER_RTL_MASK 0xF000 | 908 | #define CHIP_VER_RTL_MASK 0xF000 |
928 | #define CHIP_VER_RTL_SHIFT 12 | 909 | #define CHIP_VER_RTL_SHIFT 12 |
@@ -1077,6 +1058,7 @@ | |||
1077 | #define _RARF_RC8(x) (((x) & 0x1F) << 24) | 1058 | #define _RARF_RC8(x) (((x) & 0x1F) << 24) |
1078 | 1059 | ||
1079 | #define AC_PARAM_TXOP_OFFSET 16 | 1060 | #define AC_PARAM_TXOP_OFFSET 16 |
1061 | #define AC_PARAM_TXOP_LIMIT_OFFSET 16 | ||
1080 | #define AC_PARAM_ECW_MAX_OFFSET 12 | 1062 | #define AC_PARAM_ECW_MAX_OFFSET 12 |
1081 | #define AC_PARAM_ECW_MIN_OFFSET 8 | 1063 | #define AC_PARAM_ECW_MIN_OFFSET 8 |
1082 | #define AC_PARAM_AIFS_OFFSET 0 | 1064 | #define AC_PARAM_AIFS_OFFSET 0 |
@@ -1221,33 +1203,11 @@ | |||
1221 | #define EPROM_CMD_CONFIG 0x3 | 1203 | #define EPROM_CMD_CONFIG 0x3 |
1222 | #define EPROM_CMD_LOAD 1 | 1204 | #define EPROM_CMD_LOAD 1 |
1223 | 1205 | ||
1224 | #define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE | 1206 | #define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE |
1225 | 1207 | ||
1226 | #define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) | ||
1227 | |||
1228 | /* REG_MULTI_FUNC_CTRL(For RTL8723 Only) */ | ||
1229 | /* Enable GPIO[9] as WiFi HW PDn source */ | ||
1230 | #define WL_HWPDN_EN BIT(0) | 1208 | #define WL_HWPDN_EN BIT(0) |
1231 | /* WiFi HW PDn polarity control */ | 1209 | |
1232 | #define WL_HWPDN_SL BIT(1) | 1210 | #define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) |
1233 | /* WiFi function enable */ | ||
1234 | #define WL_FUNC_EN BIT(2) | ||
1235 | /* Enable GPIO[9] as WiFi RF HW PDn source */ | ||
1236 | #define WL_HWROF_EN BIT(3) | ||
1237 | /* Enable GPIO[11] as BT HW PDn source */ | ||
1238 | #define BT_HWPDN_EN BIT(16) | ||
1239 | /* BT HW PDn polarity control */ | ||
1240 | #define BT_HWPDN_SL BIT(17) | ||
1241 | /* BT function enable */ | ||
1242 | #define BT_FUNC_EN BIT(18) | ||
1243 | /* Enable GPIO[11] as BT/GPS RF HW PDn source */ | ||
1244 | #define BT_HWROF_EN BIT(19) | ||
1245 | /* Enable GPIO[10] as GPS HW PDn source */ | ||
1246 | #define GPS_HWPDN_EN BIT(20) | ||
1247 | /* GPS HW PDn polarity control */ | ||
1248 | #define GPS_HWPDN_SL BIT(21) | ||
1249 | /* GPS function enable */ | ||
1250 | #define GPS_FUNC_EN BIT(22) | ||
1251 | 1211 | ||
1252 | #define RPMAC_RESET 0x100 | 1212 | #define RPMAC_RESET 0x100 |
1253 | #define RPMAC_TXSTART 0x104 | 1213 | #define RPMAC_TXSTART 0x104 |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index e301b12e281a..90d0f2cf3b27 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | |||
@@ -34,9 +34,9 @@ | |||
34 | #include "rf.h" | 34 | #include "rf.h" |
35 | #include "dm.h" | 35 | #include "dm.h" |
36 | 36 | ||
37 | static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); | 37 | static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw); |
38 | 38 | ||
39 | void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) | 39 | void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) |
40 | { | 40 | { |
41 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 41 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
42 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 42 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -62,7 +62,7 @@ void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) | |||
62 | } | 62 | } |
63 | 63 | ||
64 | void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | 64 | void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, |
65 | u8 *ppowerlevel) | 65 | u8 *ppowerlevel) |
66 | { | 66 | { |
67 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 67 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
68 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 68 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -128,8 +128,7 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | |||
128 | 128 | ||
129 | tmpval = tx_agc[RF90_PATH_A] >> 8; | 129 | tmpval = tx_agc[RF90_PATH_A] >> 8; |
130 | 130 | ||
131 | if (mac->mode == WIRELESS_MODE_B) | 131 | tmpval = tmpval & 0xff00ffff; |
132 | tmpval = tmpval & 0xff00ffff; | ||
133 | 132 | ||
134 | rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); | 133 | rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); |
135 | 134 | ||
@@ -440,16 +439,17 @@ bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw) | |||
440 | else | 439 | else |
441 | rtlphy->num_total_rfpath = 2; | 440 | rtlphy->num_total_rfpath = 2; |
442 | 441 | ||
443 | return _rtl92c_phy_rf6052_config_parafile(hw); | 442 | return _rtl92ce_phy_rf6052_config_parafile(hw); |
443 | |||
444 | } | 444 | } |
445 | 445 | ||
446 | static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) | 446 | static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw) |
447 | { | 447 | { |
448 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 448 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
449 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 449 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
450 | u32 u4_regvalue = 0; | 450 | u32 u4_regvalue = 0; |
451 | u8 rfpath; | 451 | u8 rfpath; |
452 | bool rtstatus; | 452 | bool rtstatus = true; |
453 | struct bb_reg_def *pphyreg; | 453 | struct bb_reg_def *pphyreg; |
454 | 454 | ||
455 | for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { | 455 | for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { |
@@ -484,12 +484,12 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) | |||
484 | 484 | ||
485 | switch (rfpath) { | 485 | switch (rfpath) { |
486 | case RF90_PATH_A: | 486 | case RF90_PATH_A: |
487 | rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw, | 487 | rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, |
488 | (enum radio_path) rfpath); | 488 | (enum radio_path)rfpath); |
489 | break; | 489 | break; |
490 | case RF90_PATH_B: | 490 | case RF90_PATH_B: |
491 | rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw, | 491 | rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, |
492 | (enum radio_path) rfpath); | 492 | (enum radio_path)rfpath); |
493 | break; | 493 | break; |
494 | case RF90_PATH_C: | 494 | case RF90_PATH_C: |
495 | break; | 495 | break; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h index 3aa520c1c171..39ff03685986 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h | |||
@@ -34,14 +34,11 @@ | |||
34 | #define RF6052_MAX_REG 0x3F | 34 | #define RF6052_MAX_REG 0x3F |
35 | #define RF6052_MAX_PATH 2 | 35 | #define RF6052_MAX_PATH 2 |
36 | 36 | ||
37 | extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | 37 | extern void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, |
38 | u8 bandwidth); | 38 | u8 bandwidth); |
39 | extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | 39 | extern void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, |
40 | u8 *ppowerlevel); | 40 | u8 *ppowerlevel); |
41 | extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | 41 | extern void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, |
42 | u8 *ppowerlevel, u8 channel); | 42 | u8 *ppowerlevel, u8 channel); |
43 | bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); | 43 | extern bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); |
44 | bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | ||
45 | enum radio_path rfpath); | ||
46 | |||
47 | #endif | 44 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index f4e2f3dcccae..390bbb5ee11d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | |||
@@ -42,10 +42,58 @@ | |||
42 | #include "trx.h" | 42 | #include "trx.h" |
43 | #include "led.h" | 43 | #include "led.h" |
44 | 44 | ||
45 | static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw) | ||
46 | { | ||
47 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
48 | |||
49 | /*close ASPM for AMD defaultly */ | ||
50 | rtlpci->const_amdpci_aspm = 0; | ||
51 | |||
52 | /* | ||
53 | * ASPM PS mode. | ||
54 | * 0 - Disable ASPM, | ||
55 | * 1 - Enable ASPM without Clock Req, | ||
56 | * 2 - Enable ASPM with Clock Req, | ||
57 | * 3 - Alwyas Enable ASPM with Clock Req, | ||
58 | * 4 - Always Enable ASPM without Clock Req. | ||
59 | * set defult to RTL8192CE:3 RTL8192E:2 | ||
60 | * */ | ||
61 | rtlpci->const_pci_aspm = 3; | ||
62 | |||
63 | /*Setting for PCI-E device */ | ||
64 | rtlpci->const_devicepci_aspm_setting = 0x03; | ||
65 | |||
66 | /*Setting for PCI-E bridge */ | ||
67 | rtlpci->const_hostpci_aspm_setting = 0x02; | ||
68 | |||
69 | /* | ||
70 | * In Hw/Sw Radio Off situation. | ||
71 | * 0 - Default, | ||
72 | * 1 - From ASPM setting without low Mac Pwr, | ||
73 | * 2 - From ASPM setting with low Mac Pwr, | ||
74 | * 3 - Bus D3 | ||
75 | * set default to RTL8192CE:0 RTL8192SE:2 | ||
76 | */ | ||
77 | rtlpci->const_hwsw_rfoff_d3 = 0; | ||
78 | |||
79 | /* | ||
80 | * This setting works for those device with | ||
81 | * backdoor ASPM setting such as EPHY setting. | ||
82 | * 0 - Not support ASPM, | ||
83 | * 1 - Support ASPM, | ||
84 | * 2 - According to chipset. | ||
85 | */ | ||
86 | rtlpci->const_support_pciaspm = 1; | ||
87 | } | ||
88 | |||
45 | int rtl92c_init_sw_vars(struct ieee80211_hw *hw) | 89 | int rtl92c_init_sw_vars(struct ieee80211_hw *hw) |
46 | { | 90 | { |
91 | int err; | ||
47 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 92 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
48 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 93 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
94 | const struct firmware *firmware; | ||
95 | |||
96 | rtl8192ce_bt_reg_init(hw); | ||
49 | 97 | ||
50 | rtlpriv->dm.dm_initialgain_enable = 1; | 98 | rtlpriv->dm.dm_initialgain_enable = 1; |
51 | rtlpriv->dm.dm_flag = 0; | 99 | rtlpriv->dm.dm_flag = 0; |
@@ -53,7 +101,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) | |||
53 | rtlpriv->dm.thermalvalue = 0; | 101 | rtlpriv->dm.thermalvalue = 0; |
54 | rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); | 102 | rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); |
55 | 103 | ||
56 | rtlpci->receive_config = (RCR_APP_FCS | | 104 | /* compatible 5G band 88ce just 2.4G band & smsp */ |
105 | rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; | ||
106 | rtlpriv->rtlhal.bandset = BAND_ON_2_4G; | ||
107 | rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; | ||
108 | |||
109 | rtlpci->receive_config = (RCR_APPFCS | | ||
57 | RCR_AMF | | 110 | RCR_AMF | |
58 | RCR_ADF | | 111 | RCR_ADF | |
59 | RCR_APP_MIC | | 112 | RCR_APP_MIC | |
@@ -76,13 +129,49 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) | |||
76 | 129 | ||
77 | rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0); | 130 | rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0); |
78 | 131 | ||
79 | rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000); | 132 | /* for LPS & IPS */ |
133 | rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; | ||
134 | rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; | ||
135 | rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; | ||
136 | rtlpriv->psc.reg_fwctrl_lps = 3; | ||
137 | rtlpriv->psc.reg_max_lps_awakeintvl = 5; | ||
138 | /* for ASPM, you can close aspm through | ||
139 | * set const_support_pciaspm = 0 */ | ||
140 | rtl92c_init_aspm_vars(hw); | ||
141 | |||
142 | if (rtlpriv->psc.reg_fwctrl_lps == 1) | ||
143 | rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; | ||
144 | else if (rtlpriv->psc.reg_fwctrl_lps == 2) | ||
145 | rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; | ||
146 | else if (rtlpriv->psc.reg_fwctrl_lps == 3) | ||
147 | rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; | ||
148 | |||
149 | /* for firmware buf */ | ||
150 | rtlpriv->rtlhal.pfirmware = vzalloc(0x4000); | ||
80 | if (!rtlpriv->rtlhal.pfirmware) { | 151 | if (!rtlpriv->rtlhal.pfirmware) { |
81 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 152 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, |
82 | ("Can't alloc buffer for fw.\n")); | 153 | ("Can't alloc buffer for fw.\n")); |
83 | return 1; | 154 | return 1; |
84 | } | 155 | } |
85 | 156 | ||
157 | /* request fw */ | ||
158 | err = request_firmware(&firmware, rtlpriv->cfg->fw_name, | ||
159 | rtlpriv->io.dev); | ||
160 | if (err) { | ||
161 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
162 | ("Failed to request firmware!\n")); | ||
163 | return 1; | ||
164 | } | ||
165 | if (firmware->size > 0x4000) { | ||
166 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
167 | ("Firmware is too big!\n")); | ||
168 | release_firmware(firmware); | ||
169 | return 1; | ||
170 | } | ||
171 | memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); | ||
172 | rtlpriv->rtlhal.fwsize = firmware->size; | ||
173 | release_firmware(firmware); | ||
174 | |||
86 | return 0; | 175 | return 0; |
87 | } | 176 | } |
88 | 177 | ||
@@ -103,17 +192,19 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { | |||
103 | .interrupt_recognized = rtl92ce_interrupt_recognized, | 192 | .interrupt_recognized = rtl92ce_interrupt_recognized, |
104 | .hw_init = rtl92ce_hw_init, | 193 | .hw_init = rtl92ce_hw_init, |
105 | .hw_disable = rtl92ce_card_disable, | 194 | .hw_disable = rtl92ce_card_disable, |
195 | .hw_suspend = rtl92ce_suspend, | ||
196 | .hw_resume = rtl92ce_resume, | ||
106 | .enable_interrupt = rtl92ce_enable_interrupt, | 197 | .enable_interrupt = rtl92ce_enable_interrupt, |
107 | .disable_interrupt = rtl92ce_disable_interrupt, | 198 | .disable_interrupt = rtl92ce_disable_interrupt, |
108 | .set_network_type = rtl92ce_set_network_type, | 199 | .set_network_type = rtl92ce_set_network_type, |
200 | .set_chk_bssid = rtl92ce_set_check_bssid, | ||
109 | .set_qos = rtl92ce_set_qos, | 201 | .set_qos = rtl92ce_set_qos, |
110 | .set_bcn_reg = rtl92ce_set_beacon_related_registers, | 202 | .set_bcn_reg = rtl92ce_set_beacon_related_registers, |
111 | .set_bcn_intv = rtl92ce_set_beacon_interval, | 203 | .set_bcn_intv = rtl92ce_set_beacon_interval, |
112 | .update_interrupt_mask = rtl92ce_update_interrupt_mask, | 204 | .update_interrupt_mask = rtl92ce_update_interrupt_mask, |
113 | .get_hw_reg = rtl92ce_get_hw_reg, | 205 | .get_hw_reg = rtl92ce_get_hw_reg, |
114 | .set_hw_reg = rtl92ce_set_hw_reg, | 206 | .set_hw_reg = rtl92ce_set_hw_reg, |
115 | .update_rate_table = rtl92ce_update_hal_rate_table, | 207 | .update_rate_tbl = rtl92ce_update_hal_rate_tbl, |
116 | .update_rate_mask = rtl92ce_update_hal_rate_mask, | ||
117 | .fill_tx_desc = rtl92ce_tx_fill_desc, | 208 | .fill_tx_desc = rtl92ce_tx_fill_desc, |
118 | .fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc, | 209 | .fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc, |
119 | .query_rx_desc = rtl92ce_rx_query_desc, | 210 | .query_rx_desc = rtl92ce_rx_query_desc, |
@@ -123,7 +214,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { | |||
123 | .switch_channel = rtl92c_phy_sw_chnl, | 214 | .switch_channel = rtl92c_phy_sw_chnl, |
124 | .dm_watchdog = rtl92c_dm_watchdog, | 215 | .dm_watchdog = rtl92c_dm_watchdog, |
125 | .scan_operation_backup = rtl92c_phy_scan_operation_backup, | 216 | .scan_operation_backup = rtl92c_phy_scan_operation_backup, |
126 | .set_rf_power_state = rtl92ce_phy_set_rf_power_state, | 217 | .set_rf_power_state = rtl92c_phy_set_rf_power_state, |
127 | .led_control = rtl92ce_led_control, | 218 | .led_control = rtl92ce_led_control, |
128 | .set_desc = rtl92ce_set_desc, | 219 | .set_desc = rtl92ce_set_desc, |
129 | .get_desc = rtl92ce_get_desc, | 220 | .get_desc = rtl92ce_get_desc, |
@@ -133,24 +224,27 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { | |||
133 | .init_sw_leds = rtl92ce_init_sw_leds, | 224 | .init_sw_leds = rtl92ce_init_sw_leds, |
134 | .get_bbreg = rtl92c_phy_query_bb_reg, | 225 | .get_bbreg = rtl92c_phy_query_bb_reg, |
135 | .set_bbreg = rtl92c_phy_set_bb_reg, | 226 | .set_bbreg = rtl92c_phy_set_bb_reg, |
136 | .get_rfreg = rtl92ce_phy_query_rf_reg, | ||
137 | .set_rfreg = rtl92ce_phy_set_rf_reg, | 227 | .set_rfreg = rtl92ce_phy_set_rf_reg, |
138 | .cmd_send_packet = _rtl92c_cmd_send_packet, | 228 | .get_rfreg = rtl92c_phy_query_rf_reg, |
139 | .phy_rf6052_config = rtl92ce_phy_rf6052_config, | 229 | .phy_rf6052_config = rtl92ce_phy_rf6052_config, |
140 | .phy_rf6052_set_cck_txpower = rtl92ce_phy_rf6052_set_cck_txpower, | 230 | .phy_rf6052_set_cck_txpower = rtl92ce_phy_rf6052_set_cck_txpower, |
141 | .phy_rf6052_set_ofdm_txpower = rtl92ce_phy_rf6052_set_ofdm_txpower, | 231 | .phy_rf6052_set_ofdm_txpower = rtl92ce_phy_rf6052_set_ofdm_txpower, |
142 | .config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile, | 232 | .config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile, |
143 | .config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile, | 233 | .config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile, |
144 | .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, | 234 | .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, |
145 | .phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback, | ||
146 | .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower, | 235 | .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower, |
147 | }; | 236 | }; |
148 | 237 | ||
149 | static struct rtl_mod_params rtl92ce_mod_params = { | 238 | static struct rtl_mod_params rtl92ce_mod_params = { |
150 | .sw_crypto = 0, | 239 | .sw_crypto = false, |
240 | .inactiveps = true, | ||
241 | .swctrl_lps = false, | ||
242 | .fwctrl_lps = true, | ||
151 | }; | 243 | }; |
152 | 244 | ||
153 | static struct rtl_hal_cfg rtl92ce_hal_cfg = { | 245 | static struct rtl_hal_cfg rtl92ce_hal_cfg = { |
246 | .bar_id = 2, | ||
247 | .write_readback = true, | ||
154 | .name = "rtl92c_pci", | 248 | .name = "rtl92c_pci", |
155 | .fw_name = "rtlwifi/rtl8192cfw.bin", | 249 | .fw_name = "rtlwifi/rtl8192cfw.bin", |
156 | .ops = &rtl8192ce_hal_ops, | 250 | .ops = &rtl8192ce_hal_ops, |
@@ -174,6 +268,8 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = { | |||
174 | .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, | 268 | .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, |
175 | .maps[EFUSE_ANA8M] = EFUSE_ANA8M, | 269 | .maps[EFUSE_ANA8M] = EFUSE_ANA8M, |
176 | .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, | 270 | .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, |
271 | .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, | ||
272 | .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, | ||
177 | 273 | ||
178 | .maps[RWCAM] = REG_CAMCMD, | 274 | .maps[RWCAM] = REG_CAMCMD, |
179 | .maps[WCAMI] = REG_CAMWRITE, | 275 | .maps[WCAMI] = REG_CAMWRITE, |
@@ -238,7 +334,7 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = { | |||
238 | .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, | 334 | .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, |
239 | }; | 335 | }; |
240 | 336 | ||
241 | static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = { | 337 | DEFINE_PCI_DEVICE_TABLE(rtl92ce_pci_ids) = { |
242 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)}, | 338 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)}, |
243 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)}, | 339 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)}, |
244 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)}, | 340 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)}, |
@@ -256,7 +352,13 @@ MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless"); | |||
256 | MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin"); | 352 | MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin"); |
257 | 353 | ||
258 | module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); | 354 | module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); |
355 | module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444); | ||
356 | module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444); | ||
357 | module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444); | ||
259 | MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); | 358 | MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); |
359 | MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); | ||
360 | MODULE_PARM_DESC(fwlps, "using linked fw control power save " | ||
361 | "(default 1 is open)\n"); | ||
260 | 362 | ||
261 | static struct pci_driver rtl92ce_driver = { | 363 | static struct pci_driver rtl92ce_driver = { |
262 | .name = KBUILD_MODNAME, | 364 | .name = KBUILD_MODNAME, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h index 36e657668c1e..b7dc3263e433 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h | |||
@@ -33,19 +33,9 @@ | |||
33 | int rtl92c_init_sw_vars(struct ieee80211_hw *hw); | 33 | int rtl92c_init_sw_vars(struct ieee80211_hw *hw); |
34 | void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); | 34 | void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); |
35 | void rtl92c_init_var_map(struct ieee80211_hw *hw); | 35 | void rtl92c_init_var_map(struct ieee80211_hw *hw); |
36 | bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, | ||
37 | struct sk_buff *skb); | ||
38 | void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | ||
39 | u8 *ppowerlevel); | ||
40 | void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | ||
41 | u8 *ppowerlevel, u8 channel); | ||
42 | bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | 36 | bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, |
43 | u8 configtype); | 37 | u8 configtype); |
44 | bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | 38 | bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, |
45 | u8 configtype); | 39 | u8 configtype); |
46 | void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); | ||
47 | u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw, | ||
48 | enum radio_path rfpath, u32 regaddr, u32 bitmask); | ||
49 | void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw); | ||
50 | 40 | ||
51 | #endif | 41 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index aa2b5815600f..54b2bd53d36a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | |||
@@ -36,42 +36,16 @@ | |||
36 | #include "trx.h" | 36 | #include "trx.h" |
37 | #include "led.h" | 37 | #include "led.h" |
38 | 38 | ||
39 | static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(__le16 fc, | 39 | static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) |
40 | unsigned int | ||
41 | skb_queue) | ||
42 | { | 40 | { |
43 | enum rtl_desc_qsel qsel; | 41 | __le16 fc = rtl_get_fc(skb); |
44 | 42 | ||
45 | if (unlikely(ieee80211_is_beacon(fc))) { | 43 | if (unlikely(ieee80211_is_beacon(fc))) |
46 | qsel = QSLT_BEACON; | 44 | return QSLT_BEACON; |
47 | return qsel; | 45 | if (ieee80211_is_mgmt(fc)) |
48 | } | 46 | return QSLT_MGNT; |
49 | |||
50 | if (ieee80211_is_mgmt(fc)) { | ||
51 | qsel = QSLT_MGNT; | ||
52 | return qsel; | ||
53 | } | ||
54 | 47 | ||
55 | switch (skb_queue) { | 48 | return skb->priority; |
56 | case VO_QUEUE: | ||
57 | qsel = QSLT_VO; | ||
58 | break; | ||
59 | case VI_QUEUE: | ||
60 | qsel = QSLT_VI; | ||
61 | break; | ||
62 | case BE_QUEUE: | ||
63 | qsel = QSLT_BE; | ||
64 | break; | ||
65 | case BK_QUEUE: | ||
66 | qsel = QSLT_BK; | ||
67 | break; | ||
68 | default: | ||
69 | qsel = QSLT_BE; | ||
70 | RT_ASSERT(false, ("BE queue, skb_queue:%d," | ||
71 | " set qsel = 0x%X\n", skb_queue, QSLT_BE)); | ||
72 | break; | ||
73 | } | ||
74 | return qsel; | ||
75 | } | 49 | } |
76 | 50 | ||
77 | static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu) | 51 | static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu) |
@@ -255,6 +229,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
255 | u8 evm, pwdb_all, rf_rx_num = 0; | 229 | u8 evm, pwdb_all, rf_rx_num = 0; |
256 | u8 i, max_spatial_stream; | 230 | u8 i, max_spatial_stream; |
257 | u32 rssi, total_rssi = 0; | 231 | u32 rssi, total_rssi = 0; |
232 | bool in_powersavemode = false; | ||
258 | bool is_cck_rate; | 233 | bool is_cck_rate; |
259 | 234 | ||
260 | is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); | 235 | is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); |
@@ -270,9 +245,13 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
270 | u8 report, cck_highpwr; | 245 | u8 report, cck_highpwr; |
271 | cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; | 246 | cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; |
272 | 247 | ||
273 | cck_highpwr = (u8) rtl_get_bbreg(hw, | 248 | if (!in_powersavemode) |
274 | RFPGA0_XA_HSSIPARAMETER2, | 249 | cck_highpwr = (u8) rtl_get_bbreg(hw, |
275 | BIT(9)); | 250 | RFPGA0_XA_HSSIPARAMETER2, |
251 | BIT(9)); | ||
252 | else | ||
253 | cck_highpwr = false; | ||
254 | |||
276 | if (!cck_highpwr) { | 255 | if (!cck_highpwr) { |
277 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; | 256 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; |
278 | report = cck_buf->cck_agc_rpt & 0xc0; | 257 | report = cck_buf->cck_agc_rpt & 0xc0; |
@@ -398,6 +377,7 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, | |||
398 | 377 | ||
399 | if (rtlpriv->stats.ui_rssi.total_num++ >= | 378 | if (rtlpriv->stats.ui_rssi.total_num++ >= |
400 | PHY_RSSI_SLID_WIN_MAX) { | 379 | PHY_RSSI_SLID_WIN_MAX) { |
380 | |||
401 | rtlpriv->stats.ui_rssi.total_num = | 381 | rtlpriv->stats.ui_rssi.total_num = |
402 | PHY_RSSI_SLID_WIN_MAX; | 382 | PHY_RSSI_SLID_WIN_MAX; |
403 | last_rssi = | 383 | last_rssi = |
@@ -424,10 +404,6 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, | |||
424 | if (!pstats->is_cck && pstats->packet_toself) { | 404 | if (!pstats->is_cck && pstats->packet_toself) { |
425 | for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; | 405 | for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; |
426 | rfpath++) { | 406 | rfpath++) { |
427 | |||
428 | if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) | ||
429 | continue; | ||
430 | |||
431 | if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { | 407 | if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { |
432 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | 408 | rtlpriv->stats.rx_rssi_percentage[rfpath] = |
433 | pstats->rx_mimo_signalstrength[rfpath]; | 409 | pstats->rx_mimo_signalstrength[rfpath]; |
@@ -723,7 +699,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, | |||
723 | void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | 699 | void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, |
724 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | 700 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, |
725 | struct ieee80211_tx_info *info, struct sk_buff *skb, | 701 | struct ieee80211_tx_info *info, struct sk_buff *skb, |
726 | unsigned int queue_index) | 702 | u8 hw_queue, struct rtl_tcb_desc *tcb_desc) |
727 | { | 703 | { |
728 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 704 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
729 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 705 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
@@ -732,16 +708,9 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
732 | bool defaultadapter = true; | 708 | bool defaultadapter = true; |
733 | struct ieee80211_sta *sta; | 709 | struct ieee80211_sta *sta; |
734 | u8 *pdesc = (u8 *) pdesc_tx; | 710 | u8 *pdesc = (u8 *) pdesc_tx; |
735 | struct rtl_tcb_desc tcb_desc; | ||
736 | u8 *qc = ieee80211_get_qos_ctl(hdr); | ||
737 | u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
738 | u16 seq_number; | 711 | u16 seq_number; |
739 | __le16 fc = hdr->frame_control; | 712 | __le16 fc = hdr->frame_control; |
740 | u8 rate_flag = info->control.rates[0].flags; | 713 | u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue); |
741 | |||
742 | enum rtl_desc_qsel fw_qsel = | ||
743 | _rtl92ce_map_hwqueue_to_fwqueue(fc, queue_index); | ||
744 | |||
745 | bool firstseg = ((hdr->seq_ctrl & | 714 | bool firstseg = ((hdr->seq_ctrl & |
746 | cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); | 715 | cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); |
747 | 716 | ||
@@ -751,56 +720,68 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
751 | dma_addr_t mapping = pci_map_single(rtlpci->pdev, | 720 | dma_addr_t mapping = pci_map_single(rtlpci->pdev, |
752 | skb->data, skb->len, | 721 | skb->data, skb->len, |
753 | PCI_DMA_TODEVICE); | 722 | PCI_DMA_TODEVICE); |
723 | u8 bw_40 = 0; | ||
724 | |||
725 | rcu_read_lock(); | ||
726 | sta = get_sta(hw, mac->vif, mac->bssid); | ||
727 | if (mac->opmode == NL80211_IFTYPE_STATION) { | ||
728 | bw_40 = mac->bw_40; | ||
729 | } else if (mac->opmode == NL80211_IFTYPE_AP || | ||
730 | mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
731 | if (sta) | ||
732 | bw_40 = sta->ht_cap.cap & | ||
733 | IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
734 | } | ||
754 | 735 | ||
755 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; | 736 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; |
756 | 737 | ||
757 | rtl_get_tcb_desc(hw, info, skb, &tcb_desc); | 738 | rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc); |
758 | 739 | ||
759 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); | 740 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); |
760 | 741 | ||
742 | if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { | ||
743 | firstseg = true; | ||
744 | lastseg = true; | ||
745 | } | ||
761 | if (firstseg) { | 746 | if (firstseg) { |
762 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); | 747 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); |
763 | 748 | ||
764 | SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate); | 749 | SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate); |
765 | 750 | ||
766 | if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) | 751 | if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble) |
767 | SET_TX_DESC_DATA_SHORTGI(pdesc, 1); | 752 | SET_TX_DESC_DATA_SHORTGI(pdesc, 1); |
768 | 753 | ||
769 | if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && | 754 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
770 | info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
771 | SET_TX_DESC_AGG_BREAK(pdesc, 1); | 755 | SET_TX_DESC_AGG_BREAK(pdesc, 1); |
772 | SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); | 756 | SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); |
773 | } | 757 | } |
774 | SET_TX_DESC_SEQ(pdesc, seq_number); | 758 | SET_TX_DESC_SEQ(pdesc, seq_number); |
775 | 759 | ||
776 | SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable && | 760 | SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable && |
777 | !tcb_desc. | 761 | !tcb_desc-> |
778 | cts_enable) ? 1 : 0)); | 762 | cts_enable) ? 1 : 0)); |
779 | SET_TX_DESC_HW_RTS_ENABLE(pdesc, | 763 | SET_TX_DESC_HW_RTS_ENABLE(pdesc, |
780 | ((tcb_desc.rts_enable | 764 | ((tcb_desc->rts_enable |
781 | || tcb_desc.cts_enable) ? 1 : 0)); | 765 | || tcb_desc->cts_enable) ? 1 : 0)); |
782 | SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.cts_enable) ? 1 : 0)); | 766 | SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0)); |
783 | SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.rts_stbc) ? 1 : 0)); | 767 | SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0)); |
784 | 768 | ||
785 | SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate); | 769 | SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate); |
786 | SET_TX_DESC_RTS_BW(pdesc, 0); | 770 | SET_TX_DESC_RTS_BW(pdesc, 0); |
787 | SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc); | 771 | SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc); |
788 | SET_TX_DESC_RTS_SHORT(pdesc, | 772 | SET_TX_DESC_RTS_SHORT(pdesc, |
789 | ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? | 773 | ((tcb_desc->rts_rate <= DESC92C_RATE54M) ? |
790 | (tcb_desc.rts_use_shortpreamble ? 1 : 0) | 774 | (tcb_desc->rts_use_shortpreamble ? 1 : 0) |
791 | : (tcb_desc.rts_use_shortgi ? 1 : 0))); | 775 | : (tcb_desc->rts_use_shortgi ? 1 : 0))); |
792 | 776 | ||
793 | if (mac->bw_40) { | 777 | if (bw_40) { |
794 | if (tcb_desc.packet_bw) { | 778 | if (tcb_desc->packet_bw) { |
795 | SET_TX_DESC_DATA_BW(pdesc, 1); | 779 | SET_TX_DESC_DATA_BW(pdesc, 1); |
796 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); | 780 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); |
797 | } else { | 781 | } else { |
798 | SET_TX_DESC_DATA_BW(pdesc, 0); | 782 | SET_TX_DESC_DATA_BW(pdesc, 0); |
799 | 783 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, | |
800 | if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { | 784 | mac->cur_40_prime_sc); |
801 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, | ||
802 | mac->cur_40_prime_sc); | ||
803 | } | ||
804 | } | 785 | } |
805 | } else { | 786 | } else { |
806 | SET_TX_DESC_DATA_BW(pdesc, 0); | 787 | SET_TX_DESC_DATA_BW(pdesc, 0); |
@@ -810,13 +791,10 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
810 | SET_TX_DESC_LINIP(pdesc, 0); | 791 | SET_TX_DESC_LINIP(pdesc, 0); |
811 | SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); | 792 | SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); |
812 | 793 | ||
813 | rcu_read_lock(); | ||
814 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | ||
815 | if (sta) { | 794 | if (sta) { |
816 | u8 ampdu_density = sta->ht_cap.ampdu_density; | 795 | u8 ampdu_density = sta->ht_cap.ampdu_density; |
817 | SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); | 796 | SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); |
818 | } | 797 | } |
819 | rcu_read_unlock(); | ||
820 | 798 | ||
821 | if (info->control.hw_key) { | 799 | if (info->control.hw_key) { |
822 | struct ieee80211_key_conf *keyconf = | 800 | struct ieee80211_key_conf *keyconf = |
@@ -844,7 +822,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
844 | SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); | 822 | SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); |
845 | SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); | 823 | SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); |
846 | SET_TX_DESC_DISABLE_FB(pdesc, 0); | 824 | SET_TX_DESC_DISABLE_FB(pdesc, 0); |
847 | SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0); | 825 | SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0); |
848 | 826 | ||
849 | if (ieee80211_is_data_qos(fc)) { | 827 | if (ieee80211_is_data_qos(fc)) { |
850 | if (mac->rdg_en) { | 828 | if (mac->rdg_en) { |
@@ -855,24 +833,24 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
855 | } | 833 | } |
856 | } | 834 | } |
857 | } | 835 | } |
836 | rcu_read_unlock(); | ||
858 | 837 | ||
859 | SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); | 838 | SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); |
860 | SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); | 839 | SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); |
861 | 840 | ||
862 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); | 841 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); |
863 | 842 | ||
864 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); | 843 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); |
865 | 844 | ||
866 | if (rtlpriv->dm.useramask) { | 845 | if (rtlpriv->dm.useramask) { |
867 | SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index); | 846 | SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index); |
868 | SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id); | 847 | SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id); |
869 | } else { | 848 | } else { |
870 | SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index); | 849 | SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index); |
871 | SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index); | 850 | SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index); |
872 | } | 851 | } |
873 | 852 | ||
874 | if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && | 853 | if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) { |
875 | ppsc->fwctrl_lps) { | ||
876 | SET_TX_DESC_HWSEQ_EN(pdesc, 1); | 854 | SET_TX_DESC_HWSEQ_EN(pdesc, 1); |
877 | SET_TX_DESC_PKT_ID(pdesc, 8); | 855 | SET_TX_DESC_PKT_ID(pdesc, 8); |
878 | 856 | ||
@@ -923,7 +901,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, | |||
923 | 901 | ||
924 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); | 902 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); |
925 | 903 | ||
926 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); | 904 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); |
927 | 905 | ||
928 | SET_TX_DESC_RATE_ID(pdesc, 7); | 906 | SET_TX_DESC_RATE_ID(pdesc, 7); |
929 | SET_TX_DESC_MACID(pdesc, 0); | 907 | SET_TX_DESC_MACID(pdesc, 0); |
@@ -1021,7 +999,7 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) | |||
1021 | return ret; | 999 | return ret; |
1022 | } | 1000 | } |
1023 | 1001 | ||
1024 | void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) | 1002 | void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) |
1025 | { | 1003 | { |
1026 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1004 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1027 | if (hw_queue == BEACON_QUEUE) { | 1005 | if (hw_queue == BEACON_QUEUE) { |
@@ -1032,35 +1010,3 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) | |||
1032 | } | 1010 | } |
1033 | } | 1011 | } |
1034 | 1012 | ||
1035 | bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, | ||
1036 | struct sk_buff *skb) | ||
1037 | { | ||
1038 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1039 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1040 | struct rtl8192_tx_ring *ring; | ||
1041 | struct rtl_tx_desc *pdesc; | ||
1042 | u8 own; | ||
1043 | unsigned long flags; | ||
1044 | struct sk_buff *pskb = NULL; | ||
1045 | |||
1046 | ring = &rtlpci->tx_ring[BEACON_QUEUE]; | ||
1047 | |||
1048 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); | ||
1049 | |||
1050 | pskb = __skb_dequeue(&ring->queue); | ||
1051 | if (pskb) | ||
1052 | kfree_skb(pskb); | ||
1053 | |||
1054 | pdesc = &ring->desc[0]; | ||
1055 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); | ||
1056 | |||
1057 | rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); | ||
1058 | |||
1059 | __skb_queue_tail(&ring->queue, skb); | ||
1060 | |||
1061 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | ||
1062 | |||
1063 | rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); | ||
1064 | |||
1065 | return true; | ||
1066 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index b0b0b13dd0ae..0f1177137501 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | |||
@@ -724,17 +724,16 @@ struct rx_desc_92c { | |||
724 | void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | 724 | void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, |
725 | struct ieee80211_hdr *hdr, | 725 | struct ieee80211_hdr *hdr, |
726 | u8 *pdesc, struct ieee80211_tx_info *info, | 726 | u8 *pdesc, struct ieee80211_tx_info *info, |
727 | struct sk_buff *skb, unsigned int qsel); | 727 | struct sk_buff *skb, u8 hw_queue, |
728 | struct rtl_tcb_desc *ptcb_desc); | ||
728 | bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, | 729 | bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, |
729 | struct rtl_stats *stats, | 730 | struct rtl_stats *stats, |
730 | struct ieee80211_rx_status *rx_status, | 731 | struct ieee80211_rx_status *rx_status, |
731 | u8 *pdesc, struct sk_buff *skb); | 732 | u8 *pdesc, struct sk_buff *skb); |
732 | void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); | 733 | void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); |
733 | u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name); | 734 | u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name); |
734 | void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue); | 735 | void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); |
735 | void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, | 736 | void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, |
736 | bool b_firstseg, bool b_lastseg, | 737 | bool b_firstseg, bool b_lastseg, |
737 | struct sk_buff *skb); | 738 | struct sk_buff *skb); |
738 | bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
739 | |||
740 | #endif | 739 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index e43be2547827..52e2af58c1ed 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "mac.h" | 39 | #include "mac.h" |
40 | #include "dm.h" | 40 | #include "dm.h" |
41 | #include "hw.h" | 41 | #include "hw.h" |
42 | #include "../rtl8192ce/hw.h" | ||
42 | #include "trx.h" | 43 | #include "trx.h" |
43 | #include "led.h" | 44 | #include "led.h" |
44 | #include "table.h" | 45 | #include "table.h" |
@@ -605,10 +606,10 @@ void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) | |||
605 | if (!IS_NORMAL_CHIP(rtlhal->version)) | 606 | if (!IS_NORMAL_CHIP(rtlhal->version)) |
606 | return; | 607 | return; |
607 | tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); | 608 | tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); |
608 | rtlefuse->epromtype = (tmp_u1b & EEPROMSEL) ? | 609 | rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ? |
609 | EEPROM_93C46 : EEPROM_BOOT_EFUSE; | 610 | EEPROM_93C46 : EEPROM_BOOT_EFUSE; |
610 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n", | 611 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n", |
611 | (tmp_u1b & EEPROMSEL) ? "EERROM" : "EFUSE")); | 612 | (tmp_u1b & BOOT_FROM_EEPROM) ? "EERROM" : "EFUSE")); |
612 | rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; | 613 | rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; |
613 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n", | 614 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n", |
614 | (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!")); | 615 | (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!")); |
@@ -977,7 +978,7 @@ static void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw) | |||
977 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 978 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
978 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 979 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
979 | 980 | ||
980 | mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APP_FCS | | 981 | mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APPFCS | |
981 | RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | | 982 | RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | |
982 | RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32); | 983 | RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32); |
983 | rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf); | 984 | rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf); |
@@ -2182,7 +2183,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
2182 | } | 2183 | } |
2183 | } | 2184 | } |
2184 | 2185 | ||
2185 | void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw) | 2186 | void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, |
2187 | struct ieee80211_sta *sta, | ||
2188 | u8 rssi_level) | ||
2186 | { | 2189 | { |
2187 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 2190 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
2188 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 2191 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h index 62af555bb61c..32f85cba106a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h | |||
@@ -98,13 +98,14 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, | |||
98 | u32 add_msr, u32 rm_msr); | 98 | u32 add_msr, u32 rm_msr); |
99 | void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | 99 | void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); |
100 | void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | 100 | void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); |
101 | void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw); | 101 | void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, |
102 | struct ieee80211_sta *sta, | ||
103 | u8 rssi_level); | ||
102 | void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); | 104 | void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); |
103 | 105 | ||
104 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); | 106 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); |
105 | bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); | 107 | bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); |
106 | void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); | 108 | void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); |
107 | u8 _rtl92c_get_chnl_group(u8 chnl); | ||
108 | int rtl92c_download_fw(struct ieee80211_hw *hw); | 109 | int rtl92c_download_fw(struct ieee80211_hw *hw); |
109 | void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); | 110 | void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); |
110 | void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished); | 111 | void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index 4e020e654e6b..9a3d0239e27e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "table.h" | 38 | #include "table.h" |
39 | 39 | ||
40 | u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, | 40 | u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, |
41 | enum radio_path rfpath, u32 regaddr, u32 bitmask) | 41 | enum radio_path rfpath, u32 regaddr, u32 bitmask) |
42 | { | 42 | { |
43 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 43 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
44 | u32 original_value, readback_value, bitshift; | 44 | u32 original_value, readback_value, bitshift; |
@@ -64,8 +64,8 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, | |||
64 | } | 64 | } |
65 | 65 | ||
66 | void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, | 66 | void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, |
67 | enum radio_path rfpath, | 67 | enum radio_path rfpath, |
68 | u32 regaddr, u32 bitmask, u32 data) | 68 | u32 regaddr, u32 bitmask, u32 data) |
69 | { | 69 | { |
70 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 70 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
71 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 71 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -163,7 +163,7 @@ bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) | |||
163 | } | 163 | } |
164 | 164 | ||
165 | bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | 165 | bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, |
166 | u8 configtype) | 166 | u8 configtype) |
167 | { | 167 | { |
168 | int i; | 168 | int i; |
169 | u32 *phy_regarray_table; | 169 | u32 *phy_regarray_table; |
@@ -223,7 +223,7 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | |||
223 | } | 223 | } |
224 | 224 | ||
225 | bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | 225 | bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, |
226 | u8 configtype) | 226 | u8 configtype) |
227 | { | 227 | { |
228 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 228 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
229 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 229 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -459,7 +459,7 @@ void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | |||
459 | } | 459 | } |
460 | } | 460 | } |
461 | 461 | ||
462 | bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, | 462 | static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, |
463 | enum rf_pwrstate rfpwr_state) | 463 | enum rf_pwrstate rfpwr_state) |
464 | { | 464 | { |
465 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 465 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -595,7 +595,7 @@ bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
595 | } | 595 | } |
596 | 596 | ||
597 | bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, | 597 | bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, |
598 | enum rf_pwrstate rfpwr_state) | 598 | enum rf_pwrstate rfpwr_state) |
599 | { | 599 | { |
600 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 600 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
601 | bool bresult = false; | 601 | bool bresult = false; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h index 06299559ab68..ff81a61729d7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h | |||
@@ -34,3 +34,17 @@ bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath); | |||
34 | void rtl92c_phy_set_io(struct ieee80211_hw *hw); | 34 | void rtl92c_phy_set_io(struct ieee80211_hw *hw); |
35 | bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); | 35 | bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); |
36 | bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw); | 36 | bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw); |
37 | u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, | ||
38 | enum radio_path rfpath, u32 regaddr, u32 bitmask); | ||
39 | void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, | ||
40 | enum radio_path rfpath, | ||
41 | u32 regaddr, u32 bitmask, u32 data); | ||
42 | bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw); | ||
43 | bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | ||
44 | u8 configtype); | ||
45 | void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); | ||
46 | bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | ||
47 | u8 configtype); | ||
48 | void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw); | ||
49 | bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
50 | enum rf_pwrstate rfpwr_state); | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 1c79c226f145..c7576ec4744e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | |||
@@ -62,7 +62,7 @@ void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) | |||
62 | } | 62 | } |
63 | 63 | ||
64 | void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | 64 | void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, |
65 | u8 *ppowerlevel) | 65 | u8 *ppowerlevel) |
66 | { | 66 | { |
67 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 67 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
68 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 68 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
@@ -389,7 +389,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, | |||
389 | } | 389 | } |
390 | 390 | ||
391 | void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | 391 | void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, |
392 | u8 *ppowerlevel, u8 channel) | 392 | u8 *ppowerlevel, u8 channel) |
393 | { | 393 | { |
394 | u32 writeVal[2], powerBase0[2], powerBase1[2]; | 394 | u32 writeVal[2], powerBase0[2], powerBase1[2]; |
395 | u8 index = 0; | 395 | u8 index = 0; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h index 86c2728cfa00..500a2094b6bb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h | |||
@@ -43,5 +43,9 @@ extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | |||
43 | bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw); | 43 | bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw); |
44 | bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | 44 | bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, |
45 | enum radio_path rfpath); | 45 | enum radio_path rfpath); |
46 | void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | ||
47 | u8 *ppowerlevel); | ||
48 | void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | ||
49 | u8 *ppowerlevel, u8 channel); | ||
46 | 50 | ||
47 | #endif | 51 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 71244a38d49e..bee7c1480f63 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
@@ -94,7 +94,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { | |||
94 | .update_interrupt_mask = rtl92cu_update_interrupt_mask, | 94 | .update_interrupt_mask = rtl92cu_update_interrupt_mask, |
95 | .get_hw_reg = rtl92cu_get_hw_reg, | 95 | .get_hw_reg = rtl92cu_get_hw_reg, |
96 | .set_hw_reg = rtl92cu_set_hw_reg, | 96 | .set_hw_reg = rtl92cu_set_hw_reg, |
97 | .update_rate_table = rtl92cu_update_hal_rate_table, | 97 | .update_rate_tbl = rtl92cu_update_hal_rate_table, |
98 | .update_rate_mask = rtl92cu_update_hal_rate_mask, | 98 | .update_rate_mask = rtl92cu_update_hal_rate_mask, |
99 | .fill_tx_desc = rtl92cu_tx_fill_desc, | 99 | .fill_tx_desc = rtl92cu_tx_fill_desc, |
100 | .fill_fake_txdesc = rtl92cu_fill_fake_txdesc, | 100 | .fill_fake_txdesc = rtl92cu_fill_fake_txdesc, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 3f0cb81c424f..79c98f62175f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | |||
@@ -498,14 +498,14 @@ static void _rtl_tx_desc_checksum(u8 *txdesc) | |||
498 | void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | 498 | void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, |
499 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | 499 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, |
500 | struct ieee80211_tx_info *info, struct sk_buff *skb, | 500 | struct ieee80211_tx_info *info, struct sk_buff *skb, |
501 | unsigned int queue_index) | 501 | u8 queue_index, |
502 | struct rtl_tcb_desc *tcb_desc) | ||
502 | { | 503 | { |
503 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 504 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
504 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 505 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
505 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 506 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
506 | bool defaultadapter = true; | 507 | bool defaultadapter = true; |
507 | struct ieee80211_sta *sta; | 508 | struct ieee80211_sta *sta = info->control.sta = info->control.sta; |
508 | struct rtl_tcb_desc tcb_desc; | ||
509 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 509 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
510 | u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 510 | u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; |
511 | u16 seq_number; | 511 | u16 seq_number; |
@@ -517,15 +517,15 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | |||
517 | u8 *txdesc; | 517 | u8 *txdesc; |
518 | 518 | ||
519 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; | 519 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; |
520 | rtl_get_tcb_desc(hw, info, skb, &tcb_desc); | 520 | rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc); |
521 | txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE); | 521 | txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE); |
522 | memset(txdesc, 0, RTL_TX_HEADER_SIZE); | 522 | memset(txdesc, 0, RTL_TX_HEADER_SIZE); |
523 | SET_TX_DESC_PKT_SIZE(txdesc, pktlen); | 523 | SET_TX_DESC_PKT_SIZE(txdesc, pktlen); |
524 | SET_TX_DESC_LINIP(txdesc, 0); | 524 | SET_TX_DESC_LINIP(txdesc, 0); |
525 | SET_TX_DESC_PKT_OFFSET(txdesc, RTL_DUMMY_OFFSET); | 525 | SET_TX_DESC_PKT_OFFSET(txdesc, RTL_DUMMY_OFFSET); |
526 | SET_TX_DESC_OFFSET(txdesc, RTL_TX_HEADER_SIZE); | 526 | SET_TX_DESC_OFFSET(txdesc, RTL_TX_HEADER_SIZE); |
527 | SET_TX_DESC_TX_RATE(txdesc, tcb_desc.hw_rate); | 527 | SET_TX_DESC_TX_RATE(txdesc, tcb_desc->hw_rate); |
528 | if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) | 528 | if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble) |
529 | SET_TX_DESC_DATA_SHORTGI(txdesc, 1); | 529 | SET_TX_DESC_DATA_SHORTGI(txdesc, 1); |
530 | if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && | 530 | if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && |
531 | info->flags & IEEE80211_TX_CTL_AMPDU) { | 531 | info->flags & IEEE80211_TX_CTL_AMPDU) { |
@@ -535,21 +535,21 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | |||
535 | SET_TX_DESC_AGG_BREAK(txdesc, 1); | 535 | SET_TX_DESC_AGG_BREAK(txdesc, 1); |
536 | } | 536 | } |
537 | SET_TX_DESC_SEQ(txdesc, seq_number); | 537 | SET_TX_DESC_SEQ(txdesc, seq_number); |
538 | SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable && | 538 | SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable && |
539 | !tcb_desc.cts_enable) ? 1 : 0)); | 539 | !tcb_desc->cts_enable) ? 1 : 0)); |
540 | SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable || | 540 | SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable || |
541 | tcb_desc.cts_enable) ? 1 : 0)); | 541 | tcb_desc->cts_enable) ? 1 : 0)); |
542 | SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc.cts_enable) ? 1 : 0)); | 542 | SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc->cts_enable) ? 1 : 0)); |
543 | SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc.rts_stbc) ? 1 : 0)); | 543 | SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc->rts_stbc) ? 1 : 0)); |
544 | SET_TX_DESC_RTS_RATE(txdesc, tcb_desc.rts_rate); | 544 | SET_TX_DESC_RTS_RATE(txdesc, tcb_desc->rts_rate); |
545 | SET_TX_DESC_RTS_BW(txdesc, 0); | 545 | SET_TX_DESC_RTS_BW(txdesc, 0); |
546 | SET_TX_DESC_RTS_SC(txdesc, tcb_desc.rts_sc); | 546 | SET_TX_DESC_RTS_SC(txdesc, tcb_desc->rts_sc); |
547 | SET_TX_DESC_RTS_SHORT(txdesc, | 547 | SET_TX_DESC_RTS_SHORT(txdesc, |
548 | ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? | 548 | ((tcb_desc->rts_rate <= DESC92C_RATE54M) ? |
549 | (tcb_desc.rts_use_shortpreamble ? 1 : 0) | 549 | (tcb_desc->rts_use_shortpreamble ? 1 : 0) |
550 | : (tcb_desc.rts_use_shortgi ? 1 : 0))); | 550 | : (tcb_desc->rts_use_shortgi ? 1 : 0))); |
551 | if (mac->bw_40) { | 551 | if (mac->bw_40) { |
552 | if (tcb_desc.packet_bw) { | 552 | if (tcb_desc->packet_bw) { |
553 | SET_TX_DESC_DATA_BW(txdesc, 1); | 553 | SET_TX_DESC_DATA_BW(txdesc, 1); |
554 | SET_TX_DESC_DATA_SC(txdesc, 3); | 554 | SET_TX_DESC_DATA_SC(txdesc, 3); |
555 | } else { | 555 | } else { |
@@ -590,7 +590,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | |||
590 | SET_TX_DESC_DATA_RATE_FB_LIMIT(txdesc, 0x1F); | 590 | SET_TX_DESC_DATA_RATE_FB_LIMIT(txdesc, 0x1F); |
591 | SET_TX_DESC_RTS_RATE_FB_LIMIT(txdesc, 0xF); | 591 | SET_TX_DESC_RTS_RATE_FB_LIMIT(txdesc, 0xF); |
592 | SET_TX_DESC_DISABLE_FB(txdesc, 0); | 592 | SET_TX_DESC_DISABLE_FB(txdesc, 0); |
593 | SET_TX_DESC_USE_RATE(txdesc, tcb_desc.use_driver_rate ? 1 : 0); | 593 | SET_TX_DESC_USE_RATE(txdesc, tcb_desc->use_driver_rate ? 1 : 0); |
594 | if (ieee80211_is_data_qos(fc)) { | 594 | if (ieee80211_is_data_qos(fc)) { |
595 | if (mac->rdg_en) { | 595 | if (mac->rdg_en) { |
596 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, | 596 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, |
@@ -600,11 +600,11 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | |||
600 | } | 600 | } |
601 | } | 601 | } |
602 | if (rtlpriv->dm.useramask) { | 602 | if (rtlpriv->dm.useramask) { |
603 | SET_TX_DESC_RATE_ID(txdesc, tcb_desc.ratr_index); | 603 | SET_TX_DESC_RATE_ID(txdesc, tcb_desc->ratr_index); |
604 | SET_TX_DESC_MACID(txdesc, tcb_desc.mac_id); | 604 | SET_TX_DESC_MACID(txdesc, tcb_desc->mac_id); |
605 | } else { | 605 | } else { |
606 | SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc.ratr_index); | 606 | SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc->ratr_index); |
607 | SET_TX_DESC_MACID(txdesc, tcb_desc.ratr_index); | 607 | SET_TX_DESC_MACID(txdesc, tcb_desc->ratr_index); |
608 | } | 608 | } |
609 | if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && | 609 | if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && |
610 | ppsc->fwctrl_lps) { | 610 | ppsc->fwctrl_lps) { |
@@ -656,7 +656,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, | |||
656 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 656 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); |
657 | __le16 fc = hdr->frame_control; | 657 | __le16 fc = hdr->frame_control; |
658 | 658 | ||
659 | memset(pdesc, 0, RTL_TX_HEADER_SIZE); | 659 | memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE); |
660 | if (firstseg) | 660 | if (firstseg) |
661 | SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE); | 661 | SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE); |
662 | SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); | 662 | SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h index b396d46edbb7..53de5f66e242 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h | |||
@@ -37,6 +37,8 @@ | |||
37 | #define RTL92C_SIZE_MAX_RX_BUFFER 15360 /* 8192 */ | 37 | #define RTL92C_SIZE_MAX_RX_BUFFER 15360 /* 8192 */ |
38 | #define RX_DRV_INFO_SIZE_UNIT 8 | 38 | #define RX_DRV_INFO_SIZE_UNIT 8 |
39 | 39 | ||
40 | #define RTL_AGG_ON 1 | ||
41 | |||
40 | enum usb_rx_agg_mode { | 42 | enum usb_rx_agg_mode { |
41 | USB_RX_AGG_DISABLE, | 43 | USB_RX_AGG_DISABLE, |
42 | USB_RX_AGG_DMA, | 44 | USB_RX_AGG_DMA, |
@@ -419,7 +421,8 @@ struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *, | |||
419 | void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | 421 | void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, |
420 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | 422 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, |
421 | struct ieee80211_tx_info *info, struct sk_buff *skb, | 423 | struct ieee80211_tx_info *info, struct sk_buff *skb, |
422 | unsigned int queue_index); | 424 | u8 queue_index, |
425 | struct rtl_tcb_desc *tcb_desc); | ||
423 | void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, | 426 | void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, |
424 | u32 buffer_len, bool bIsPsPoll); | 427 | u32 buffer_len, bool bIsPsPoll); |
425 | void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, | 428 | void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index f5d85735d642..a9367eba1ea7 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -852,6 +852,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
852 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 852 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
853 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 853 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
854 | struct rtl_tx_desc *pdesc = NULL; | 854 | struct rtl_tx_desc *pdesc = NULL; |
855 | struct rtl_tcb_desc tcb_desc; | ||
855 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 856 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); |
856 | __le16 fc = hdr->frame_control; | 857 | __le16 fc = hdr->frame_control; |
857 | u8 *pda_addr = hdr->addr1; | 858 | u8 *pda_addr = hdr->addr1; |
@@ -860,8 +861,17 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
860 | u8 tid = 0; | 861 | u8 tid = 0; |
861 | u16 seq_number = 0; | 862 | u16 seq_number = 0; |
862 | 863 | ||
863 | if (ieee80211_is_mgmt(fc)) | 864 | if (ieee80211_is_auth(fc)) { |
864 | rtl_tx_mgmt_proc(hw, skb); | 865 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); |
866 | rtl_ips_nic_on(hw); | ||
867 | } | ||
868 | |||
869 | if (rtlpriv->psc.sw_ps_enabled) { | ||
870 | if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && | ||
871 | !ieee80211_has_pm(fc)) | ||
872 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); | ||
873 | } | ||
874 | |||
865 | rtl_action_proc(hw, skb, true); | 875 | rtl_action_proc(hw, skb, true); |
866 | if (is_multicast_ether_addr(pda_addr)) | 876 | if (is_multicast_ether_addr(pda_addr)) |
867 | rtlpriv->stats.txbytesmulticast += skb->len; | 877 | rtlpriv->stats.txbytesmulticast += skb->len; |
@@ -878,7 +888,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
878 | seq_number <<= 4; | 888 | seq_number <<= 4; |
879 | } | 889 | } |
880 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb, | 890 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb, |
881 | hw_queue); | 891 | hw_queue, &tcb_desc); |
882 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | 892 | if (!ieee80211_has_morefrags(hdr->frame_control)) { |
883 | if (qc) | 893 | if (qc) |
884 | mac->tids[tid].seq_number = seq_number; | 894 | mac->tids[tid].seq_number = seq_number; |
@@ -887,7 +897,8 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
887 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); | 897 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); |
888 | } | 898 | } |
889 | 899 | ||
890 | static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 900 | static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb, |
901 | struct rtl_tcb_desc *dummy) | ||
891 | { | 902 | { |
892 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | 903 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); |
893 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 904 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h index abadfe918d30..d2a63fb3e1e6 100644 --- a/drivers/net/wireless/rtlwifi/usb.h +++ b/drivers/net/wireless/rtlwifi/usb.h | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
32 | #include <linux/skbuff.h> | 32 | #include <linux/skbuff.h> |
33 | 33 | ||
34 | #define RTL_RX_DESC_SIZE 24 | ||
35 | |||
34 | #define RTL_USB_DEVICE(vend, prod, cfg) \ | 36 | #define RTL_USB_DEVICE(vend, prod, cfg) \ |
35 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ | 37 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ |
36 | .idVendor = (vend), \ | 38 | .idVendor = (vend), \ |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 2713efe07ce5..693395ee98f9 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -68,6 +68,8 @@ | |||
68 | #define QBSS_LOAD_SIZE 5 | 68 | #define QBSS_LOAD_SIZE 5 |
69 | #define MAX_WMMELE_LENGTH 64 | 69 | #define MAX_WMMELE_LENGTH 64 |
70 | 70 | ||
71 | #define TOTAL_CAM_ENTRY 32 | ||
72 | |||
71 | /*slot time for 11g. */ | 73 | /*slot time for 11g. */ |
72 | #define RTL_SLOT_TIME_9 9 | 74 | #define RTL_SLOT_TIME_9 9 |
73 | #define RTL_SLOT_TIME_20 20 | 75 | #define RTL_SLOT_TIME_20 20 |
@@ -94,8 +96,10 @@ | |||
94 | #define CHANNEL_GROUP_MAX_5G 9 | 96 | #define CHANNEL_GROUP_MAX_5G 9 |
95 | #define CHANNEL_MAX_NUMBER_2G 14 | 97 | #define CHANNEL_MAX_NUMBER_2G 14 |
96 | #define AVG_THERMAL_NUM 8 | 98 | #define AVG_THERMAL_NUM 8 |
99 | #define MAX_TID_COUNT 9 | ||
97 | 100 | ||
98 | /* for early mode */ | 101 | /* for early mode */ |
102 | #define FCS_LEN 4 | ||
99 | #define EM_HDR_LEN 8 | 103 | #define EM_HDR_LEN 8 |
100 | enum intf_type { | 104 | enum intf_type { |
101 | INTF_PCI = 0, | 105 | INTF_PCI = 0, |
@@ -159,6 +163,8 @@ enum hardware_type { | |||
159 | (IS_HARDWARE_TYPE_8192DE(rtlhal) || IS_HARDWARE_TYPE_8192DU(rtlhal)) | 163 | (IS_HARDWARE_TYPE_8192DE(rtlhal) || IS_HARDWARE_TYPE_8192DU(rtlhal)) |
160 | #define IS_HARDWARE_TYPE_8723(rtlhal) \ | 164 | #define IS_HARDWARE_TYPE_8723(rtlhal) \ |
161 | (IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal)) | 165 | (IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal)) |
166 | #define IS_HARDWARE_TYPE_8723U(rtlhal) \ | ||
167 | (rtlhal->hw_type == HARDWARE_TYPE_RTL8723U) | ||
162 | 168 | ||
163 | enum scan_operation_backup_opt { | 169 | enum scan_operation_backup_opt { |
164 | SCAN_OPT_BACKUP = 0, | 170 | SCAN_OPT_BACKUP = 0, |
@@ -297,6 +303,9 @@ enum hw_variables { | |||
297 | HW_VAR_DATA_FILTER, | 303 | HW_VAR_DATA_FILTER, |
298 | }; | 304 | }; |
299 | 305 | ||
306 | #define HWSET_MAX_SIZE 128 | ||
307 | #define EFUSE_MAX_SECTION 16 | ||
308 | |||
300 | enum _RT_MEDIA_STATUS { | 309 | enum _RT_MEDIA_STATUS { |
301 | RT_MEDIA_DISCONNECT = 0, | 310 | RT_MEDIA_DISCONNECT = 0, |
302 | RT_MEDIA_CONNECT = 1 | 311 | RT_MEDIA_CONNECT = 1 |
@@ -843,6 +852,7 @@ struct rtl_phy { | |||
843 | bool apk_done; | 852 | bool apk_done; |
844 | u32 reg_rf3c[2]; /* pathA / pathB */ | 853 | u32 reg_rf3c[2]; /* pathA / pathB */ |
845 | 854 | ||
855 | /* bfsync */ | ||
846 | u8 framesync; | 856 | u8 framesync; |
847 | u32 framesync_c34; | 857 | u32 framesync_c34; |
848 | 858 | ||
@@ -852,6 +862,10 @@ struct rtl_phy { | |||
852 | }; | 862 | }; |
853 | 863 | ||
854 | #define MAX_TID_COUNT 9 | 864 | #define MAX_TID_COUNT 9 |
865 | #define RTL_AGG_STOP 0 | ||
866 | #define RTL_AGG_PROGRESS 1 | ||
867 | #define RTL_AGG_START 2 | ||
868 | #define RTL_AGG_OPERATIONAL 3 | ||
855 | #define RTL_AGG_OFF 0 | 869 | #define RTL_AGG_OFF 0 |
856 | #define RTL_AGG_ON 1 | 870 | #define RTL_AGG_ON 1 |
857 | #define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2 | 871 | #define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2 |
@@ -871,6 +885,13 @@ struct rtl_tid_data { | |||
871 | struct rtl_ht_agg agg; | 885 | struct rtl_ht_agg agg; |
872 | }; | 886 | }; |
873 | 887 | ||
888 | struct rtl_sta_info { | ||
889 | u8 ratr_index; | ||
890 | u8 wireless_mode; | ||
891 | u8 mimo_ps; | ||
892 | struct rtl_tid_data tids[MAX_TID_COUNT]; | ||
893 | } __packed; | ||
894 | |||
874 | struct rtl_priv; | 895 | struct rtl_priv; |
875 | struct rtl_io { | 896 | struct rtl_io { |
876 | struct device *dev; | 897 | struct device *dev; |
@@ -894,6 +915,7 @@ struct rtl_io { | |||
894 | u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr); | 915 | u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr); |
895 | int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len, | 916 | int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len, |
896 | u8 *pdata); | 917 | u8 *pdata); |
918 | |||
897 | }; | 919 | }; |
898 | 920 | ||
899 | struct rtl_mac { | 921 | struct rtl_mac { |
@@ -916,6 +938,8 @@ struct rtl_mac { | |||
916 | int n_channels; | 938 | int n_channels; |
917 | int n_bitrates; | 939 | int n_bitrates; |
918 | 940 | ||
941 | bool offchan_deley; | ||
942 | |||
919 | /*filters */ | 943 | /*filters */ |
920 | u32 rx_conf; | 944 | u32 rx_conf; |
921 | u16 rx_mgt_filter; | 945 | u16 rx_mgt_filter; |
@@ -1032,7 +1056,9 @@ struct rtl_security { | |||
1032 | enum rt_enc_alg pairwise_enc_algorithm; | 1056 | enum rt_enc_alg pairwise_enc_algorithm; |
1033 | /*Encryption Algorithm for Brocast/Multicast */ | 1057 | /*Encryption Algorithm for Brocast/Multicast */ |
1034 | enum rt_enc_alg group_enc_algorithm; | 1058 | enum rt_enc_alg group_enc_algorithm; |
1035 | 1059 | /*Cam Entry Bitmap */ | |
1060 | u32 hwsec_cam_bitmap; | ||
1061 | u8 hwsec_cam_sta_addr[TOTAL_CAM_ENTRY][ETH_ALEN]; | ||
1036 | /*local Key buffer, indx 0 is for | 1062 | /*local Key buffer, indx 0 is for |
1037 | pairwise key 1-4 is for agoup key. */ | 1063 | pairwise key 1-4 is for agoup key. */ |
1038 | u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN]; | 1064 | u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN]; |
@@ -1053,7 +1079,7 @@ struct rtl_dm { | |||
1053 | bool current_turbo_edca; | 1079 | bool current_turbo_edca; |
1054 | bool is_any_nonbepkts; /*out dm */ | 1080 | bool is_any_nonbepkts; /*out dm */ |
1055 | bool is_cur_rdlstate; | 1081 | bool is_cur_rdlstate; |
1056 | bool txpower_trackingInit; | 1082 | bool txpower_trackinginit; |
1057 | bool disable_framebursting; | 1083 | bool disable_framebursting; |
1058 | bool cck_inch14; | 1084 | bool cck_inch14; |
1059 | bool txpower_tracking; | 1085 | bool txpower_tracking; |
@@ -1079,7 +1105,6 @@ struct rtl_dm { | |||
1079 | bool disable_tx_int; | 1105 | bool disable_tx_int; |
1080 | char ofdm_index[2]; | 1106 | char ofdm_index[2]; |
1081 | char cck_index; | 1107 | char cck_index; |
1082 | u8 power_index_backup[6]; | ||
1083 | }; | 1108 | }; |
1084 | 1109 | ||
1085 | #define EFUSE_MAX_LOGICAL_SIZE 256 | 1110 | #define EFUSE_MAX_LOGICAL_SIZE 256 |
@@ -1175,6 +1200,7 @@ struct rtl_ps_ctl { | |||
1175 | * otherwise Offset[560h] = 0x00. | 1200 | * otherwise Offset[560h] = 0x00. |
1176 | * */ | 1201 | * */ |
1177 | bool support_aspm; | 1202 | bool support_aspm; |
1203 | |||
1178 | bool support_backdoor; | 1204 | bool support_backdoor; |
1179 | 1205 | ||
1180 | /*for LPS */ | 1206 | /*for LPS */ |
@@ -1201,7 +1227,6 @@ struct rtl_ps_ctl { | |||
1201 | 1227 | ||
1202 | /*just for PCIE ASPM */ | 1228 | /*just for PCIE ASPM */ |
1203 | u8 const_amdpci_aspm; | 1229 | u8 const_amdpci_aspm; |
1204 | |||
1205 | bool pwrdown_mode; | 1230 | bool pwrdown_mode; |
1206 | 1231 | ||
1207 | enum rf_pwrstate inactive_pwrstate; | 1232 | enum rf_pwrstate inactive_pwrstate; |
@@ -1282,6 +1307,10 @@ struct rt_link_detect { | |||
1282 | bool busytraffic; | 1307 | bool busytraffic; |
1283 | bool higher_busytraffic; | 1308 | bool higher_busytraffic; |
1284 | bool higher_busyrxtraffic; | 1309 | bool higher_busyrxtraffic; |
1310 | |||
1311 | u32 tidtx_in4period[MAX_TID_COUNT][4]; | ||
1312 | u32 tidtx_inperiod[MAX_TID_COUNT]; | ||
1313 | bool higher_busytxtraffic[MAX_TID_COUNT]; | ||
1285 | }; | 1314 | }; |
1286 | 1315 | ||
1287 | struct rtl_tcb_desc { | 1316 | struct rtl_tcb_desc { |
@@ -1344,13 +1373,15 @@ struct rtl_hal_ops { | |||
1344 | u32 add_msr, u32 rm_msr); | 1373 | u32 add_msr, u32 rm_msr); |
1345 | void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); | 1374 | void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); |
1346 | void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); | 1375 | void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); |
1347 | void (*update_rate_table) (struct ieee80211_hw *hw); | 1376 | void (*update_rate_tbl) (struct ieee80211_hw *hw, |
1377 | struct ieee80211_sta *sta, u8 rssi_level); | ||
1348 | void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level); | 1378 | void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level); |
1349 | void (*fill_tx_desc) (struct ieee80211_hw *hw, | 1379 | void (*fill_tx_desc) (struct ieee80211_hw *hw, |
1350 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | 1380 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, |
1351 | struct ieee80211_tx_info *info, | 1381 | struct ieee80211_tx_info *info, |
1352 | struct sk_buff *skb, unsigned int queue_index); | 1382 | struct sk_buff *skb, u8 hw_queue, |
1353 | void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 * pDesc, | 1383 | struct rtl_tcb_desc *ptcb_desc); |
1384 | void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 *pDesc, | ||
1354 | u32 buffer_len, bool bIsPsPoll); | 1385 | u32 buffer_len, bool bIsPsPoll); |
1355 | void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, | 1386 | void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, |
1356 | bool firstseg, bool lastseg, | 1387 | bool firstseg, bool lastseg, |
@@ -1370,10 +1401,10 @@ struct rtl_hal_ops { | |||
1370 | enum led_ctl_mode ledaction); | 1401 | enum led_ctl_mode ledaction); |
1371 | void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val); | 1402 | void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val); |
1372 | u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name); | 1403 | u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name); |
1373 | void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue); | 1404 | void (*tx_polling) (struct ieee80211_hw *hw, u8 hw_queue); |
1374 | void (*enable_hw_sec) (struct ieee80211_hw *hw); | 1405 | void (*enable_hw_sec) (struct ieee80211_hw *hw); |
1375 | void (*set_key) (struct ieee80211_hw *hw, u32 key_index, | 1406 | void (*set_key) (struct ieee80211_hw *hw, u32 key_index, |
1376 | u8 *p_macaddr, bool is_group, u8 enc_algo, | 1407 | u8 *macaddr, bool is_group, u8 enc_algo, |
1377 | bool is_wepkey, bool clear_all); | 1408 | bool is_wepkey, bool clear_all); |
1378 | void (*init_sw_leds) (struct ieee80211_hw *hw); | 1409 | void (*init_sw_leds) (struct ieee80211_hw *hw); |
1379 | void (*deinit_sw_leds) (struct ieee80211_hw *hw); | 1410 | void (*deinit_sw_leds) (struct ieee80211_hw *hw); |
@@ -1384,6 +1415,7 @@ struct rtl_hal_ops { | |||
1384 | u32 regaddr, u32 bitmask); | 1415 | u32 regaddr, u32 bitmask); |
1385 | void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, | 1416 | void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, |
1386 | u32 regaddr, u32 bitmask, u32 data); | 1417 | u32 regaddr, u32 bitmask, u32 data); |
1418 | void (*linked_set_reg) (struct ieee80211_hw *hw); | ||
1387 | bool (*phy_rf6052_config) (struct ieee80211_hw *hw); | 1419 | bool (*phy_rf6052_config) (struct ieee80211_hw *hw); |
1388 | void (*phy_rf6052_set_cck_txpower) (struct ieee80211_hw *hw, | 1420 | void (*phy_rf6052_set_cck_txpower) (struct ieee80211_hw *hw, |
1389 | u8 *powerlevel); | 1421 | u8 *powerlevel); |
@@ -1404,7 +1436,9 @@ struct rtl_intf_ops { | |||
1404 | int (*adapter_start) (struct ieee80211_hw *hw); | 1436 | int (*adapter_start) (struct ieee80211_hw *hw); |
1405 | void (*adapter_stop) (struct ieee80211_hw *hw); | 1437 | void (*adapter_stop) (struct ieee80211_hw *hw); |
1406 | 1438 | ||
1407 | int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb); | 1439 | int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb, |
1440 | struct rtl_tcb_desc *ptcb_desc); | ||
1441 | void (*flush)(struct ieee80211_hw *hw, bool drop); | ||
1408 | int (*reset_trx_ring) (struct ieee80211_hw *hw); | 1442 | int (*reset_trx_ring) (struct ieee80211_hw *hw); |
1409 | bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb); | 1443 | bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb); |
1410 | 1444 | ||
@@ -1418,6 +1452,15 @@ struct rtl_intf_ops { | |||
1418 | struct rtl_mod_params { | 1452 | struct rtl_mod_params { |
1419 | /* default: 0 = using hardware encryption */ | 1453 | /* default: 0 = using hardware encryption */ |
1420 | int sw_crypto; | 1454 | int sw_crypto; |
1455 | |||
1456 | /* default: 1 = using no linked power save */ | ||
1457 | bool inactiveps; | ||
1458 | |||
1459 | /* default: 1 = using linked sw power save */ | ||
1460 | bool swctrl_lps; | ||
1461 | |||
1462 | /* default: 1 = using linked fw power save */ | ||
1463 | bool fwctrl_lps; | ||
1421 | }; | 1464 | }; |
1422 | 1465 | ||
1423 | struct rtl_hal_usbint_cfg { | 1466 | struct rtl_hal_usbint_cfg { |
@@ -1445,6 +1488,7 @@ struct rtl_hal_usbint_cfg { | |||
1445 | 1488 | ||
1446 | struct rtl_hal_cfg { | 1489 | struct rtl_hal_cfg { |
1447 | u8 bar_id; | 1490 | u8 bar_id; |
1491 | bool write_readback; | ||
1448 | char *name; | 1492 | char *name; |
1449 | char *fw_name; | 1493 | char *fw_name; |
1450 | struct rtl_hal_ops *ops; | 1494 | struct rtl_hal_ops *ops; |
@@ -1469,7 +1513,6 @@ struct rtl_locks { | |||
1469 | spinlock_t rf_lock; | 1513 | spinlock_t rf_lock; |
1470 | spinlock_t lps_lock; | 1514 | spinlock_t lps_lock; |
1471 | spinlock_t waitq_lock; | 1515 | spinlock_t waitq_lock; |
1472 | spinlock_t tx_urb_lock; | ||
1473 | 1516 | ||
1474 | /*Dual mac*/ | 1517 | /*Dual mac*/ |
1475 | spinlock_t cck_and_rw_pagea_lock; | 1518 | spinlock_t cck_and_rw_pagea_lock; |
@@ -1653,13 +1696,23 @@ struct bt_coexist_info { | |||
1653 | #define EF4BYTE(_val) \ | 1696 | #define EF4BYTE(_val) \ |
1654 | (le32_to_cpu(_val)) | 1697 | (le32_to_cpu(_val)) |
1655 | 1698 | ||
1699 | /* Read data from memory */ | ||
1700 | #define READEF1BYTE(_ptr) \ | ||
1701 | EF1BYTE(*((u8 *)(_ptr))) | ||
1656 | /* Read le16 data from memory and convert to host ordering */ | 1702 | /* Read le16 data from memory and convert to host ordering */ |
1657 | #define READEF2BYTE(_ptr) \ | 1703 | #define READEF2BYTE(_ptr) \ |
1658 | EF2BYTE(*((u16 *)(_ptr))) | 1704 | EF2BYTE(*((u16 *)(_ptr))) |
1705 | #define READEF4BYTE(_ptr) \ | ||
1706 | EF4BYTE(*((u32 *)(_ptr))) | ||
1659 | 1707 | ||
1708 | /* Write data to memory */ | ||
1709 | #define WRITEEF1BYTE(_ptr, _val) \ | ||
1710 | (*((u8 *)(_ptr))) = EF1BYTE(_val) | ||
1660 | /* Write le16 data to memory in host ordering */ | 1711 | /* Write le16 data to memory in host ordering */ |
1661 | #define WRITEEF2BYTE(_ptr, _val) \ | 1712 | #define WRITEEF2BYTE(_ptr, _val) \ |
1662 | (*((u16 *)(_ptr))) = EF2BYTE(_val) | 1713 | (*((u16 *)(_ptr))) = EF2BYTE(_val) |
1714 | #define WRITEEF4BYTE(_ptr, _val) \ | ||
1715 | (*((u16 *)(_ptr))) = EF2BYTE(_val) | ||
1663 | 1716 | ||
1664 | /* Create a bit mask | 1717 | /* Create a bit mask |
1665 | * Examples: | 1718 | * Examples: |
@@ -1698,6 +1751,25 @@ struct bt_coexist_info { | |||
1698 | #define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ | 1751 | #define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ |
1699 | (EF1BYTE(*((u8 *)(__pstart)))) | 1752 | (EF1BYTE(*((u8 *)(__pstart)))) |
1700 | 1753 | ||
1754 | /*Description: | ||
1755 | Translate subfield (continuous bits in little-endian) of 4-byte | ||
1756 | value to host byte ordering.*/ | ||
1757 | #define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ | ||
1758 | ( \ | ||
1759 | (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \ | ||
1760 | BIT_LEN_MASK_32(__bitlen) \ | ||
1761 | ) | ||
1762 | #define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ | ||
1763 | ( \ | ||
1764 | (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \ | ||
1765 | BIT_LEN_MASK_16(__bitlen) \ | ||
1766 | ) | ||
1767 | #define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ | ||
1768 | ( \ | ||
1769 | (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \ | ||
1770 | BIT_LEN_MASK_8(__bitlen) \ | ||
1771 | ) | ||
1772 | |||
1701 | /* Description: | 1773 | /* Description: |
1702 | * Mask subfield (continuous bits in little-endian) of 4-byte value | 1774 | * Mask subfield (continuous bits in little-endian) of 4-byte value |
1703 | * and return the result in 4-byte value in host byte ordering. | 1775 | * and return the result in 4-byte value in host byte ordering. |
@@ -1721,6 +1793,18 @@ struct bt_coexist_info { | |||
1721 | /* Description: | 1793 | /* Description: |
1722 | * Set subfield of little-endian 4-byte value to specified value. | 1794 | * Set subfield of little-endian 4-byte value to specified value. |
1723 | */ | 1795 | */ |
1796 | #define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \ | ||
1797 | *((u32 *)(__pstart)) = EF4BYTE \ | ||
1798 | ( \ | ||
1799 | LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \ | ||
1800 | ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \ | ||
1801 | ); | ||
1802 | #define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \ | ||
1803 | *((u16 *)(__pstart)) = EF2BYTE \ | ||
1804 | ( \ | ||
1805 | LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \ | ||
1806 | ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \ | ||
1807 | ); | ||
1724 | #define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \ | 1808 | #define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \ |
1725 | *((u8 *)(__pstart)) = EF1BYTE \ | 1809 | *((u8 *)(__pstart)) = EF1BYTE \ |
1726 | ( \ | 1810 | ( \ |
@@ -1728,12 +1812,16 @@ struct bt_coexist_info { | |||
1728 | ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \ | 1812 | ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \ |
1729 | ); | 1813 | ); |
1730 | 1814 | ||
1815 | #define N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \ | ||
1816 | (__value) : (((__value + __aligment - 1) / __aligment) * __aligment)) | ||
1817 | |||
1731 | /**************************************** | 1818 | /**************************************** |
1732 | mem access macro define end | 1819 | mem access macro define end |
1733 | ****************************************/ | 1820 | ****************************************/ |
1734 | 1821 | ||
1735 | #define byte(x, n) ((x >> (8 * n)) & 0xff) | 1822 | #define byte(x, n) ((x >> (8 * n)) & 0xff) |
1736 | 1823 | ||
1824 | #define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC) | ||
1737 | #define RTL_WATCH_DOG_TIME 2000 | 1825 | #define RTL_WATCH_DOG_TIME 2000 |
1738 | #define MSECS(t) msecs_to_jiffies(t) | 1826 | #define MSECS(t) msecs_to_jiffies(t) |
1739 | #define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS) | 1827 | #define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS) |
@@ -1768,6 +1856,15 @@ struct bt_coexist_info { | |||
1768 | #define container_of_dwork_rtl(x, y, z) \ | 1856 | #define container_of_dwork_rtl(x, y, z) \ |
1769 | container_of(container_of(x, struct delayed_work, work), y, z) | 1857 | container_of(container_of(x, struct delayed_work, work), y, z) |
1770 | 1858 | ||
1859 | #define FILL_OCTET_STRING(_os, _octet, _len) \ | ||
1860 | (_os).octet = (u8 *)(_octet); \ | ||
1861 | (_os).length = (_len); | ||
1862 | |||
1863 | #define CP_MACADDR(des, src) \ | ||
1864 | ((des)[0] = (src)[0], (des)[1] = (src)[1],\ | ||
1865 | (des)[2] = (src)[2], (des)[3] = (src)[3],\ | ||
1866 | (des)[4] = (src)[4], (des)[5] = (src)[5]) | ||
1867 | |||
1771 | static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) | 1868 | static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) |
1772 | { | 1869 | { |
1773 | return rtlpriv->io.read8_sync(rtlpriv, addr); | 1870 | return rtlpriv->io.read8_sync(rtlpriv, addr); |
@@ -1786,17 +1883,26 @@ static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr) | |||
1786 | static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8) | 1883 | static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8) |
1787 | { | 1884 | { |
1788 | rtlpriv->io.write8_async(rtlpriv, addr, val8); | 1885 | rtlpriv->io.write8_async(rtlpriv, addr, val8); |
1886 | |||
1887 | if (rtlpriv->cfg->write_readback) | ||
1888 | rtlpriv->io.read8_sync(rtlpriv, addr); | ||
1789 | } | 1889 | } |
1790 | 1890 | ||
1791 | static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16) | 1891 | static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16) |
1792 | { | 1892 | { |
1793 | rtlpriv->io.write16_async(rtlpriv, addr, val16); | 1893 | rtlpriv->io.write16_async(rtlpriv, addr, val16); |
1894 | |||
1895 | if (rtlpriv->cfg->write_readback) | ||
1896 | rtlpriv->io.read16_sync(rtlpriv, addr); | ||
1794 | } | 1897 | } |
1795 | 1898 | ||
1796 | static inline void rtl_write_dword(struct rtl_priv *rtlpriv, | 1899 | static inline void rtl_write_dword(struct rtl_priv *rtlpriv, |
1797 | u32 addr, u32 val32) | 1900 | u32 addr, u32 val32) |
1798 | { | 1901 | { |
1799 | rtlpriv->io.write32_async(rtlpriv, addr, val32); | 1902 | rtlpriv->io.write32_async(rtlpriv, addr, val32); |
1903 | |||
1904 | if (rtlpriv->cfg->write_readback) | ||
1905 | rtlpriv->io.read32_sync(rtlpriv, addr); | ||
1800 | } | 1906 | } |
1801 | 1907 | ||
1802 | static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw, | 1908 | static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw, |
@@ -1855,4 +1961,31 @@ static inline u8 get_rf_type(struct rtl_phy *rtlphy) | |||
1855 | return rtlphy->rf_type; | 1961 | return rtlphy->rf_type; |
1856 | } | 1962 | } |
1857 | 1963 | ||
1964 | static inline struct ieee80211_hdr *rtl_get_hdr(struct sk_buff *skb) | ||
1965 | { | ||
1966 | return (struct ieee80211_hdr *)(skb->data); | ||
1967 | } | ||
1968 | |||
1969 | static inline __le16 rtl_get_fc(struct sk_buff *skb) | ||
1970 | { | ||
1971 | return rtl_get_hdr(skb)->frame_control; | ||
1972 | } | ||
1973 | |||
1974 | static inline u16 rtl_get_tid_h(struct ieee80211_hdr *hdr) | ||
1975 | { | ||
1976 | return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
1977 | } | ||
1978 | |||
1979 | static inline u16 rtl_get_tid(struct sk_buff *skb) | ||
1980 | { | ||
1981 | return rtl_get_tid_h(rtl_get_hdr(skb)); | ||
1982 | } | ||
1983 | |||
1984 | static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw, | ||
1985 | struct ieee80211_vif *vif, | ||
1986 | u8 *bssid) | ||
1987 | { | ||
1988 | return ieee80211_find_sta(vif, bssid); | ||
1989 | } | ||
1990 | |||
1858 | #endif | 1991 | #endif |
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 692ebff38fc8..35ce7b0f4a60 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig | |||
@@ -3,7 +3,7 @@ menuconfig WL12XX_MENU | |||
3 | depends on MAC80211 && EXPERIMENTAL | 3 | depends on MAC80211 && EXPERIMENTAL |
4 | ---help--- | 4 | ---help--- |
5 | This will enable TI wl12xx driver support for the following chips: | 5 | This will enable TI wl12xx driver support for the following chips: |
6 | wl1271 and wl1273. | 6 | wl1271, wl1273, wl1281 and wl1283. |
7 | The drivers make use of the mac80211 stack. | 7 | The drivers make use of the mac80211 stack. |
8 | 8 | ||
9 | config WL12XX | 9 | config WL12XX |
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index a3db755ceeda..a5c9c0aff83f 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c | |||
@@ -965,10 +965,13 @@ int wl1271_acx_ap_mem_cfg(struct wl1271 *wl) | |||
965 | } | 965 | } |
966 | 966 | ||
967 | /* memory config */ | 967 | /* memory config */ |
968 | mem_conf->num_stations = wl->conf.mem.num_stations; | 968 | /* FIXME: for now we always use mem_wl127x for AP, because it |
969 | mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num; | 969 | * doesn't support dynamic memory and we don't have the |
970 | mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num; | 970 | * optimal values for wl128x without dynamic memory yet */ |
971 | mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles; | 971 | mem_conf->num_stations = wl->conf.mem_wl127x.num_stations; |
972 | mem_conf->rx_mem_block_num = wl->conf.mem_wl127x.rx_block_num; | ||
973 | mem_conf->tx_min_mem_block_num = wl->conf.mem_wl127x.tx_min_block_num; | ||
974 | mem_conf->num_ssid_profiles = wl->conf.mem_wl127x.ssid_profiles; | ||
972 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); | 975 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); |
973 | 976 | ||
974 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, | 977 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, |
@@ -986,6 +989,7 @@ out: | |||
986 | int wl1271_acx_sta_mem_cfg(struct wl1271 *wl) | 989 | int wl1271_acx_sta_mem_cfg(struct wl1271 *wl) |
987 | { | 990 | { |
988 | struct wl1271_acx_sta_config_memory *mem_conf; | 991 | struct wl1271_acx_sta_config_memory *mem_conf; |
992 | struct conf_memory_settings *mem; | ||
989 | int ret; | 993 | int ret; |
990 | 994 | ||
991 | wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); | 995 | wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); |
@@ -996,16 +1000,21 @@ int wl1271_acx_sta_mem_cfg(struct wl1271 *wl) | |||
996 | goto out; | 1000 | goto out; |
997 | } | 1001 | } |
998 | 1002 | ||
1003 | if (wl->chip.id == CHIP_ID_1283_PG20) | ||
1004 | mem = &wl->conf.mem_wl128x; | ||
1005 | else | ||
1006 | mem = &wl->conf.mem_wl127x; | ||
1007 | |||
999 | /* memory config */ | 1008 | /* memory config */ |
1000 | mem_conf->num_stations = wl->conf.mem.num_stations; | 1009 | mem_conf->num_stations = mem->num_stations; |
1001 | mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num; | 1010 | mem_conf->rx_mem_block_num = mem->rx_block_num; |
1002 | mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num; | 1011 | mem_conf->tx_min_mem_block_num = mem->tx_min_block_num; |
1003 | mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles; | 1012 | mem_conf->num_ssid_profiles = mem->ssid_profiles; |
1004 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); | 1013 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); |
1005 | mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory; | 1014 | mem_conf->dyn_mem_enable = mem->dynamic_memory; |
1006 | mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks; | 1015 | mem_conf->tx_free_req = mem->min_req_tx_blocks; |
1007 | mem_conf->rx_free_req = wl->conf.mem.min_req_rx_blocks; | 1016 | mem_conf->rx_free_req = mem->min_req_rx_blocks; |
1008 | mem_conf->tx_min = wl->conf.mem.tx_min; | 1017 | mem_conf->tx_min = mem->tx_min; |
1009 | 1018 | ||
1010 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, | 1019 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, |
1011 | sizeof(*mem_conf)); | 1020 | sizeof(*mem_conf)); |
@@ -1019,6 +1028,32 @@ out: | |||
1019 | return ret; | 1028 | return ret; |
1020 | } | 1029 | } |
1021 | 1030 | ||
1031 | int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap) | ||
1032 | { | ||
1033 | struct wl1271_acx_host_config_bitmap *bitmap_conf; | ||
1034 | int ret; | ||
1035 | |||
1036 | bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL); | ||
1037 | if (!bitmap_conf) { | ||
1038 | ret = -ENOMEM; | ||
1039 | goto out; | ||
1040 | } | ||
1041 | |||
1042 | bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap); | ||
1043 | |||
1044 | ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP, | ||
1045 | bitmap_conf, sizeof(*bitmap_conf)); | ||
1046 | if (ret < 0) { | ||
1047 | wl1271_warning("wl1271 bitmap config opt failed: %d", ret); | ||
1048 | goto out; | ||
1049 | } | ||
1050 | |||
1051 | out: | ||
1052 | kfree(bitmap_conf); | ||
1053 | |||
1054 | return ret; | ||
1055 | } | ||
1056 | |||
1022 | int wl1271_acx_init_mem_config(struct wl1271 *wl) | 1057 | int wl1271_acx_init_mem_config(struct wl1271 *wl) |
1023 | { | 1058 | { |
1024 | int ret; | 1059 | int ret; |
@@ -1489,22 +1524,46 @@ out: | |||
1489 | return ret; | 1524 | return ret; |
1490 | } | 1525 | } |
1491 | 1526 | ||
1492 | int wl1271_acx_max_tx_retry(struct wl1271 *wl) | 1527 | int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl) |
1493 | { | 1528 | { |
1494 | struct wl1271_acx_max_tx_retry *acx = NULL; | 1529 | struct wl1271_acx_ap_max_tx_retry *acx = NULL; |
1495 | int ret; | 1530 | int ret; |
1496 | 1531 | ||
1497 | wl1271_debug(DEBUG_ACX, "acx max tx retry"); | 1532 | wl1271_debug(DEBUG_ACX, "acx ap max tx retry"); |
1498 | 1533 | ||
1499 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | 1534 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); |
1500 | if (!acx) | 1535 | if (!acx) |
1501 | return -ENOMEM; | 1536 | return -ENOMEM; |
1502 | 1537 | ||
1503 | acx->max_tx_retry = cpu_to_le16(wl->conf.tx.ap_max_tx_retries); | 1538 | acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries); |
1504 | 1539 | ||
1505 | ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx)); | 1540 | ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx)); |
1506 | if (ret < 0) { | 1541 | if (ret < 0) { |
1507 | wl1271_warning("acx max tx retry failed: %d", ret); | 1542 | wl1271_warning("acx ap max tx retry failed: %d", ret); |
1543 | goto out; | ||
1544 | } | ||
1545 | |||
1546 | out: | ||
1547 | kfree(acx); | ||
1548 | return ret; | ||
1549 | } | ||
1550 | |||
1551 | int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl) | ||
1552 | { | ||
1553 | struct wl1271_acx_sta_max_tx_retry *acx = NULL; | ||
1554 | int ret; | ||
1555 | |||
1556 | wl1271_debug(DEBUG_ACX, "acx sta max tx retry"); | ||
1557 | |||
1558 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
1559 | if (!acx) | ||
1560 | return -ENOMEM; | ||
1561 | |||
1562 | acx->max_tx_retry = wl->conf.tx.max_tx_retries; | ||
1563 | |||
1564 | ret = wl1271_cmd_configure(wl, ACX_CONS_TX_FAILURE, acx, sizeof(*acx)); | ||
1565 | if (ret < 0) { | ||
1566 | wl1271_warning("acx sta max tx retry failed: %d", ret); | ||
1508 | goto out; | 1567 | goto out; |
1509 | } | 1568 | } |
1510 | 1569 | ||
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index dd19b01d807b..942908cd53a3 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h | |||
@@ -939,6 +939,16 @@ struct wl1271_acx_keep_alive_config { | |||
939 | u8 padding; | 939 | u8 padding; |
940 | } __packed; | 940 | } __packed; |
941 | 941 | ||
942 | #define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0) | ||
943 | #define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1) | ||
944 | #define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3) | ||
945 | |||
946 | struct wl1271_acx_host_config_bitmap { | ||
947 | struct acx_header header; | ||
948 | |||
949 | __le32 host_cfg_bitmap; | ||
950 | } __packed; | ||
951 | |||
942 | enum { | 952 | enum { |
943 | WL1271_ACX_TRIG_TYPE_LEVEL = 0, | 953 | WL1271_ACX_TRIG_TYPE_LEVEL = 0, |
944 | WL1271_ACX_TRIG_TYPE_EDGE, | 954 | WL1271_ACX_TRIG_TYPE_EDGE, |
@@ -1135,7 +1145,7 @@ struct wl1271_acx_fw_tsf_information { | |||
1135 | u8 padding[3]; | 1145 | u8 padding[3]; |
1136 | } __packed; | 1146 | } __packed; |
1137 | 1147 | ||
1138 | struct wl1271_acx_max_tx_retry { | 1148 | struct wl1271_acx_ap_max_tx_retry { |
1139 | struct acx_header header; | 1149 | struct acx_header header; |
1140 | 1150 | ||
1141 | /* | 1151 | /* |
@@ -1146,6 +1156,13 @@ struct wl1271_acx_max_tx_retry { | |||
1146 | u8 padding_1[2]; | 1156 | u8 padding_1[2]; |
1147 | } __packed; | 1157 | } __packed; |
1148 | 1158 | ||
1159 | struct wl1271_acx_sta_max_tx_retry { | ||
1160 | struct acx_header header; | ||
1161 | |||
1162 | u8 max_tx_retry; | ||
1163 | u8 padding_1[3]; | ||
1164 | } __packed; | ||
1165 | |||
1149 | struct wl1271_acx_config_ps { | 1166 | struct wl1271_acx_config_ps { |
1150 | struct acx_header header; | 1167 | struct acx_header header; |
1151 | 1168 | ||
@@ -1275,6 +1292,7 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl); | |||
1275 | int wl1271_acx_ap_mem_cfg(struct wl1271 *wl); | 1292 | int wl1271_acx_ap_mem_cfg(struct wl1271 *wl); |
1276 | int wl1271_acx_sta_mem_cfg(struct wl1271 *wl); | 1293 | int wl1271_acx_sta_mem_cfg(struct wl1271 *wl); |
1277 | int wl1271_acx_init_mem_config(struct wl1271 *wl); | 1294 | int wl1271_acx_init_mem_config(struct wl1271 *wl); |
1295 | int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap); | ||
1278 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); | 1296 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); |
1279 | int wl1271_acx_smart_reflex(struct wl1271 *wl); | 1297 | int wl1271_acx_smart_reflex(struct wl1271 *wl); |
1280 | int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); | 1298 | int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); |
@@ -1296,7 +1314,8 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl, | |||
1296 | int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, | 1314 | int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, |
1297 | bool enable); | 1315 | bool enable); |
1298 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); | 1316 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); |
1299 | int wl1271_acx_max_tx_retry(struct wl1271 *wl); | 1317 | int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl); |
1318 | int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl); | ||
1300 | int wl1271_acx_config_ps(struct wl1271 *wl); | 1319 | int wl1271_acx_config_ps(struct wl1271 *wl); |
1301 | int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); | 1320 | int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); |
1302 | 1321 | ||
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 6934dffd5174..d263ebb6f974 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c | |||
@@ -22,6 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/wl12xx.h> | ||
25 | 26 | ||
26 | #include "acx.h" | 27 | #include "acx.h" |
27 | #include "reg.h" | 28 | #include "reg.h" |
@@ -243,33 +244,57 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) | |||
243 | if (wl->nvs == NULL) | 244 | if (wl->nvs == NULL) |
244 | return -ENODEV; | 245 | return -ENODEV; |
245 | 246 | ||
246 | /* | 247 | if (wl->chip.id == CHIP_ID_1283_PG20) { |
247 | * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band | 248 | struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs; |
248 | * configurations) can be removed when those NVS files stop floating | 249 | |
249 | * around. | 250 | if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) { |
250 | */ | 251 | if (nvs->general_params.dual_mode_select) |
251 | if (wl->nvs_len == sizeof(struct wl1271_nvs_file) || | 252 | wl->enable_11a = true; |
252 | wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) { | 253 | } else { |
253 | /* for now 11a is unsupported in AP mode */ | 254 | wl1271_error("nvs size is not as expected: %zu != %zu", |
254 | if (wl->bss_type != BSS_TYPE_AP_BSS && | 255 | wl->nvs_len, |
255 | wl->nvs->general_params.dual_mode_select) | 256 | sizeof(struct wl128x_nvs_file)); |
256 | wl->enable_11a = true; | 257 | kfree(wl->nvs); |
257 | } | 258 | wl->nvs = NULL; |
259 | wl->nvs_len = 0; | ||
260 | return -EILSEQ; | ||
261 | } | ||
258 | 262 | ||
259 | if (wl->nvs_len != sizeof(struct wl1271_nvs_file) && | 263 | /* only the first part of the NVS needs to be uploaded */ |
260 | (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE || | 264 | nvs_len = sizeof(nvs->nvs); |
261 | wl->enable_11a)) { | 265 | nvs_ptr = (u8 *)nvs->nvs; |
262 | wl1271_error("nvs size is not as expected: %zu != %zu", | 266 | |
263 | wl->nvs_len, sizeof(struct wl1271_nvs_file)); | 267 | } else { |
264 | kfree(wl->nvs); | 268 | struct wl1271_nvs_file *nvs = |
265 | wl->nvs = NULL; | 269 | (struct wl1271_nvs_file *)wl->nvs; |
266 | wl->nvs_len = 0; | 270 | /* |
267 | return -EILSEQ; | 271 | * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz |
268 | } | 272 | * band configurations) can be removed when those NVS files stop |
273 | * floating around. | ||
274 | */ | ||
275 | if (wl->nvs_len == sizeof(struct wl1271_nvs_file) || | ||
276 | wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) { | ||
277 | /* for now 11a is unsupported in AP mode */ | ||
278 | if (wl->bss_type != BSS_TYPE_AP_BSS && | ||
279 | nvs->general_params.dual_mode_select) | ||
280 | wl->enable_11a = true; | ||
281 | } | ||
269 | 282 | ||
270 | /* only the first part of the NVS needs to be uploaded */ | 283 | if (wl->nvs_len != sizeof(struct wl1271_nvs_file) && |
271 | nvs_len = sizeof(wl->nvs->nvs); | 284 | (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE || |
272 | nvs_ptr = (u8 *)wl->nvs->nvs; | 285 | wl->enable_11a)) { |
286 | wl1271_error("nvs size is not as expected: %zu != %zu", | ||
287 | wl->nvs_len, sizeof(struct wl1271_nvs_file)); | ||
288 | kfree(wl->nvs); | ||
289 | wl->nvs = NULL; | ||
290 | wl->nvs_len = 0; | ||
291 | return -EILSEQ; | ||
292 | } | ||
293 | |||
294 | /* only the first part of the NVS needs to be uploaded */ | ||
295 | nvs_len = sizeof(nvs->nvs); | ||
296 | nvs_ptr = (u8 *) nvs->nvs; | ||
297 | } | ||
273 | 298 | ||
274 | /* update current MAC address to NVS */ | 299 | /* update current MAC address to NVS */ |
275 | nvs_ptr[11] = wl->mac_addr[0]; | 300 | nvs_ptr[11] = wl->mac_addr[0]; |
@@ -319,10 +344,13 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) | |||
319 | /* | 344 | /* |
320 | * We've reached the first zero length, the first NVS table | 345 | * We've reached the first zero length, the first NVS table |
321 | * is located at an aligned offset which is at least 7 bytes further. | 346 | * is located at an aligned offset which is at least 7 bytes further. |
347 | * NOTE: The wl->nvs->nvs element must be first, in order to | ||
348 | * simplify the casting, we assume it is at the beginning of | ||
349 | * the wl->nvs structure. | ||
322 | */ | 350 | */ |
323 | nvs_ptr = (u8 *)wl->nvs->nvs + | 351 | nvs_ptr = (u8 *)wl->nvs + |
324 | ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4); | 352 | ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4); |
325 | nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs; | 353 | nvs_len -= nvs_ptr - (u8 *)wl->nvs; |
326 | 354 | ||
327 | /* Now we must set the partition correctly */ | 355 | /* Now we must set the partition correctly */ |
328 | wl1271_set_partition(wl, &part_table[PART_WORK]); | 356 | wl1271_set_partition(wl, &part_table[PART_WORK]); |
@@ -450,10 +478,14 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) | |||
450 | DISCONNECT_EVENT_COMPLETE_ID | | 478 | DISCONNECT_EVENT_COMPLETE_ID | |
451 | RSSI_SNR_TRIGGER_0_EVENT_ID | | 479 | RSSI_SNR_TRIGGER_0_EVENT_ID | |
452 | PSPOLL_DELIVERY_FAILURE_EVENT_ID | | 480 | PSPOLL_DELIVERY_FAILURE_EVENT_ID | |
453 | SOFT_GEMINI_SENSE_EVENT_ID; | 481 | SOFT_GEMINI_SENSE_EVENT_ID | |
482 | MAX_TX_RETRY_EVENT_ID; | ||
454 | 483 | ||
455 | if (wl->bss_type == BSS_TYPE_AP_BSS) | 484 | if (wl->bss_type == BSS_TYPE_AP_BSS) |
456 | wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID; | 485 | wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID | |
486 | INACTIVE_STA_EVENT_ID; | ||
487 | else | ||
488 | wl->event_mask |= DUMMY_PACKET_EVENT_ID; | ||
457 | 489 | ||
458 | ret = wl1271_event_unmask(wl); | 490 | ret = wl1271_event_unmask(wl); |
459 | if (ret < 0) { | 491 | if (ret < 0) { |
@@ -493,24 +525,159 @@ static void wl1271_boot_hw_version(struct wl1271 *wl) | |||
493 | wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION; | 525 | wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION; |
494 | } | 526 | } |
495 | 527 | ||
496 | /* uploads NVS and firmware */ | 528 | static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl) |
497 | int wl1271_load_firmware(struct wl1271 *wl) | ||
498 | { | 529 | { |
499 | int ret = 0; | 530 | u16 spare_reg; |
500 | u32 tmp, clk, pause; | 531 | |
532 | /* Mask bits [2] & [8:4] in the sys_clk_cfg register */ | ||
533 | spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG); | ||
534 | if (spare_reg == 0xFFFF) | ||
535 | return -EFAULT; | ||
536 | spare_reg |= (BIT(3) | BIT(5) | BIT(6)); | ||
537 | wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg); | ||
538 | |||
539 | /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */ | ||
540 | wl1271_top_reg_write(wl, SYS_CLK_CFG_REG, | ||
541 | WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF); | ||
542 | |||
543 | /* Delay execution for 15msec, to let the HW settle */ | ||
544 | mdelay(15); | ||
545 | |||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | static bool wl128x_is_tcxo_valid(struct wl1271 *wl) | ||
550 | { | ||
551 | u16 tcxo_detection; | ||
552 | |||
553 | tcxo_detection = wl1271_top_reg_read(wl, TCXO_CLK_DETECT_REG); | ||
554 | if (tcxo_detection & TCXO_DET_FAILED) | ||
555 | return false; | ||
556 | |||
557 | return true; | ||
558 | } | ||
559 | |||
560 | static bool wl128x_is_fref_valid(struct wl1271 *wl) | ||
561 | { | ||
562 | u16 fref_detection; | ||
563 | |||
564 | fref_detection = wl1271_top_reg_read(wl, FREF_CLK_DETECT_REG); | ||
565 | if (fref_detection & FREF_CLK_DETECT_FAIL) | ||
566 | return false; | ||
567 | |||
568 | return true; | ||
569 | } | ||
570 | |||
571 | static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl) | ||
572 | { | ||
573 | wl1271_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL); | ||
574 | wl1271_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL); | ||
575 | wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL); | ||
576 | |||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) | ||
581 | { | ||
582 | u16 spare_reg; | ||
583 | u16 pll_config; | ||
584 | u8 input_freq; | ||
585 | |||
586 | /* Mask bits [3:1] in the sys_clk_cfg register */ | ||
587 | spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG); | ||
588 | if (spare_reg == 0xFFFF) | ||
589 | return -EFAULT; | ||
590 | spare_reg |= BIT(2); | ||
591 | wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg); | ||
592 | |||
593 | /* Handle special cases of the TCXO clock */ | ||
594 | if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 || | ||
595 | wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6) | ||
596 | return wl128x_manually_configure_mcs_pll(wl); | ||
597 | |||
598 | /* Set the input frequency according to the selected clock source */ | ||
599 | input_freq = (clk & 1) + 1; | ||
600 | |||
601 | pll_config = wl1271_top_reg_read(wl, MCS_PLL_CONFIG_REG); | ||
602 | if (pll_config == 0xFFFF) | ||
603 | return -EFAULT; | ||
604 | pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT); | ||
605 | pll_config |= MCS_PLL_ENABLE_HP; | ||
606 | wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | /* | ||
612 | * WL128x has two clocks input - TCXO and FREF. | ||
613 | * TCXO is the main clock of the device, while FREF is used to sync | ||
614 | * between the GPS and the cellular modem. | ||
615 | * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used | ||
616 | * as the WLAN/BT main clock. | ||
617 | */ | ||
618 | static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) | ||
619 | { | ||
620 | u16 sys_clk_cfg; | ||
621 | |||
622 | /* For XTAL-only modes, FREF will be used after switching from TCXO */ | ||
623 | if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL || | ||
624 | wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) { | ||
625 | if (!wl128x_switch_tcxo_to_fref(wl)) | ||
626 | return -EINVAL; | ||
627 | goto fref_clk; | ||
628 | } | ||
629 | |||
630 | /* Query the HW, to determine which clock source we should use */ | ||
631 | sys_clk_cfg = wl1271_top_reg_read(wl, SYS_CLK_CFG_REG); | ||
632 | if (sys_clk_cfg == 0xFFFF) | ||
633 | return -EINVAL; | ||
634 | if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF) | ||
635 | goto fref_clk; | ||
636 | |||
637 | /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */ | ||
638 | if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 || | ||
639 | wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) { | ||
640 | if (!wl128x_switch_tcxo_to_fref(wl)) | ||
641 | return -EINVAL; | ||
642 | goto fref_clk; | ||
643 | } | ||
644 | |||
645 | /* TCXO clock is selected */ | ||
646 | if (!wl128x_is_tcxo_valid(wl)) | ||
647 | return -EINVAL; | ||
648 | *selected_clock = wl->tcxo_clock; | ||
649 | goto config_mcs_pll; | ||
650 | |||
651 | fref_clk: | ||
652 | /* FREF clock is selected */ | ||
653 | if (!wl128x_is_fref_valid(wl)) | ||
654 | return -EINVAL; | ||
655 | *selected_clock = wl->ref_clock; | ||
656 | |||
657 | config_mcs_pll: | ||
658 | return wl128x_configure_mcs_pll(wl, *selected_clock); | ||
659 | } | ||
660 | |||
661 | static int wl127x_boot_clk(struct wl1271 *wl) | ||
662 | { | ||
663 | u32 pause; | ||
664 | u32 clk; | ||
501 | 665 | ||
502 | wl1271_boot_hw_version(wl); | 666 | wl1271_boot_hw_version(wl); |
503 | 667 | ||
504 | if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4) | 668 | if (wl->ref_clock == CONF_REF_CLK_19_2_E || |
669 | wl->ref_clock == CONF_REF_CLK_38_4_E || | ||
670 | wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL) | ||
505 | /* ref clk: 19.2/38.4/38.4-XTAL */ | 671 | /* ref clk: 19.2/38.4/38.4-XTAL */ |
506 | clk = 0x3; | 672 | clk = 0x3; |
507 | else if (wl->ref_clock == 1 || wl->ref_clock == 3) | 673 | else if (wl->ref_clock == CONF_REF_CLK_26_E || |
674 | wl->ref_clock == CONF_REF_CLK_52_E) | ||
508 | /* ref clk: 26/52 */ | 675 | /* ref clk: 26/52 */ |
509 | clk = 0x5; | 676 | clk = 0x5; |
510 | else | 677 | else |
511 | return -EINVAL; | 678 | return -EINVAL; |
512 | 679 | ||
513 | if (wl->ref_clock != 0) { | 680 | if (wl->ref_clock != CONF_REF_CLK_19_2_E) { |
514 | u16 val; | 681 | u16 val; |
515 | /* Set clock type (open drain) */ | 682 | /* Set clock type (open drain) */ |
516 | val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); | 683 | val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); |
@@ -540,6 +707,26 @@ int wl1271_load_firmware(struct wl1271 *wl) | |||
540 | pause |= WU_COUNTER_PAUSE_VAL; | 707 | pause |= WU_COUNTER_PAUSE_VAL; |
541 | wl1271_write32(wl, WU_COUNTER_PAUSE, pause); | 708 | wl1271_write32(wl, WU_COUNTER_PAUSE, pause); |
542 | 709 | ||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | /* uploads NVS and firmware */ | ||
714 | int wl1271_load_firmware(struct wl1271 *wl) | ||
715 | { | ||
716 | int ret = 0; | ||
717 | u32 tmp, clk; | ||
718 | int selected_clock = -1; | ||
719 | |||
720 | if (wl->chip.id == CHIP_ID_1283_PG20) { | ||
721 | ret = wl128x_boot_clk(wl, &selected_clock); | ||
722 | if (ret < 0) | ||
723 | goto out; | ||
724 | } else { | ||
725 | ret = wl127x_boot_clk(wl); | ||
726 | if (ret < 0) | ||
727 | goto out; | ||
728 | } | ||
729 | |||
543 | /* Continue the ELP wake up sequence */ | 730 | /* Continue the ELP wake up sequence */ |
544 | wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); | 731 | wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); |
545 | udelay(500); | 732 | udelay(500); |
@@ -555,7 +742,12 @@ int wl1271_load_firmware(struct wl1271 *wl) | |||
555 | 742 | ||
556 | wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); | 743 | wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); |
557 | 744 | ||
558 | clk |= (wl->ref_clock << 1) << 4; | 745 | if (wl->chip.id == CHIP_ID_1283_PG20) { |
746 | clk |= ((selected_clock & 0x3) << 1) << 4; | ||
747 | } else { | ||
748 | clk |= (wl->ref_clock << 1) << 4; | ||
749 | } | ||
750 | |||
559 | wl1271_write32(wl, DRPW_SCRATCH_START, clk); | 751 | wl1271_write32(wl, DRPW_SCRATCH_START, clk); |
560 | 752 | ||
561 | wl1271_set_partition(wl, &part_table[PART_WORK]); | 753 | wl1271_set_partition(wl, &part_table[PART_WORK]); |
@@ -585,16 +777,12 @@ int wl1271_load_firmware(struct wl1271 *wl) | |||
585 | /* 6. read the EEPROM parameters */ | 777 | /* 6. read the EEPROM parameters */ |
586 | tmp = wl1271_read32(wl, SCR_PAD2); | 778 | tmp = wl1271_read32(wl, SCR_PAD2); |
587 | 779 | ||
588 | ret = wl1271_boot_write_irq_polarity(wl); | ||
589 | if (ret < 0) | ||
590 | goto out; | ||
591 | |||
592 | wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, | ||
593 | WL1271_ACX_ALL_EVENTS_VECTOR); | ||
594 | |||
595 | /* WL1271: The reference driver skips steps 7 to 10 (jumps directly | 780 | /* WL1271: The reference driver skips steps 7 to 10 (jumps directly |
596 | * to upload_fw) */ | 781 | * to upload_fw) */ |
597 | 782 | ||
783 | if (wl->chip.id == CHIP_ID_1283_PG20) | ||
784 | wl1271_top_reg_write(wl, SDIO_IO_DS, wl->conf.hci_io_ds); | ||
785 | |||
598 | ret = wl1271_boot_upload_firmware(wl); | 786 | ret = wl1271_boot_upload_firmware(wl); |
599 | if (ret < 0) | 787 | if (ret < 0) |
600 | goto out; | 788 | goto out; |
@@ -618,6 +806,13 @@ int wl1271_boot(struct wl1271 *wl) | |||
618 | if (ret < 0) | 806 | if (ret < 0) |
619 | goto out; | 807 | goto out; |
620 | 808 | ||
809 | ret = wl1271_boot_write_irq_polarity(wl); | ||
810 | if (ret < 0) | ||
811 | goto out; | ||
812 | |||
813 | wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, | ||
814 | WL1271_ACX_ALL_EVENTS_VECTOR); | ||
815 | |||
621 | /* Enable firmware interrupts now */ | 816 | /* Enable firmware interrupts now */ |
622 | wl1271_boot_enable_interrupts(wl); | 817 | wl1271_boot_enable_interrupts(wl); |
623 | 818 | ||
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h index 17229b86fc71..e8f8255bbabe 100644 --- a/drivers/net/wireless/wl12xx/boot.h +++ b/drivers/net/wireless/wl12xx/boot.h | |||
@@ -74,4 +74,56 @@ struct wl1271_static_data { | |||
74 | #define FREF_CLK_POLARITY_BITS 0xfffff8ff | 74 | #define FREF_CLK_POLARITY_BITS 0xfffff8ff |
75 | #define CLK_REQ_OUTN_SEL 0x700 | 75 | #define CLK_REQ_OUTN_SEL 0x700 |
76 | 76 | ||
77 | /* PLL configuration algorithm for wl128x */ | ||
78 | #define SYS_CLK_CFG_REG 0x2200 | ||
79 | /* Bit[0] - 0-TCXO, 1-FREF */ | ||
80 | #define MCS_PLL_CLK_SEL_FREF BIT(0) | ||
81 | /* Bit[3:2] - 01-TCXO, 10-FREF */ | ||
82 | #define WL_CLK_REQ_TYPE_FREF BIT(3) | ||
83 | #define WL_CLK_REQ_TYPE_PG2 (BIT(3) | BIT(2)) | ||
84 | /* Bit[4] - 0-TCXO, 1-FREF */ | ||
85 | #define PRCM_CM_EN_MUX_WLAN_FREF BIT(4) | ||
86 | |||
87 | #define TCXO_ILOAD_INT_REG 0x2264 | ||
88 | #define TCXO_CLK_DETECT_REG 0x2266 | ||
89 | |||
90 | #define TCXO_DET_FAILED BIT(4) | ||
91 | |||
92 | #define FREF_ILOAD_INT_REG 0x2084 | ||
93 | #define FREF_CLK_DETECT_REG 0x2086 | ||
94 | #define FREF_CLK_DETECT_FAIL BIT(4) | ||
95 | |||
96 | /* Use this reg for masking during driver access */ | ||
97 | #define WL_SPARE_REG 0x2320 | ||
98 | #define WL_SPARE_VAL BIT(2) | ||
99 | /* Bit[6:5:3] - mask wl write SYS_CLK_CFG[8:5:2:4] */ | ||
100 | #define WL_SPARE_MASK_8526 (BIT(6) | BIT(5) | BIT(3)) | ||
101 | |||
102 | #define PLL_LOCK_COUNTERS_REG 0xD8C | ||
103 | #define PLL_LOCK_COUNTERS_COEX 0x0F | ||
104 | #define PLL_LOCK_COUNTERS_MCS 0xF0 | ||
105 | #define MCS_PLL_OVERRIDE_REG 0xD90 | ||
106 | #define MCS_PLL_CONFIG_REG 0xD92 | ||
107 | #define MCS_SEL_IN_FREQ_MASK 0x0070 | ||
108 | #define MCS_SEL_IN_FREQ_SHIFT 4 | ||
109 | #define MCS_PLL_CONFIG_REG_VAL 0x73 | ||
110 | #define MCS_PLL_ENABLE_HP (BIT(0) | BIT(1)) | ||
111 | |||
112 | #define MCS_PLL_M_REG 0xD94 | ||
113 | #define MCS_PLL_N_REG 0xD96 | ||
114 | #define MCS_PLL_M_REG_VAL 0xC8 | ||
115 | #define MCS_PLL_N_REG_VAL 0x07 | ||
116 | |||
117 | #define SDIO_IO_DS 0xd14 | ||
118 | |||
119 | /* SDIO/wSPI DS configuration values */ | ||
120 | enum { | ||
121 | HCI_IO_DS_8MA = 0, | ||
122 | HCI_IO_DS_4MA = 1, /* default */ | ||
123 | HCI_IO_DS_6MA = 2, | ||
124 | HCI_IO_DS_2MA = 3, | ||
125 | }; | ||
126 | |||
127 | /* end PLL configuration algorithm for wl128x */ | ||
128 | |||
77 | #endif | 129 | #endif |
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 96324336f936..69d24f35cd9a 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -110,7 +110,47 @@ out: | |||
110 | int wl1271_cmd_general_parms(struct wl1271 *wl) | 110 | int wl1271_cmd_general_parms(struct wl1271 *wl) |
111 | { | 111 | { |
112 | struct wl1271_general_parms_cmd *gen_parms; | 112 | struct wl1271_general_parms_cmd *gen_parms; |
113 | struct wl1271_ini_general_params *gp = &wl->nvs->general_params; | 113 | struct wl1271_ini_general_params *gp = |
114 | &((struct wl1271_nvs_file *)wl->nvs)->general_params; | ||
115 | bool answer = false; | ||
116 | int ret; | ||
117 | |||
118 | if (!wl->nvs) | ||
119 | return -ENODEV; | ||
120 | |||
121 | gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); | ||
122 | if (!gen_parms) | ||
123 | return -ENOMEM; | ||
124 | |||
125 | gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; | ||
126 | |||
127 | memcpy(&gen_parms->general_params, gp, sizeof(*gp)); | ||
128 | |||
129 | if (gp->tx_bip_fem_auto_detect) | ||
130 | answer = true; | ||
131 | |||
132 | ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); | ||
133 | if (ret < 0) { | ||
134 | wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); | ||
135 | goto out; | ||
136 | } | ||
137 | |||
138 | gp->tx_bip_fem_manufacturer = | ||
139 | gen_parms->general_params.tx_bip_fem_manufacturer; | ||
140 | |||
141 | wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", | ||
142 | answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); | ||
143 | |||
144 | out: | ||
145 | kfree(gen_parms); | ||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | int wl128x_cmd_general_parms(struct wl1271 *wl) | ||
150 | { | ||
151 | struct wl128x_general_parms_cmd *gen_parms; | ||
152 | struct wl128x_ini_general_params *gp = | ||
153 | &((struct wl128x_nvs_file *)wl->nvs)->general_params; | ||
114 | bool answer = false; | 154 | bool answer = false; |
115 | int ret; | 155 | int ret; |
116 | 156 | ||
@@ -147,8 +187,9 @@ out: | |||
147 | 187 | ||
148 | int wl1271_cmd_radio_parms(struct wl1271 *wl) | 188 | int wl1271_cmd_radio_parms(struct wl1271 *wl) |
149 | { | 189 | { |
190 | struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs; | ||
150 | struct wl1271_radio_parms_cmd *radio_parms; | 191 | struct wl1271_radio_parms_cmd *radio_parms; |
151 | struct wl1271_ini_general_params *gp = &wl->nvs->general_params; | 192 | struct wl1271_ini_general_params *gp = &nvs->general_params; |
152 | int ret; | 193 | int ret; |
153 | 194 | ||
154 | if (!wl->nvs) | 195 | if (!wl->nvs) |
@@ -161,18 +202,18 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) | |||
161 | radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; | 202 | radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; |
162 | 203 | ||
163 | /* 2.4GHz parameters */ | 204 | /* 2.4GHz parameters */ |
164 | memcpy(&radio_parms->static_params_2, &wl->nvs->stat_radio_params_2, | 205 | memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, |
165 | sizeof(struct wl1271_ini_band_params_2)); | 206 | sizeof(struct wl1271_ini_band_params_2)); |
166 | memcpy(&radio_parms->dyn_params_2, | 207 | memcpy(&radio_parms->dyn_params_2, |
167 | &wl->nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, | 208 | &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, |
168 | sizeof(struct wl1271_ini_fem_params_2)); | 209 | sizeof(struct wl1271_ini_fem_params_2)); |
169 | 210 | ||
170 | /* 5GHz parameters */ | 211 | /* 5GHz parameters */ |
171 | memcpy(&radio_parms->static_params_5, | 212 | memcpy(&radio_parms->static_params_5, |
172 | &wl->nvs->stat_radio_params_5, | 213 | &nvs->stat_radio_params_5, |
173 | sizeof(struct wl1271_ini_band_params_5)); | 214 | sizeof(struct wl1271_ini_band_params_5)); |
174 | memcpy(&radio_parms->dyn_params_5, | 215 | memcpy(&radio_parms->dyn_params_5, |
175 | &wl->nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, | 216 | &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, |
176 | sizeof(struct wl1271_ini_fem_params_5)); | 217 | sizeof(struct wl1271_ini_fem_params_5)); |
177 | 218 | ||
178 | wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", | 219 | wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", |
@@ -186,6 +227,50 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) | |||
186 | return ret; | 227 | return ret; |
187 | } | 228 | } |
188 | 229 | ||
230 | int wl128x_cmd_radio_parms(struct wl1271 *wl) | ||
231 | { | ||
232 | struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs; | ||
233 | struct wl128x_radio_parms_cmd *radio_parms; | ||
234 | struct wl128x_ini_general_params *gp = &nvs->general_params; | ||
235 | int ret; | ||
236 | |||
237 | if (!wl->nvs) | ||
238 | return -ENODEV; | ||
239 | |||
240 | radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); | ||
241 | if (!radio_parms) | ||
242 | return -ENOMEM; | ||
243 | |||
244 | radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; | ||
245 | |||
246 | /* 2.4GHz parameters */ | ||
247 | memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, | ||
248 | sizeof(struct wl128x_ini_band_params_2)); | ||
249 | memcpy(&radio_parms->dyn_params_2, | ||
250 | &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, | ||
251 | sizeof(struct wl128x_ini_fem_params_2)); | ||
252 | |||
253 | /* 5GHz parameters */ | ||
254 | memcpy(&radio_parms->static_params_5, | ||
255 | &nvs->stat_radio_params_5, | ||
256 | sizeof(struct wl128x_ini_band_params_5)); | ||
257 | memcpy(&radio_parms->dyn_params_5, | ||
258 | &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, | ||
259 | sizeof(struct wl128x_ini_fem_params_5)); | ||
260 | |||
261 | radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options; | ||
262 | |||
263 | wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", | ||
264 | radio_parms, sizeof(*radio_parms)); | ||
265 | |||
266 | ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0); | ||
267 | if (ret < 0) | ||
268 | wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed"); | ||
269 | |||
270 | kfree(radio_parms); | ||
271 | return ret; | ||
272 | } | ||
273 | |||
189 | int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) | 274 | int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) |
190 | { | 275 | { |
191 | struct wl1271_ext_radio_parms_cmd *ext_radio_parms; | 276 | struct wl1271_ext_radio_parms_cmd *ext_radio_parms; |
@@ -985,7 +1070,7 @@ int wl1271_cmd_start_bss(struct wl1271 *wl) | |||
985 | 1070 | ||
986 | memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN); | 1071 | memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN); |
987 | 1072 | ||
988 | cmd->aging_period = cpu_to_le16(WL1271_AP_DEF_INACTIV_SEC); | 1073 | cmd->aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); |
989 | cmd->bss_index = WL1271_AP_BSS_INDEX; | 1074 | cmd->bss_index = WL1271_AP_BSS_INDEX; |
990 | cmd->global_hlid = WL1271_AP_GLOBAL_HLID; | 1075 | cmd->global_hlid = WL1271_AP_GLOBAL_HLID; |
991 | cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID; | 1076 | cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID; |
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 54c12e71417e..5cac95d9480c 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h | |||
@@ -32,7 +32,9 @@ struct acx_header; | |||
32 | int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, | 32 | int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, |
33 | size_t res_len); | 33 | size_t res_len); |
34 | int wl1271_cmd_general_parms(struct wl1271 *wl); | 34 | int wl1271_cmd_general_parms(struct wl1271 *wl); |
35 | int wl128x_cmd_general_parms(struct wl1271 *wl); | ||
35 | int wl1271_cmd_radio_parms(struct wl1271 *wl); | 36 | int wl1271_cmd_radio_parms(struct wl1271 *wl); |
37 | int wl128x_cmd_radio_parms(struct wl1271 *wl); | ||
36 | int wl1271_cmd_ext_radio_parms(struct wl1271 *wl); | 38 | int wl1271_cmd_ext_radio_parms(struct wl1271 *wl); |
37 | int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type); | 39 | int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type); |
38 | int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); | 40 | int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); |
@@ -415,6 +417,21 @@ struct wl1271_general_parms_cmd { | |||
415 | u8 padding[3]; | 417 | u8 padding[3]; |
416 | } __packed; | 418 | } __packed; |
417 | 419 | ||
420 | struct wl128x_general_parms_cmd { | ||
421 | struct wl1271_cmd_header header; | ||
422 | |||
423 | struct wl1271_cmd_test_header test; | ||
424 | |||
425 | struct wl128x_ini_general_params general_params; | ||
426 | |||
427 | u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM]; | ||
428 | u8 sr_sen_n_p; | ||
429 | u8 sr_sen_n_p_gain; | ||
430 | u8 sr_sen_nrn; | ||
431 | u8 sr_sen_prn; | ||
432 | u8 padding[3]; | ||
433 | } __packed; | ||
434 | |||
418 | struct wl1271_radio_parms_cmd { | 435 | struct wl1271_radio_parms_cmd { |
419 | struct wl1271_cmd_header header; | 436 | struct wl1271_cmd_header header; |
420 | 437 | ||
@@ -431,6 +448,23 @@ struct wl1271_radio_parms_cmd { | |||
431 | u8 padding3[2]; | 448 | u8 padding3[2]; |
432 | } __packed; | 449 | } __packed; |
433 | 450 | ||
451 | struct wl128x_radio_parms_cmd { | ||
452 | struct wl1271_cmd_header header; | ||
453 | |||
454 | struct wl1271_cmd_test_header test; | ||
455 | |||
456 | /* Static radio parameters */ | ||
457 | struct wl128x_ini_band_params_2 static_params_2; | ||
458 | struct wl128x_ini_band_params_5 static_params_5; | ||
459 | |||
460 | u8 fem_vendor_and_options; | ||
461 | |||
462 | /* Dynamic radio parameters */ | ||
463 | struct wl128x_ini_fem_params_2 dyn_params_2; | ||
464 | u8 padding2; | ||
465 | struct wl128x_ini_fem_params_5 dyn_params_5; | ||
466 | } __packed; | ||
467 | |||
434 | struct wl1271_ext_radio_parms_cmd { | 468 | struct wl1271_ext_radio_parms_cmd { |
435 | struct wl1271_cmd_header header; | 469 | struct wl1271_cmd_header header; |
436 | 470 | ||
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 8a8323896eec..e3de91528de8 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h | |||
@@ -683,10 +683,18 @@ struct conf_tx_settings { | |||
683 | struct conf_tx_rate_class ap_bcst_conf; | 683 | struct conf_tx_rate_class ap_bcst_conf; |
684 | 684 | ||
685 | /* | 685 | /* |
686 | * AP-mode - allow this number of TX retries to a station before an | 686 | * Allow this number of TX retries to a connected station/AP before an |
687 | * event is triggered from FW. | 687 | * event is triggered from FW. |
688 | * In AP-mode the hlids of unreachable stations are given in the | ||
689 | * "sta_tx_retry_exceeded" member in the event mailbox. | ||
688 | */ | 690 | */ |
689 | u16 ap_max_tx_retries; | 691 | u8 max_tx_retries; |
692 | |||
693 | /* | ||
694 | * AP-mode - after this number of seconds a connected station is | ||
695 | * considered inactive. | ||
696 | */ | ||
697 | u16 ap_aging_period; | ||
690 | 698 | ||
691 | /* | 699 | /* |
692 | * Configuration for TID parameters. | 700 | * Configuration for TID parameters. |
@@ -1004,7 +1012,9 @@ enum { | |||
1004 | CONF_REF_CLK_19_2_E, | 1012 | CONF_REF_CLK_19_2_E, |
1005 | CONF_REF_CLK_26_E, | 1013 | CONF_REF_CLK_26_E, |
1006 | CONF_REF_CLK_38_4_E, | 1014 | CONF_REF_CLK_38_4_E, |
1007 | CONF_REF_CLK_52_E | 1015 | CONF_REF_CLK_52_E, |
1016 | CONF_REF_CLK_38_4_M_XTAL, | ||
1017 | CONF_REF_CLK_26_M_XTAL, | ||
1008 | }; | 1018 | }; |
1009 | 1019 | ||
1010 | enum single_dual_band_enum { | 1020 | enum single_dual_band_enum { |
@@ -1018,15 +1028,6 @@ enum single_dual_band_enum { | |||
1018 | #define CONF_NUMBER_OF_CHANNELS_2_4 14 | 1028 | #define CONF_NUMBER_OF_CHANNELS_2_4 14 |
1019 | #define CONF_NUMBER_OF_CHANNELS_5 35 | 1029 | #define CONF_NUMBER_OF_CHANNELS_5 35 |
1020 | 1030 | ||
1021 | struct conf_radio_parms { | ||
1022 | /* | ||
1023 | * FEM parameter set to use | ||
1024 | * | ||
1025 | * Range: 0 or 1 | ||
1026 | */ | ||
1027 | u8 fem; | ||
1028 | }; | ||
1029 | |||
1030 | struct conf_itrim_settings { | 1031 | struct conf_itrim_settings { |
1031 | /* enable dco itrim */ | 1032 | /* enable dco itrim */ |
1032 | u8 enable; | 1033 | u8 enable; |
@@ -1202,7 +1203,9 @@ struct conf_drv_settings { | |||
1202 | struct conf_scan_settings scan; | 1203 | struct conf_scan_settings scan; |
1203 | struct conf_rf_settings rf; | 1204 | struct conf_rf_settings rf; |
1204 | struct conf_ht_setting ht; | 1205 | struct conf_ht_setting ht; |
1205 | struct conf_memory_settings mem; | 1206 | struct conf_memory_settings mem_wl127x; |
1207 | struct conf_memory_settings mem_wl128x; | ||
1208 | u8 hci_io_ds; | ||
1206 | }; | 1209 | }; |
1207 | 1210 | ||
1208 | #endif | 1211 | #endif |
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index 8e75b09723b9..70ab1986788e 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c | |||
@@ -267,7 +267,7 @@ static ssize_t gpio_power_write(struct file *file, | |||
267 | } | 267 | } |
268 | buf[len] = '\0'; | 268 | buf[len] = '\0'; |
269 | 269 | ||
270 | ret = strict_strtoul(buf, 0, &value); | 270 | ret = kstrtoul(buf, 0, &value); |
271 | if (ret < 0) { | 271 | if (ret < 0) { |
272 | wl1271_warning("illegal value in gpio_power"); | 272 | wl1271_warning("illegal value in gpio_power"); |
273 | return -EINVAL; | 273 | return -EINVAL; |
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 1b170c5cc595..d7be3aec6fc3 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c | |||
@@ -33,6 +33,7 @@ void wl1271_pspoll_work(struct work_struct *work) | |||
33 | { | 33 | { |
34 | struct delayed_work *dwork; | 34 | struct delayed_work *dwork; |
35 | struct wl1271 *wl; | 35 | struct wl1271 *wl; |
36 | int ret; | ||
36 | 37 | ||
37 | dwork = container_of(work, struct delayed_work, work); | 38 | dwork = container_of(work, struct delayed_work, work); |
38 | wl = container_of(dwork, struct wl1271, pspoll_work); | 39 | wl = container_of(dwork, struct wl1271, pspoll_work); |
@@ -55,8 +56,13 @@ void wl1271_pspoll_work(struct work_struct *work) | |||
55 | * delivery failure occurred, and no-one changed state since, so | 56 | * delivery failure occurred, and no-one changed state since, so |
56 | * we should go back to powersave. | 57 | * we should go back to powersave. |
57 | */ | 58 | */ |
59 | ret = wl1271_ps_elp_wakeup(wl); | ||
60 | if (ret < 0) | ||
61 | goto out; | ||
62 | |||
58 | wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true); | 63 | wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true); |
59 | 64 | ||
65 | wl1271_ps_elp_sleep(wl); | ||
60 | out: | 66 | out: |
61 | mutex_unlock(&wl->mutex); | 67 | mutex_unlock(&wl->mutex); |
62 | }; | 68 | }; |
@@ -129,11 +135,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl, | |||
129 | 135 | ||
130 | /* enable beacon early termination */ | 136 | /* enable beacon early termination */ |
131 | ret = wl1271_acx_bet_enable(wl, true); | 137 | ret = wl1271_acx_bet_enable(wl, true); |
132 | if (ret < 0) | ||
133 | break; | ||
134 | |||
135 | /* go to extremely low power mode */ | ||
136 | wl1271_ps_elp_sleep(wl); | ||
137 | break; | 138 | break; |
138 | default: | 139 | default: |
139 | break; | 140 | break; |
@@ -173,6 +174,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
173 | u32 vector; | 174 | u32 vector; |
174 | bool beacon_loss = false; | 175 | bool beacon_loss = false; |
175 | bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); | 176 | bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); |
177 | bool disconnect_sta = false; | ||
178 | unsigned long sta_bitmap = 0; | ||
176 | 179 | ||
177 | wl1271_event_mbox_dump(mbox); | 180 | wl1271_event_mbox_dump(mbox); |
178 | 181 | ||
@@ -228,9 +231,60 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
228 | wl1271_event_rssi_trigger(wl, mbox); | 231 | wl1271_event_rssi_trigger(wl, mbox); |
229 | } | 232 | } |
230 | 233 | ||
234 | if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) { | ||
235 | wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); | ||
236 | if (wl->vif) | ||
237 | wl1271_tx_dummy_packet(wl); | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | * "TX retries exceeded" has a different meaning according to mode. | ||
242 | * In AP mode the offending station is disconnected. In STA mode we | ||
243 | * report connection loss. | ||
244 | */ | ||
245 | if (vector & MAX_TX_RETRY_EVENT_ID) { | ||
246 | wl1271_debug(DEBUG_EVENT, "MAX_TX_RETRY_EVENT_ID"); | ||
247 | if (is_ap) { | ||
248 | sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded); | ||
249 | disconnect_sta = true; | ||
250 | } else { | ||
251 | beacon_loss = true; | ||
252 | } | ||
253 | } | ||
254 | |||
255 | if ((vector & INACTIVE_STA_EVENT_ID) && is_ap) { | ||
256 | wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID"); | ||
257 | sta_bitmap |= le16_to_cpu(mbox->sta_aging_status); | ||
258 | disconnect_sta = true; | ||
259 | } | ||
260 | |||
231 | if (wl->vif && beacon_loss) | 261 | if (wl->vif && beacon_loss) |
232 | ieee80211_connection_loss(wl->vif); | 262 | ieee80211_connection_loss(wl->vif); |
233 | 263 | ||
264 | if (is_ap && disconnect_sta) { | ||
265 | u32 num_packets = wl->conf.tx.max_tx_retries; | ||
266 | struct ieee80211_sta *sta; | ||
267 | const u8 *addr; | ||
268 | int h; | ||
269 | |||
270 | for (h = find_first_bit(&sta_bitmap, AP_MAX_LINKS); | ||
271 | h < AP_MAX_LINKS; | ||
272 | h = find_next_bit(&sta_bitmap, AP_MAX_LINKS, h+1)) { | ||
273 | if (!wl1271_is_active_sta(wl, h)) | ||
274 | continue; | ||
275 | |||
276 | addr = wl->links[h].addr; | ||
277 | |||
278 | rcu_read_lock(); | ||
279 | sta = ieee80211_find_sta(wl->vif, addr); | ||
280 | if (sta) { | ||
281 | wl1271_debug(DEBUG_EVENT, "remove sta %d", h); | ||
282 | ieee80211_report_low_ack(sta, num_packets); | ||
283 | } | ||
284 | rcu_read_unlock(); | ||
285 | } | ||
286 | } | ||
287 | |||
234 | return 0; | 288 | return 0; |
235 | } | 289 | } |
236 | 290 | ||
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index 0e80886f3031..7ae5a0821241 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h | |||
@@ -58,10 +58,16 @@ enum { | |||
58 | CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17), | 58 | CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17), |
59 | BSS_LOSE_EVENT_ID = BIT(18), | 59 | BSS_LOSE_EVENT_ID = BIT(18), |
60 | REGAINED_BSS_EVENT_ID = BIT(19), | 60 | REGAINED_BSS_EVENT_ID = BIT(19), |
61 | ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20), | 61 | MAX_TX_RETRY_EVENT_ID = BIT(20), |
62 | STA_REMOVE_COMPLETE_EVENT_ID = BIT(21), /* AP */ | 62 | /* STA: dummy paket for dynamic mem blocks */ |
63 | DUMMY_PACKET_EVENT_ID = BIT(21), | ||
64 | /* AP: STA remove complete */ | ||
65 | STA_REMOVE_COMPLETE_EVENT_ID = BIT(21), | ||
63 | SOFT_GEMINI_SENSE_EVENT_ID = BIT(22), | 66 | SOFT_GEMINI_SENSE_EVENT_ID = BIT(22), |
67 | /* STA: SG prediction */ | ||
64 | SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23), | 68 | SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23), |
69 | /* AP: Inactive STA */ | ||
70 | INACTIVE_STA_EVENT_ID = BIT(23), | ||
65 | SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24), | 71 | SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24), |
66 | PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25), | 72 | PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25), |
67 | DBG_EVENT_ID = BIT(26), | 73 | DBG_EVENT_ID = BIT(26), |
@@ -116,7 +122,11 @@ struct event_mailbox { | |||
116 | 122 | ||
117 | /* AP FW only */ | 123 | /* AP FW only */ |
118 | u8 hlid_removed; | 124 | u8 hlid_removed; |
125 | |||
126 | /* a bitmap of hlids for stations that have been inactive too long */ | ||
119 | __le16 sta_aging_status; | 127 | __le16 sta_aging_status; |
128 | |||
129 | /* a bitmap of hlids for stations which didn't respond to TX */ | ||
120 | __le16 sta_tx_retry_exceeded; | 130 | __le16 sta_tx_retry_exceeded; |
121 | 131 | ||
122 | u8 reserved_5[24]; | 132 | u8 reserved_5[24]; |
@@ -127,4 +137,7 @@ void wl1271_event_mbox_config(struct wl1271 *wl); | |||
127 | int wl1271_event_handle(struct wl1271 *wl, u8 mbox); | 137 | int wl1271_event_handle(struct wl1271 *wl, u8 mbox); |
128 | void wl1271_pspoll_work(struct work_struct *work); | 138 | void wl1271_pspoll_work(struct work_struct *work); |
129 | 139 | ||
140 | /* Functions from main.c */ | ||
141 | bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid); | ||
142 | |||
130 | #endif | 143 | #endif |
diff --git a/drivers/net/wireless/wl12xx/ini.h b/drivers/net/wireless/wl12xx/ini.h index c330a2583dfd..1420c842b8f1 100644 --- a/drivers/net/wireless/wl12xx/ini.h +++ b/drivers/net/wireless/wl12xx/ini.h | |||
@@ -41,6 +41,28 @@ struct wl1271_ini_general_params { | |||
41 | u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM]; | 41 | u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM]; |
42 | } __packed; | 42 | } __packed; |
43 | 43 | ||
44 | #define WL128X_INI_MAX_SETTINGS_PARAM 4 | ||
45 | |||
46 | struct wl128x_ini_general_params { | ||
47 | u8 ref_clock; | ||
48 | u8 settling_time; | ||
49 | u8 clk_valid_on_wakeup; | ||
50 | u8 tcxo_ref_clock; | ||
51 | u8 tcxo_settling_time; | ||
52 | u8 tcxo_valid_on_wakeup; | ||
53 | u8 tcxo_ldo_voltage; | ||
54 | u8 xtal_itrim_val; | ||
55 | u8 platform_conf; | ||
56 | u8 dual_mode_select; | ||
57 | u8 tx_bip_fem_auto_detect; | ||
58 | u8 tx_bip_fem_manufacturer; | ||
59 | u8 general_settings[WL128X_INI_MAX_SETTINGS_PARAM]; | ||
60 | u8 sr_state; | ||
61 | u8 srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM]; | ||
62 | u8 srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM]; | ||
63 | u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM]; | ||
64 | } __packed; | ||
65 | |||
44 | #define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15 | 66 | #define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15 |
45 | 67 | ||
46 | struct wl1271_ini_band_params_2 { | 68 | struct wl1271_ini_band_params_2 { |
@@ -49,9 +71,16 @@ struct wl1271_ini_band_params_2 { | |||
49 | u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; | 71 | u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; |
50 | } __packed; | 72 | } __packed; |
51 | 73 | ||
52 | #define WL1271_INI_RATE_GROUP_COUNT 6 | ||
53 | #define WL1271_INI_CHANNEL_COUNT_2 14 | 74 | #define WL1271_INI_CHANNEL_COUNT_2 14 |
54 | 75 | ||
76 | struct wl128x_ini_band_params_2 { | ||
77 | u8 rx_trace_insertion_loss; | ||
78 | u8 tx_trace_loss[WL1271_INI_CHANNEL_COUNT_2]; | ||
79 | u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; | ||
80 | } __packed; | ||
81 | |||
82 | #define WL1271_INI_RATE_GROUP_COUNT 6 | ||
83 | |||
55 | struct wl1271_ini_fem_params_2 { | 84 | struct wl1271_ini_fem_params_2 { |
56 | __le16 tx_bip_ref_pd_voltage; | 85 | __le16 tx_bip_ref_pd_voltage; |
57 | u8 tx_bip_ref_power; | 86 | u8 tx_bip_ref_power; |
@@ -68,6 +97,28 @@ struct wl1271_ini_fem_params_2 { | |||
68 | u8 normal_to_degraded_high_thr; | 97 | u8 normal_to_degraded_high_thr; |
69 | } __packed; | 98 | } __packed; |
70 | 99 | ||
100 | #define WL128X_INI_RATE_GROUP_COUNT 7 | ||
101 | /* low and high temperatures */ | ||
102 | #define WL128X_INI_PD_VS_TEMPERATURE_RANGES 2 | ||
103 | |||
104 | struct wl128x_ini_fem_params_2 { | ||
105 | __le16 tx_bip_ref_pd_voltage; | ||
106 | u8 tx_bip_ref_power; | ||
107 | u8 tx_bip_ref_offset; | ||
108 | u8 tx_per_rate_pwr_limits_normal[WL128X_INI_RATE_GROUP_COUNT]; | ||
109 | u8 tx_per_rate_pwr_limits_degraded[WL128X_INI_RATE_GROUP_COUNT]; | ||
110 | u8 tx_per_rate_pwr_limits_extreme[WL128X_INI_RATE_GROUP_COUNT]; | ||
111 | u8 tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2]; | ||
112 | u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2]; | ||
113 | u8 tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT]; | ||
114 | u8 tx_ibias[WL128X_INI_RATE_GROUP_COUNT + 1]; | ||
115 | u8 tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_2]; | ||
116 | u8 tx_pd_vs_temperature[WL128X_INI_PD_VS_TEMPERATURE_RANGES]; | ||
117 | u8 rx_fem_insertion_loss; | ||
118 | u8 degraded_low_to_normal_thr; | ||
119 | u8 normal_to_degraded_high_thr; | ||
120 | } __packed; | ||
121 | |||
71 | #define WL1271_INI_CHANNEL_COUNT_5 35 | 122 | #define WL1271_INI_CHANNEL_COUNT_5 35 |
72 | #define WL1271_INI_SUB_BAND_COUNT_5 7 | 123 | #define WL1271_INI_SUB_BAND_COUNT_5 7 |
73 | 124 | ||
@@ -77,6 +128,12 @@ struct wl1271_ini_band_params_5 { | |||
77 | u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; | 128 | u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; |
78 | } __packed; | 129 | } __packed; |
79 | 130 | ||
131 | struct wl128x_ini_band_params_5 { | ||
132 | u8 rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; | ||
133 | u8 tx_trace_loss[WL1271_INI_CHANNEL_COUNT_5]; | ||
134 | u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; | ||
135 | } __packed; | ||
136 | |||
80 | struct wl1271_ini_fem_params_5 { | 137 | struct wl1271_ini_fem_params_5 { |
81 | __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5]; | 138 | __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5]; |
82 | u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5]; | 139 | u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5]; |
@@ -92,6 +149,23 @@ struct wl1271_ini_fem_params_5 { | |||
92 | u8 normal_to_degraded_high_thr; | 149 | u8 normal_to_degraded_high_thr; |
93 | } __packed; | 150 | } __packed; |
94 | 151 | ||
152 | struct wl128x_ini_fem_params_5 { | ||
153 | __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5]; | ||
154 | u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5]; | ||
155 | u8 tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5]; | ||
156 | u8 tx_per_rate_pwr_limits_normal[WL128X_INI_RATE_GROUP_COUNT]; | ||
157 | u8 tx_per_rate_pwr_limits_degraded[WL128X_INI_RATE_GROUP_COUNT]; | ||
158 | u8 tx_per_rate_pwr_limits_extreme[WL128X_INI_RATE_GROUP_COUNT]; | ||
159 | u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5]; | ||
160 | u8 tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT]; | ||
161 | u8 tx_ibias[WL128X_INI_RATE_GROUP_COUNT]; | ||
162 | u8 tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_5]; | ||
163 | u8 tx_pd_vs_temperature[WL1271_INI_SUB_BAND_COUNT_5 * | ||
164 | WL128X_INI_PD_VS_TEMPERATURE_RANGES]; | ||
165 | u8 rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; | ||
166 | u8 degraded_low_to_normal_thr; | ||
167 | u8 normal_to_degraded_high_thr; | ||
168 | } __packed; | ||
95 | 169 | ||
96 | /* NVS data structure */ | 170 | /* NVS data structure */ |
97 | #define WL1271_INI_NVS_SECTION_SIZE 468 | 171 | #define WL1271_INI_NVS_SECTION_SIZE 468 |
@@ -100,7 +174,7 @@ struct wl1271_ini_fem_params_5 { | |||
100 | #define WL1271_INI_LEGACY_NVS_FILE_SIZE 800 | 174 | #define WL1271_INI_LEGACY_NVS_FILE_SIZE 800 |
101 | 175 | ||
102 | struct wl1271_nvs_file { | 176 | struct wl1271_nvs_file { |
103 | /* NVS section */ | 177 | /* NVS section - must be first! */ |
104 | u8 nvs[WL1271_INI_NVS_SECTION_SIZE]; | 178 | u8 nvs[WL1271_INI_NVS_SECTION_SIZE]; |
105 | 179 | ||
106 | /* INI section */ | 180 | /* INI section */ |
@@ -120,4 +194,24 @@ struct wl1271_nvs_file { | |||
120 | } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; | 194 | } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; |
121 | } __packed; | 195 | } __packed; |
122 | 196 | ||
197 | struct wl128x_nvs_file { | ||
198 | /* NVS section - must be first! */ | ||
199 | u8 nvs[WL1271_INI_NVS_SECTION_SIZE]; | ||
200 | |||
201 | /* INI section */ | ||
202 | struct wl128x_ini_general_params general_params; | ||
203 | u8 fem_vendor_and_options; | ||
204 | struct wl128x_ini_band_params_2 stat_radio_params_2; | ||
205 | u8 padding2; | ||
206 | struct { | ||
207 | struct wl128x_ini_fem_params_2 params; | ||
208 | u8 padding; | ||
209 | } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; | ||
210 | struct wl128x_ini_band_params_5 stat_radio_params_5; | ||
211 | u8 padding3; | ||
212 | struct { | ||
213 | struct wl128x_ini_fem_params_5 params; | ||
214 | u8 padding; | ||
215 | } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; | ||
216 | } __packed; | ||
123 | #endif | 217 | #endif |
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 6072fe457135..ab3b1e21de29 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "cmd.h" | 31 | #include "cmd.h" |
32 | #include "reg.h" | 32 | #include "reg.h" |
33 | #include "tx.h" | 33 | #include "tx.h" |
34 | #include "io.h" | ||
34 | 35 | ||
35 | int wl1271_sta_init_templates_config(struct wl1271 *wl) | 36 | int wl1271_sta_init_templates_config(struct wl1271 *wl) |
36 | { | 37 | { |
@@ -321,9 +322,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl) | |||
321 | { | 322 | { |
322 | int ret; | 323 | int ret; |
323 | 324 | ||
324 | ret = wl1271_cmd_ext_radio_parms(wl); | 325 | if (wl->chip.id != CHIP_ID_1283_PG20) { |
325 | if (ret < 0) | 326 | ret = wl1271_cmd_ext_radio_parms(wl); |
326 | return ret; | 327 | if (ret < 0) |
328 | return ret; | ||
329 | } | ||
327 | 330 | ||
328 | /* PS config */ | 331 | /* PS config */ |
329 | ret = wl1271_acx_config_ps(wl); | 332 | ret = wl1271_acx_config_ps(wl); |
@@ -372,6 +375,10 @@ static int wl1271_sta_hw_init(struct wl1271 *wl) | |||
372 | if (ret < 0) | 375 | if (ret < 0) |
373 | return ret; | 376 | return ret; |
374 | 377 | ||
378 | ret = wl1271_acx_sta_max_tx_retry(wl); | ||
379 | if (ret < 0) | ||
380 | return ret; | ||
381 | |||
375 | ret = wl1271_acx_sta_mem_cfg(wl); | 382 | ret = wl1271_acx_sta_mem_cfg(wl); |
376 | if (ret < 0) | 383 | if (ret < 0) |
377 | return ret; | 384 | return ret; |
@@ -438,7 +445,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl) | |||
438 | if (ret < 0) | 445 | if (ret < 0) |
439 | return ret; | 446 | return ret; |
440 | 447 | ||
441 | ret = wl1271_acx_max_tx_retry(wl); | 448 | ret = wl1271_acx_ap_max_tx_retry(wl); |
442 | if (ret < 0) | 449 | if (ret < 0) |
443 | return ret; | 450 | return ret; |
444 | 451 | ||
@@ -504,6 +511,27 @@ static int wl1271_set_ba_policies(struct wl1271 *wl) | |||
504 | return ret; | 511 | return ret; |
505 | } | 512 | } |
506 | 513 | ||
514 | int wl1271_chip_specific_init(struct wl1271 *wl) | ||
515 | { | ||
516 | int ret = 0; | ||
517 | |||
518 | if (wl->chip.id == CHIP_ID_1283_PG20) { | ||
519 | u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE; | ||
520 | |||
521 | if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT) | ||
522 | /* Enable SDIO padding */ | ||
523 | host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; | ||
524 | |||
525 | /* Must be before wl1271_acx_init_mem_config() */ | ||
526 | ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap); | ||
527 | if (ret < 0) | ||
528 | goto out; | ||
529 | } | ||
530 | out: | ||
531 | return ret; | ||
532 | } | ||
533 | |||
534 | |||
507 | int wl1271_hw_init(struct wl1271 *wl) | 535 | int wl1271_hw_init(struct wl1271 *wl) |
508 | { | 536 | { |
509 | struct conf_tx_ac_category *conf_ac; | 537 | struct conf_tx_ac_category *conf_ac; |
@@ -511,11 +539,22 @@ int wl1271_hw_init(struct wl1271 *wl) | |||
511 | int ret, i; | 539 | int ret, i; |
512 | bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); | 540 | bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); |
513 | 541 | ||
514 | ret = wl1271_cmd_general_parms(wl); | 542 | if (wl->chip.id == CHIP_ID_1283_PG20) |
543 | ret = wl128x_cmd_general_parms(wl); | ||
544 | else | ||
545 | ret = wl1271_cmd_general_parms(wl); | ||
546 | if (ret < 0) | ||
547 | return ret; | ||
548 | |||
549 | if (wl->chip.id == CHIP_ID_1283_PG20) | ||
550 | ret = wl128x_cmd_radio_parms(wl); | ||
551 | else | ||
552 | ret = wl1271_cmd_radio_parms(wl); | ||
515 | if (ret < 0) | 553 | if (ret < 0) |
516 | return ret; | 554 | return ret; |
517 | 555 | ||
518 | ret = wl1271_cmd_radio_parms(wl); | 556 | /* Chip-specific init */ |
557 | ret = wl1271_chip_specific_init(wl); | ||
519 | if (ret < 0) | 558 | if (ret < 0) |
520 | return ret; | 559 | return ret; |
521 | 560 | ||
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h index 3a8bd3f426d2..4975270a91ab 100644 --- a/drivers/net/wireless/wl12xx/init.h +++ b/drivers/net/wireless/wl12xx/init.h | |||
@@ -31,6 +31,7 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl); | |||
31 | int wl1271_init_phy_config(struct wl1271 *wl); | 31 | int wl1271_init_phy_config(struct wl1271 *wl); |
32 | int wl1271_init_pta(struct wl1271 *wl); | 32 | int wl1271_init_pta(struct wl1271 *wl); |
33 | int wl1271_init_energy_detection(struct wl1271 *wl); | 33 | int wl1271_init_energy_detection(struct wl1271 *wl); |
34 | int wl1271_chip_specific_init(struct wl1271 *wl); | ||
34 | int wl1271_hw_init(struct wl1271 *wl); | 35 | int wl1271_hw_init(struct wl1271 *wl); |
35 | 36 | ||
36 | #endif | 37 | #endif |
diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c index d557f73e7c19..da5c1ad942a4 100644 --- a/drivers/net/wireless/wl12xx/io.c +++ b/drivers/net/wireless/wl12xx/io.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "wl12xx.h" | 29 | #include "wl12xx.h" |
30 | #include "wl12xx_80211.h" | 30 | #include "wl12xx_80211.h" |
31 | #include "io.h" | 31 | #include "io.h" |
32 | #include "tx.h" | ||
32 | 33 | ||
33 | #define OCP_CMD_LOOP 32 | 34 | #define OCP_CMD_LOOP 32 |
34 | 35 | ||
@@ -43,6 +44,16 @@ | |||
43 | #define OCP_STATUS_REQ_FAILED 0x20000 | 44 | #define OCP_STATUS_REQ_FAILED 0x20000 |
44 | #define OCP_STATUS_RESP_ERROR 0x30000 | 45 | #define OCP_STATUS_RESP_ERROR 0x30000 |
45 | 46 | ||
47 | bool wl1271_set_block_size(struct wl1271 *wl) | ||
48 | { | ||
49 | if (wl->if_ops->set_block_size) { | ||
50 | wl->if_ops->set_block_size(wl, WL12XX_BUS_BLOCK_SIZE); | ||
51 | return true; | ||
52 | } | ||
53 | |||
54 | return false; | ||
55 | } | ||
56 | |||
46 | void wl1271_disable_interrupts(struct wl1271 *wl) | 57 | void wl1271_disable_interrupts(struct wl1271 *wl) |
47 | { | 58 | { |
48 | wl->if_ops->disable_irq(wl); | 59 | wl->if_ops->disable_irq(wl); |
diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h index 00c771ea70bf..beed621a8ae0 100644 --- a/drivers/net/wireless/wl12xx/io.h +++ b/drivers/net/wireless/wl12xx/io.h | |||
@@ -169,5 +169,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl); | |||
169 | struct ieee80211_hw *wl1271_alloc_hw(void); | 169 | struct ieee80211_hw *wl1271_alloc_hw(void); |
170 | int wl1271_free_hw(struct wl1271 *wl); | 170 | int wl1271_free_hw(struct wl1271 *wl); |
171 | irqreturn_t wl1271_irq(int irq, void *data); | 171 | irqreturn_t wl1271_irq(int irq, void *data); |
172 | bool wl1271_set_block_size(struct wl1271 *wl); | ||
173 | int wl1271_tx_dummy_packet(struct wl1271 *wl); | ||
174 | void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters); | ||
172 | 175 | ||
173 | #endif | 176 | #endif |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8b3c8d196b03..0c69e959d0de 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/vmalloc.h> | 30 | #include <linux/vmalloc.h> |
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/wl12xx.h> | ||
33 | 34 | ||
34 | #include "wl12xx.h" | 35 | #include "wl12xx.h" |
35 | #include "wl12xx_80211.h" | 36 | #include "wl12xx_80211.h" |
@@ -54,7 +55,7 @@ static struct conf_drv_settings default_conf = { | |||
54 | [CONF_SG_BT_PER_THRESHOLD] = 7500, | 55 | [CONF_SG_BT_PER_THRESHOLD] = 7500, |
55 | [CONF_SG_HV3_MAX_OVERRIDE] = 0, | 56 | [CONF_SG_HV3_MAX_OVERRIDE] = 0, |
56 | [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400, | 57 | [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400, |
57 | [CONF_SG_BT_LOAD_RATIO] = 50, | 58 | [CONF_SG_BT_LOAD_RATIO] = 200, |
58 | [CONF_SG_AUTO_PS_MODE] = 1, | 59 | [CONF_SG_AUTO_PS_MODE] = 1, |
59 | [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, | 60 | [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, |
60 | [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, | 61 | [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, |
@@ -191,7 +192,8 @@ static struct conf_drv_settings default_conf = { | |||
191 | .long_retry_limit = 10, | 192 | .long_retry_limit = 10, |
192 | .aflags = 0, | 193 | .aflags = 0, |
193 | }, | 194 | }, |
194 | .ap_max_tx_retries = 100, | 195 | .max_tx_retries = 100, |
196 | .ap_aging_period = 300, | ||
195 | .tid_conf_count = 4, | 197 | .tid_conf_count = 4, |
196 | .tid_conf = { | 198 | .tid_conf = { |
197 | [CONF_TX_AC_BE] = { | 199 | [CONF_TX_AC_BE] = { |
@@ -254,7 +256,7 @@ static struct conf_drv_settings default_conf = { | |||
254 | .ps_poll_threshold = 10, | 256 | .ps_poll_threshold = 10, |
255 | .ps_poll_recovery_period = 700, | 257 | .ps_poll_recovery_period = 700, |
256 | .bet_enable = CONF_BET_MODE_ENABLE, | 258 | .bet_enable = CONF_BET_MODE_ENABLE, |
257 | .bet_max_consecutive = 10, | 259 | .bet_max_consecutive = 50, |
258 | .psm_entry_retries = 5, | 260 | .psm_entry_retries = 5, |
259 | .psm_exit_retries = 255, | 261 | .psm_exit_retries = 255, |
260 | .psm_entry_nullfunc_retries = 3, | 262 | .psm_entry_nullfunc_retries = 3, |
@@ -298,7 +300,7 @@ static struct conf_drv_settings default_conf = { | |||
298 | .tx_ba_win_size = 64, | 300 | .tx_ba_win_size = 64, |
299 | .inactivity_timeout = 10000, | 301 | .inactivity_timeout = 10000, |
300 | }, | 302 | }, |
301 | .mem = { | 303 | .mem_wl127x = { |
302 | .num_stations = 1, | 304 | .num_stations = 1, |
303 | .ssid_profiles = 1, | 305 | .ssid_profiles = 1, |
304 | .rx_block_num = 70, | 306 | .rx_block_num = 70, |
@@ -307,7 +309,18 @@ static struct conf_drv_settings default_conf = { | |||
307 | .min_req_tx_blocks = 100, | 309 | .min_req_tx_blocks = 100, |
308 | .min_req_rx_blocks = 22, | 310 | .min_req_rx_blocks = 22, |
309 | .tx_min = 27, | 311 | .tx_min = 27, |
310 | } | 312 | }, |
313 | .mem_wl128x = { | ||
314 | .num_stations = 1, | ||
315 | .ssid_profiles = 1, | ||
316 | .rx_block_num = 40, | ||
317 | .tx_min_block_num = 40, | ||
318 | .dynamic_memory = 1, | ||
319 | .min_req_tx_blocks = 45, | ||
320 | .min_req_rx_blocks = 22, | ||
321 | .tx_min = 27, | ||
322 | }, | ||
323 | .hci_io_ds = HCI_IO_DS_6MA, | ||
311 | }; | 324 | }; |
312 | 325 | ||
313 | static void __wl1271_op_remove_interface(struct wl1271 *wl); | 326 | static void __wl1271_op_remove_interface(struct wl1271 *wl); |
@@ -329,6 +342,7 @@ static struct platform_device wl1271_device = { | |||
329 | }, | 342 | }, |
330 | }; | 343 | }; |
331 | 344 | ||
345 | static DEFINE_MUTEX(wl_list_mutex); | ||
332 | static LIST_HEAD(wl_list); | 346 | static LIST_HEAD(wl_list); |
333 | 347 | ||
334 | static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, | 348 | static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, |
@@ -359,10 +373,12 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, | |||
359 | return NOTIFY_DONE; | 373 | return NOTIFY_DONE; |
360 | 374 | ||
361 | wl_temp = hw->priv; | 375 | wl_temp = hw->priv; |
376 | mutex_lock(&wl_list_mutex); | ||
362 | list_for_each_entry(wl, &wl_list, list) { | 377 | list_for_each_entry(wl, &wl_list, list) { |
363 | if (wl == wl_temp) | 378 | if (wl == wl_temp) |
364 | break; | 379 | break; |
365 | } | 380 | } |
381 | mutex_unlock(&wl_list_mutex); | ||
366 | if (wl != wl_temp) | 382 | if (wl != wl_temp) |
367 | return NOTIFY_DONE; | 383 | return NOTIFY_DONE; |
368 | 384 | ||
@@ -438,15 +454,30 @@ static int wl1271_plt_init(struct wl1271 *wl) | |||
438 | struct conf_tx_tid *conf_tid; | 454 | struct conf_tx_tid *conf_tid; |
439 | int ret, i; | 455 | int ret, i; |
440 | 456 | ||
441 | ret = wl1271_cmd_general_parms(wl); | 457 | if (wl->chip.id == CHIP_ID_1283_PG20) |
458 | ret = wl128x_cmd_general_parms(wl); | ||
459 | else | ||
460 | ret = wl1271_cmd_general_parms(wl); | ||
442 | if (ret < 0) | 461 | if (ret < 0) |
443 | return ret; | 462 | return ret; |
444 | 463 | ||
445 | ret = wl1271_cmd_radio_parms(wl); | 464 | if (wl->chip.id == CHIP_ID_1283_PG20) |
465 | ret = wl128x_cmd_radio_parms(wl); | ||
466 | else | ||
467 | ret = wl1271_cmd_radio_parms(wl); | ||
468 | if (ret < 0) | ||
469 | return ret; | ||
470 | |||
471 | if (wl->chip.id != CHIP_ID_1283_PG20) { | ||
472 | ret = wl1271_cmd_ext_radio_parms(wl); | ||
473 | if (ret < 0) | ||
474 | return ret; | ||
475 | } | ||
446 | if (ret < 0) | 476 | if (ret < 0) |
447 | return ret; | 477 | return ret; |
448 | 478 | ||
449 | ret = wl1271_cmd_ext_radio_parms(wl); | 479 | /* Chip-specific initializations */ |
480 | ret = wl1271_chip_specific_init(wl); | ||
450 | if (ret < 0) | 481 | if (ret < 0) |
451 | return ret; | 482 | return ret; |
452 | 483 | ||
@@ -593,15 +624,17 @@ static void wl1271_fw_status(struct wl1271 *wl, | |||
593 | { | 624 | { |
594 | struct wl1271_fw_common_status *status = &full_status->common; | 625 | struct wl1271_fw_common_status *status = &full_status->common; |
595 | struct timespec ts; | 626 | struct timespec ts; |
596 | u32 total = 0; | 627 | u32 old_tx_blk_count = wl->tx_blocks_available; |
628 | u32 freed_blocks = 0; | ||
597 | int i; | 629 | int i; |
598 | 630 | ||
599 | if (wl->bss_type == BSS_TYPE_AP_BSS) | 631 | if (wl->bss_type == BSS_TYPE_AP_BSS) { |
600 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, | 632 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, |
601 | sizeof(struct wl1271_fw_ap_status), false); | 633 | sizeof(struct wl1271_fw_ap_status), false); |
602 | else | 634 | } else { |
603 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, | 635 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, |
604 | sizeof(struct wl1271_fw_sta_status), false); | 636 | sizeof(struct wl1271_fw_sta_status), false); |
637 | } | ||
605 | 638 | ||
606 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " | 639 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " |
607 | "drv_rx_counter = %d, tx_results_counter = %d)", | 640 | "drv_rx_counter = %d, tx_results_counter = %d)", |
@@ -612,22 +645,37 @@ static void wl1271_fw_status(struct wl1271 *wl, | |||
612 | 645 | ||
613 | /* update number of available TX blocks */ | 646 | /* update number of available TX blocks */ |
614 | for (i = 0; i < NUM_TX_QUEUES; i++) { | 647 | for (i = 0; i < NUM_TX_QUEUES; i++) { |
615 | u32 cnt = le32_to_cpu(status->tx_released_blks[i]) - | 648 | freed_blocks += le32_to_cpu(status->tx_released_blks[i]) - |
616 | wl->tx_blocks_freed[i]; | 649 | wl->tx_blocks_freed[i]; |
617 | 650 | ||
618 | wl->tx_blocks_freed[i] = | 651 | wl->tx_blocks_freed[i] = |
619 | le32_to_cpu(status->tx_released_blks[i]); | 652 | le32_to_cpu(status->tx_released_blks[i]); |
620 | wl->tx_blocks_available += cnt; | ||
621 | total += cnt; | ||
622 | } | 653 | } |
623 | 654 | ||
624 | /* if more blocks are available now, tx work can be scheduled */ | 655 | wl->tx_allocated_blocks -= freed_blocks; |
625 | if (total) | ||
626 | clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); | ||
627 | 656 | ||
628 | /* for AP update num of allocated TX blocks per link and ps status */ | 657 | if (wl->bss_type == BSS_TYPE_AP_BSS) { |
629 | if (wl->bss_type == BSS_TYPE_AP_BSS) | 658 | /* Update num of allocated TX blocks per link and ps status */ |
630 | wl1271_irq_update_links_status(wl, &full_status->ap); | 659 | wl1271_irq_update_links_status(wl, &full_status->ap); |
660 | wl->tx_blocks_available += freed_blocks; | ||
661 | } else { | ||
662 | int avail = full_status->sta.tx_total - wl->tx_allocated_blocks; | ||
663 | |||
664 | /* | ||
665 | * The FW might change the total number of TX memblocks before | ||
666 | * we get a notification about blocks being released. Thus, the | ||
667 | * available blocks calculation might yield a temporary result | ||
668 | * which is lower than the actual available blocks. Keeping in | ||
669 | * mind that only blocks that were allocated can be moved from | ||
670 | * TX to RX, tx_blocks_available should never decrease here. | ||
671 | */ | ||
672 | wl->tx_blocks_available = max((int)wl->tx_blocks_available, | ||
673 | avail); | ||
674 | } | ||
675 | |||
676 | /* if more blocks are available now, tx work can be scheduled */ | ||
677 | if (wl->tx_blocks_available > old_tx_blk_count) | ||
678 | clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); | ||
631 | 679 | ||
632 | /* update the host-chipset time offset */ | 680 | /* update the host-chipset time offset */ |
633 | getnstimeofday(&ts); | 681 | getnstimeofday(&ts); |
@@ -674,6 +722,13 @@ irqreturn_t wl1271_irq(int irq, void *cookie) | |||
674 | set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); | 722 | set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); |
675 | cancel_work_sync(&wl->tx_work); | 723 | cancel_work_sync(&wl->tx_work); |
676 | 724 | ||
725 | /* | ||
726 | * In case edge triggered interrupt must be used, we cannot iterate | ||
727 | * more than once without introducing race conditions with the hardirq. | ||
728 | */ | ||
729 | if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) | ||
730 | loopcount = 1; | ||
731 | |||
677 | mutex_lock(&wl->mutex); | 732 | mutex_lock(&wl->mutex); |
678 | 733 | ||
679 | wl1271_debug(DEBUG_IRQ, "IRQ work"); | 734 | wl1271_debug(DEBUG_IRQ, "IRQ work"); |
@@ -785,11 +840,17 @@ static int wl1271_fetch_firmware(struct wl1271 *wl) | |||
785 | 840 | ||
786 | switch (wl->bss_type) { | 841 | switch (wl->bss_type) { |
787 | case BSS_TYPE_AP_BSS: | 842 | case BSS_TYPE_AP_BSS: |
788 | fw_name = WL1271_AP_FW_NAME; | 843 | if (wl->chip.id == CHIP_ID_1283_PG20) |
844 | fw_name = WL128X_AP_FW_NAME; | ||
845 | else | ||
846 | fw_name = WL127X_AP_FW_NAME; | ||
789 | break; | 847 | break; |
790 | case BSS_TYPE_IBSS: | 848 | case BSS_TYPE_IBSS: |
791 | case BSS_TYPE_STA_BSS: | 849 | case BSS_TYPE_STA_BSS: |
792 | fw_name = WL1271_FW_NAME; | 850 | if (wl->chip.id == CHIP_ID_1283_PG20) |
851 | fw_name = WL128X_FW_NAME; | ||
852 | else | ||
853 | fw_name = WL1271_FW_NAME; | ||
793 | break; | 854 | break; |
794 | default: | 855 | default: |
795 | wl1271_error("no compatible firmware for bss_type %d", | 856 | wl1271_error("no compatible firmware for bss_type %d", |
@@ -838,14 +899,14 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) | |||
838 | const struct firmware *fw; | 899 | const struct firmware *fw; |
839 | int ret; | 900 | int ret; |
840 | 901 | ||
841 | ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl)); | 902 | ret = request_firmware(&fw, WL12XX_NVS_NAME, wl1271_wl_to_dev(wl)); |
842 | 903 | ||
843 | if (ret < 0) { | 904 | if (ret < 0) { |
844 | wl1271_error("could not get nvs file: %d", ret); | 905 | wl1271_error("could not get nvs file: %d", ret); |
845 | return ret; | 906 | return ret; |
846 | } | 907 | } |
847 | 908 | ||
848 | wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); | 909 | wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL); |
849 | 910 | ||
850 | if (!wl->nvs) { | 911 | if (!wl->nvs) { |
851 | wl1271_error("could not allocate memory for the nvs file"); | 912 | wl1271_error("could not allocate memory for the nvs file"); |
@@ -954,6 +1015,17 @@ static int wl1271_chip_wakeup(struct wl1271 *wl) | |||
954 | if (ret < 0) | 1015 | if (ret < 0) |
955 | goto out; | 1016 | goto out; |
956 | break; | 1017 | break; |
1018 | case CHIP_ID_1283_PG20: | ||
1019 | wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)", | ||
1020 | wl->chip.id); | ||
1021 | |||
1022 | ret = wl1271_setup(wl); | ||
1023 | if (ret < 0) | ||
1024 | goto out; | ||
1025 | if (wl1271_set_block_size(wl)) | ||
1026 | wl->quirks |= WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT; | ||
1027 | break; | ||
1028 | case CHIP_ID_1283_PG10: | ||
957 | default: | 1029 | default: |
958 | wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); | 1030 | wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); |
959 | ret = -ENODEV; | 1031 | ret = -ENODEV; |
@@ -978,6 +1050,24 @@ out: | |||
978 | return ret; | 1050 | return ret; |
979 | } | 1051 | } |
980 | 1052 | ||
1053 | static unsigned int wl1271_get_fw_ver_quirks(struct wl1271 *wl) | ||
1054 | { | ||
1055 | unsigned int quirks = 0; | ||
1056 | unsigned int *fw_ver = wl->chip.fw_ver; | ||
1057 | |||
1058 | /* Only for wl127x */ | ||
1059 | if ((fw_ver[FW_VER_CHIP] == FW_VER_CHIP_WL127X) && | ||
1060 | /* Check STA version */ | ||
1061 | (((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) && | ||
1062 | (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_STA_MIN)) || | ||
1063 | /* Check AP version */ | ||
1064 | ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP) && | ||
1065 | (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_AP_MIN)))) | ||
1066 | quirks |= WL12XX_QUIRK_USE_2_SPARE_BLOCKS; | ||
1067 | |||
1068 | return quirks; | ||
1069 | } | ||
1070 | |||
981 | int wl1271_plt_start(struct wl1271 *wl) | 1071 | int wl1271_plt_start(struct wl1271 *wl) |
982 | { | 1072 | { |
983 | int retries = WL1271_BOOT_RETRIES; | 1073 | int retries = WL1271_BOOT_RETRIES; |
@@ -1013,6 +1103,9 @@ int wl1271_plt_start(struct wl1271 *wl) | |||
1013 | wl->state = WL1271_STATE_PLT; | 1103 | wl->state = WL1271_STATE_PLT; |
1014 | wl1271_notice("firmware booted in PLT mode (%s)", | 1104 | wl1271_notice("firmware booted in PLT mode (%s)", |
1015 | wl->chip.fw_ver_str); | 1105 | wl->chip.fw_ver_str); |
1106 | |||
1107 | /* Check if any quirks are needed with older fw versions */ | ||
1108 | wl->quirks |= wl1271_get_fw_ver_quirks(wl); | ||
1016 | goto out; | 1109 | goto out; |
1017 | 1110 | ||
1018 | irq_disable: | 1111 | irq_disable: |
@@ -1040,7 +1133,7 @@ out: | |||
1040 | return ret; | 1133 | return ret; |
1041 | } | 1134 | } |
1042 | 1135 | ||
1043 | int __wl1271_plt_stop(struct wl1271 *wl) | 1136 | static int __wl1271_plt_stop(struct wl1271 *wl) |
1044 | { | 1137 | { |
1045 | int ret = 0; | 1138 | int ret = 0; |
1046 | 1139 | ||
@@ -1124,6 +1217,69 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1124 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 1217 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
1125 | } | 1218 | } |
1126 | 1219 | ||
1220 | int wl1271_tx_dummy_packet(struct wl1271 *wl) | ||
1221 | { | ||
1222 | unsigned long flags; | ||
1223 | |||
1224 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
1225 | set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags); | ||
1226 | wl->tx_queue_count++; | ||
1227 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
1228 | |||
1229 | /* The FW is low on RX memory blocks, so send the dummy packet asap */ | ||
1230 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) | ||
1231 | wl1271_tx_work_locked(wl); | ||
1232 | |||
1233 | /* | ||
1234 | * If the FW TX is busy, TX work will be scheduled by the threaded | ||
1235 | * interrupt handler function | ||
1236 | */ | ||
1237 | return 0; | ||
1238 | } | ||
1239 | |||
1240 | /* | ||
1241 | * The size of the dummy packet should be at least 1400 bytes. However, in | ||
1242 | * order to minimize the number of bus transactions, aligning it to 512 bytes | ||
1243 | * boundaries could be beneficial, performance wise | ||
1244 | */ | ||
1245 | #define TOTAL_TX_DUMMY_PACKET_SIZE (ALIGN(1400, 512)) | ||
1246 | |||
1247 | static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl) | ||
1248 | { | ||
1249 | struct sk_buff *skb; | ||
1250 | struct ieee80211_hdr_3addr *hdr; | ||
1251 | unsigned int dummy_packet_size; | ||
1252 | |||
1253 | dummy_packet_size = TOTAL_TX_DUMMY_PACKET_SIZE - | ||
1254 | sizeof(struct wl1271_tx_hw_descr) - sizeof(*hdr); | ||
1255 | |||
1256 | skb = dev_alloc_skb(TOTAL_TX_DUMMY_PACKET_SIZE); | ||
1257 | if (!skb) { | ||
1258 | wl1271_warning("Failed to allocate a dummy packet skb"); | ||
1259 | return NULL; | ||
1260 | } | ||
1261 | |||
1262 | skb_reserve(skb, sizeof(struct wl1271_tx_hw_descr)); | ||
1263 | |||
1264 | hdr = (struct ieee80211_hdr_3addr *) skb_put(skb, sizeof(*hdr)); | ||
1265 | memset(hdr, 0, sizeof(*hdr)); | ||
1266 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
1267 | IEEE80211_STYPE_NULLFUNC | | ||
1268 | IEEE80211_FCTL_TODS); | ||
1269 | |||
1270 | memset(skb_put(skb, dummy_packet_size), 0, dummy_packet_size); | ||
1271 | |||
1272 | /* Dummy packets require the TID to be management */ | ||
1273 | skb->priority = WL1271_TID_MGMT; | ||
1274 | |||
1275 | /* Initialize all fields that might be used */ | ||
1276 | skb->queue_mapping = 0; | ||
1277 | memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info)); | ||
1278 | |||
1279 | return skb; | ||
1280 | } | ||
1281 | |||
1282 | |||
1127 | static struct notifier_block wl1271_dev_notifier = { | 1283 | static struct notifier_block wl1271_dev_notifier = { |
1128 | .notifier_call = wl1271_dev_notify, | 1284 | .notifier_call = wl1271_dev_notify, |
1129 | }; | 1285 | }; |
@@ -1174,6 +1330,16 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, | |||
1174 | goto out; | 1330 | goto out; |
1175 | } | 1331 | } |
1176 | 1332 | ||
1333 | /* | ||
1334 | * in some very corner case HW recovery scenarios its possible to | ||
1335 | * get here before __wl1271_op_remove_interface is complete, so | ||
1336 | * opt out if that is the case. | ||
1337 | */ | ||
1338 | if (test_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags)) { | ||
1339 | ret = -EBUSY; | ||
1340 | goto out; | ||
1341 | } | ||
1342 | |||
1177 | switch (vif->type) { | 1343 | switch (vif->type) { |
1178 | case NL80211_IFTYPE_STATION: | 1344 | case NL80211_IFTYPE_STATION: |
1179 | wl->bss_type = BSS_TYPE_STA_BSS; | 1345 | wl->bss_type = BSS_TYPE_STA_BSS; |
@@ -1242,6 +1408,7 @@ power_off: | |||
1242 | 1408 | ||
1243 | wl->vif = vif; | 1409 | wl->vif = vif; |
1244 | wl->state = WL1271_STATE_ON; | 1410 | wl->state = WL1271_STATE_ON; |
1411 | set_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags); | ||
1245 | wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str); | 1412 | wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str); |
1246 | 1413 | ||
1247 | /* update hw/fw version info in wiphy struct */ | 1414 | /* update hw/fw version info in wiphy struct */ |
@@ -1249,6 +1416,9 @@ power_off: | |||
1249 | strncpy(wiphy->fw_version, wl->chip.fw_ver_str, | 1416 | strncpy(wiphy->fw_version, wl->chip.fw_ver_str, |
1250 | sizeof(wiphy->fw_version)); | 1417 | sizeof(wiphy->fw_version)); |
1251 | 1418 | ||
1419 | /* Check if any quirks are needed with older fw versions */ | ||
1420 | wl->quirks |= wl1271_get_fw_ver_quirks(wl); | ||
1421 | |||
1252 | /* | 1422 | /* |
1253 | * Now we know if 11a is supported (info from the NVS), so disable | 1423 | * Now we know if 11a is supported (info from the NVS), so disable |
1254 | * 11a channels if not supported | 1424 | * 11a channels if not supported |
@@ -1262,8 +1432,10 @@ power_off: | |||
1262 | out: | 1432 | out: |
1263 | mutex_unlock(&wl->mutex); | 1433 | mutex_unlock(&wl->mutex); |
1264 | 1434 | ||
1435 | mutex_lock(&wl_list_mutex); | ||
1265 | if (!ret) | 1436 | if (!ret) |
1266 | list_add(&wl->list, &wl_list); | 1437 | list_add(&wl->list, &wl_list); |
1438 | mutex_unlock(&wl_list_mutex); | ||
1267 | 1439 | ||
1268 | return ret; | 1440 | return ret; |
1269 | } | 1441 | } |
@@ -1274,11 +1446,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
1274 | 1446 | ||
1275 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); | 1447 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); |
1276 | 1448 | ||
1449 | /* because of hardware recovery, we may get here twice */ | ||
1450 | if (wl->state != WL1271_STATE_ON) | ||
1451 | return; | ||
1452 | |||
1277 | wl1271_info("down"); | 1453 | wl1271_info("down"); |
1278 | 1454 | ||
1455 | mutex_lock(&wl_list_mutex); | ||
1279 | list_del(&wl->list); | 1456 | list_del(&wl->list); |
1280 | 1457 | mutex_unlock(&wl_list_mutex); | |
1281 | WARN_ON(wl->state != WL1271_STATE_ON); | ||
1282 | 1458 | ||
1283 | /* enable dyn ps just in case (if left on due to fw crash etc) */ | 1459 | /* enable dyn ps just in case (if left on due to fw crash etc) */ |
1284 | if (wl->bss_type == BSS_TYPE_STA_BSS) | 1460 | if (wl->bss_type == BSS_TYPE_STA_BSS) |
@@ -1286,12 +1462,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
1286 | 1462 | ||
1287 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { | 1463 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { |
1288 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 1464 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
1289 | kfree(wl->scan.scanned_ch); | 1465 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); |
1290 | wl->scan.scanned_ch = NULL; | ||
1291 | wl->scan.req = NULL; | 1466 | wl->scan.req = NULL; |
1292 | ieee80211_scan_completed(wl->hw, true); | 1467 | ieee80211_scan_completed(wl->hw, true); |
1293 | } | 1468 | } |
1294 | 1469 | ||
1470 | /* | ||
1471 | * this must be before the cancel_work calls below, so that the work | ||
1472 | * functions don't perform further work. | ||
1473 | */ | ||
1295 | wl->state = WL1271_STATE_OFF; | 1474 | wl->state = WL1271_STATE_OFF; |
1296 | 1475 | ||
1297 | mutex_unlock(&wl->mutex); | 1476 | mutex_unlock(&wl->mutex); |
@@ -1321,6 +1500,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
1321 | wl->psm_entry_retry = 0; | 1500 | wl->psm_entry_retry = 0; |
1322 | wl->power_level = WL1271_DEFAULT_POWER_LEVEL; | 1501 | wl->power_level = WL1271_DEFAULT_POWER_LEVEL; |
1323 | wl->tx_blocks_available = 0; | 1502 | wl->tx_blocks_available = 0; |
1503 | wl->tx_allocated_blocks = 0; | ||
1324 | wl->tx_results_count = 0; | 1504 | wl->tx_results_count = 0; |
1325 | wl->tx_packets_count = 0; | 1505 | wl->tx_packets_count = 0; |
1326 | wl->tx_security_last_seq = 0; | 1506 | wl->tx_security_last_seq = 0; |
@@ -1328,7 +1508,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
1328 | wl->time_offset = 0; | 1508 | wl->time_offset = 0; |
1329 | wl->session_counter = 0; | 1509 | wl->session_counter = 0; |
1330 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; | 1510 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; |
1331 | wl->flags = 0; | ||
1332 | wl->vif = NULL; | 1511 | wl->vif = NULL; |
1333 | wl->filters = 0; | 1512 | wl->filters = 0; |
1334 | wl1271_free_ap_keys(wl); | 1513 | wl1271_free_ap_keys(wl); |
@@ -1336,6 +1515,13 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
1336 | wl->ap_fw_ps_map = 0; | 1515 | wl->ap_fw_ps_map = 0; |
1337 | wl->ap_ps_map = 0; | 1516 | wl->ap_ps_map = 0; |
1338 | 1517 | ||
1518 | /* | ||
1519 | * this is performed after the cancel_work calls and the associated | ||
1520 | * mutex_lock, so that wl1271_op_add_interface does not accidentally | ||
1521 | * get executed before all these vars have been reset. | ||
1522 | */ | ||
1523 | wl->flags = 0; | ||
1524 | |||
1339 | for (i = 0; i < NUM_TX_QUEUES; i++) | 1525 | for (i = 0; i < NUM_TX_QUEUES; i++) |
1340 | wl->tx_blocks_freed[i] = 0; | 1526 | wl->tx_blocks_freed[i] = 0; |
1341 | 1527 | ||
@@ -1368,7 +1554,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, | |||
1368 | cancel_work_sync(&wl->recovery_work); | 1554 | cancel_work_sync(&wl->recovery_work); |
1369 | } | 1555 | } |
1370 | 1556 | ||
1371 | static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) | 1557 | void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) |
1372 | { | 1558 | { |
1373 | wl1271_set_default_filters(wl); | 1559 | wl1271_set_default_filters(wl); |
1374 | 1560 | ||
@@ -1431,10 +1617,10 @@ static int wl1271_join(struct wl1271 *wl, bool set_assoc) | |||
1431 | * One of the side effects of the JOIN command is that is clears | 1617 | * One of the side effects of the JOIN command is that is clears |
1432 | * WPA/WPA2 keys from the chipset. Performing a JOIN while associated | 1618 | * WPA/WPA2 keys from the chipset. Performing a JOIN while associated |
1433 | * to a WPA/WPA2 access point will therefore kill the data-path. | 1619 | * to a WPA/WPA2 access point will therefore kill the data-path. |
1434 | * Currently there is no supported scenario for JOIN during | 1620 | * Currently the only valid scenario for JOIN during association |
1435 | * association - if it becomes a supported scenario, the WPA/WPA2 keys | 1621 | * is on roaming, in which case we will also be given new keys. |
1436 | * must be handled somehow. | 1622 | * Keep the below message for now, unless it starts bothering |
1437 | * | 1623 | * users who really like to roam a lot :) |
1438 | */ | 1624 | */ |
1439 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | 1625 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) |
1440 | wl1271_info("JOIN while associated."); | 1626 | wl1271_info("JOIN while associated."); |
@@ -1490,7 +1676,7 @@ static int wl1271_unjoin(struct wl1271 *wl) | |||
1490 | clear_bit(WL1271_FLAG_JOINED, &wl->flags); | 1676 | clear_bit(WL1271_FLAG_JOINED, &wl->flags); |
1491 | memset(wl->bssid, 0, ETH_ALEN); | 1677 | memset(wl->bssid, 0, ETH_ALEN); |
1492 | 1678 | ||
1493 | /* stop filterting packets based on bssid */ | 1679 | /* stop filtering packets based on bssid */ |
1494 | wl1271_configure_filters(wl, FIF_OTHER_BSS); | 1680 | wl1271_configure_filters(wl, FIF_OTHER_BSS); |
1495 | 1681 | ||
1496 | out: | 1682 | out: |
@@ -1569,7 +1755,12 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1569 | mutex_lock(&wl->mutex); | 1755 | mutex_lock(&wl->mutex); |
1570 | 1756 | ||
1571 | if (unlikely(wl->state == WL1271_STATE_OFF)) { | 1757 | if (unlikely(wl->state == WL1271_STATE_OFF)) { |
1572 | ret = -EAGAIN; | 1758 | /* we support configuring the channel and band while off */ |
1759 | if ((changed & IEEE80211_CONF_CHANGE_CHANNEL)) { | ||
1760 | wl->band = conf->channel->band; | ||
1761 | wl->channel = channel; | ||
1762 | } | ||
1763 | |||
1573 | goto out; | 1764 | goto out; |
1574 | } | 1765 | } |
1575 | 1766 | ||
@@ -2650,32 +2841,31 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2650 | conf_tid->ack_policy = CONF_ACK_POLICY_LEGACY; | 2841 | conf_tid->ack_policy = CONF_ACK_POLICY_LEGACY; |
2651 | conf_tid->apsd_conf[0] = 0; | 2842 | conf_tid->apsd_conf[0] = 0; |
2652 | conf_tid->apsd_conf[1] = 0; | 2843 | conf_tid->apsd_conf[1] = 0; |
2653 | } else { | 2844 | goto out; |
2654 | ret = wl1271_ps_elp_wakeup(wl); | 2845 | } |
2655 | if (ret < 0) | ||
2656 | goto out; | ||
2657 | 2846 | ||
2658 | /* | 2847 | ret = wl1271_ps_elp_wakeup(wl); |
2659 | * the txop is confed in units of 32us by the mac80211, | 2848 | if (ret < 0) |
2660 | * we need us | 2849 | goto out; |
2661 | */ | ||
2662 | ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), | ||
2663 | params->cw_min, params->cw_max, | ||
2664 | params->aifs, params->txop << 5); | ||
2665 | if (ret < 0) | ||
2666 | goto out_sleep; | ||
2667 | 2850 | ||
2668 | ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), | 2851 | /* |
2669 | CONF_CHANNEL_TYPE_EDCF, | 2852 | * the txop is confed in units of 32us by the mac80211, |
2670 | wl1271_tx_get_queue(queue), | 2853 | * we need us |
2671 | ps_scheme, CONF_ACK_POLICY_LEGACY, | 2854 | */ |
2672 | 0, 0); | 2855 | ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), |
2673 | if (ret < 0) | 2856 | params->cw_min, params->cw_max, |
2674 | goto out_sleep; | 2857 | params->aifs, params->txop << 5); |
2858 | if (ret < 0) | ||
2859 | goto out_sleep; | ||
2860 | |||
2861 | ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), | ||
2862 | CONF_CHANNEL_TYPE_EDCF, | ||
2863 | wl1271_tx_get_queue(queue), | ||
2864 | ps_scheme, CONF_ACK_POLICY_LEGACY, | ||
2865 | 0, 0); | ||
2675 | 2866 | ||
2676 | out_sleep: | 2867 | out_sleep: |
2677 | wl1271_ps_elp_sleep(wl); | 2868 | wl1271_ps_elp_sleep(wl); |
2678 | } | ||
2679 | 2869 | ||
2680 | out: | 2870 | out: |
2681 | mutex_unlock(&wl->mutex); | 2871 | mutex_unlock(&wl->mutex); |
@@ -2764,6 +2954,12 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid) | |||
2764 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); | 2954 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); |
2765 | } | 2955 | } |
2766 | 2956 | ||
2957 | bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid) | ||
2958 | { | ||
2959 | int id = hlid - WL1271_AP_STA_HLID_START; | ||
2960 | return test_bit(id, wl->ap_hlid_map); | ||
2961 | } | ||
2962 | |||
2767 | static int wl1271_op_sta_add(struct ieee80211_hw *hw, | 2963 | static int wl1271_op_sta_add(struct ieee80211_hw *hw, |
2768 | struct ieee80211_vif *vif, | 2964 | struct ieee80211_vif *vif, |
2769 | struct ieee80211_sta *sta) | 2965 | struct ieee80211_sta *sta) |
@@ -2847,10 +3043,11 @@ out: | |||
2847 | return ret; | 3043 | return ret; |
2848 | } | 3044 | } |
2849 | 3045 | ||
2850 | int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 3046 | static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, |
2851 | enum ieee80211_ampdu_mlme_action action, | 3047 | struct ieee80211_vif *vif, |
2852 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | 3048 | enum ieee80211_ampdu_mlme_action action, |
2853 | u8 buf_size) | 3049 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, |
3050 | u8 buf_size) | ||
2854 | { | 3051 | { |
2855 | struct wl1271 *wl = hw->priv; | 3052 | struct wl1271 *wl = hw->priv; |
2856 | int ret; | 3053 | int ret; |
@@ -3003,7 +3200,8 @@ static const u8 wl1271_rate_to_idx_2ghz[] = { | |||
3003 | 3200 | ||
3004 | #ifdef CONFIG_WL12XX_HT | 3201 | #ifdef CONFIG_WL12XX_HT |
3005 | #define WL12XX_HT_CAP { \ | 3202 | #define WL12XX_HT_CAP { \ |
3006 | .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \ | 3203 | .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \ |
3204 | (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \ | ||
3007 | .ht_supported = true, \ | 3205 | .ht_supported = true, \ |
3008 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \ | 3206 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \ |
3009 | .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \ | 3207 | .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \ |
@@ -3207,8 +3405,7 @@ static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev, | |||
3207 | unsigned long res; | 3405 | unsigned long res; |
3208 | int ret; | 3406 | int ret; |
3209 | 3407 | ||
3210 | ret = strict_strtoul(buf, 10, &res); | 3408 | ret = kstrtoul(buf, 10, &res); |
3211 | |||
3212 | if (ret < 0) { | 3409 | if (ret < 0) { |
3213 | wl1271_warning("incorrect value written to bt_coex_mode"); | 3410 | wl1271_warning("incorrect value written to bt_coex_mode"); |
3214 | return count; | 3411 | return count; |
@@ -3273,7 +3470,11 @@ int wl1271_register_hw(struct wl1271 *wl) | |||
3273 | 3470 | ||
3274 | ret = wl1271_fetch_nvs(wl); | 3471 | ret = wl1271_fetch_nvs(wl); |
3275 | if (ret == 0) { | 3472 | if (ret == 0) { |
3276 | u8 *nvs_ptr = (u8 *)wl->nvs->nvs; | 3473 | /* NOTE: The wl->nvs->nvs element must be first, in |
3474 | * order to simplify the casting, we assume it is at | ||
3475 | * the beginning of the wl->nvs structure. | ||
3476 | */ | ||
3477 | u8 *nvs_ptr = (u8 *)wl->nvs; | ||
3277 | 3478 | ||
3278 | wl->mac_addr[0] = nvs_ptr[11]; | 3479 | wl->mac_addr[0] = nvs_ptr[11]; |
3279 | wl->mac_addr[1] = nvs_ptr[10]; | 3480 | wl->mac_addr[1] = nvs_ptr[10]; |
@@ -3341,7 +3542,6 @@ int wl1271_init_ieee80211(struct wl1271 *wl) | |||
3341 | IEEE80211_HW_HAS_RATE_CONTROL | | 3542 | IEEE80211_HW_HAS_RATE_CONTROL | |
3342 | IEEE80211_HW_CONNECTION_MONITOR | | 3543 | IEEE80211_HW_CONNECTION_MONITOR | |
3343 | IEEE80211_HW_SUPPORTS_CQM_RSSI | | 3544 | IEEE80211_HW_SUPPORTS_CQM_RSSI | |
3344 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | ||
3345 | IEEE80211_HW_AP_LINK_PS; | 3545 | IEEE80211_HW_AP_LINK_PS; |
3346 | 3546 | ||
3347 | wl->hw->wiphy->cipher_suites = cipher_suites; | 3547 | wl->hw->wiphy->cipher_suites = cipher_suites; |
@@ -3358,6 +3558,10 @@ int wl1271_init_ieee80211(struct wl1271 *wl) | |||
3358 | wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE - | 3558 | wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE - |
3359 | sizeof(struct ieee80211_header); | 3559 | sizeof(struct ieee80211_header); |
3360 | 3560 | ||
3561 | /* make sure all our channels fit in the scanned_ch bitmask */ | ||
3562 | BUILD_BUG_ON(ARRAY_SIZE(wl1271_channels) + | ||
3563 | ARRAY_SIZE(wl1271_channels_5ghz) > | ||
3564 | WL1271_MAX_CHANNELS); | ||
3361 | /* | 3565 | /* |
3362 | * We keep local copies of the band structs because we need to | 3566 | * We keep local copies of the band structs because we need to |
3363 | * modify them on a per-device basis. | 3567 | * modify them on a per-device basis. |
@@ -3458,6 +3662,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
3458 | wl->ap_ps_map = 0; | 3662 | wl->ap_ps_map = 0; |
3459 | wl->ap_fw_ps_map = 0; | 3663 | wl->ap_fw_ps_map = 0; |
3460 | wl->quirks = 0; | 3664 | wl->quirks = 0; |
3665 | wl->platform_quirks = 0; | ||
3461 | 3666 | ||
3462 | memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); | 3667 | memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); |
3463 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) | 3668 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) |
@@ -3478,11 +3683,17 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
3478 | goto err_hw; | 3683 | goto err_hw; |
3479 | } | 3684 | } |
3480 | 3685 | ||
3686 | wl->dummy_packet = wl12xx_alloc_dummy_packet(wl); | ||
3687 | if (!wl->dummy_packet) { | ||
3688 | ret = -ENOMEM; | ||
3689 | goto err_aggr; | ||
3690 | } | ||
3691 | |||
3481 | /* Register platform device */ | 3692 | /* Register platform device */ |
3482 | ret = platform_device_register(wl->plat_dev); | 3693 | ret = platform_device_register(wl->plat_dev); |
3483 | if (ret) { | 3694 | if (ret) { |
3484 | wl1271_error("couldn't register platform device"); | 3695 | wl1271_error("couldn't register platform device"); |
3485 | goto err_aggr; | 3696 | goto err_dummy_packet; |
3486 | } | 3697 | } |
3487 | dev_set_drvdata(&wl->plat_dev->dev, wl); | 3698 | dev_set_drvdata(&wl->plat_dev->dev, wl); |
3488 | 3699 | ||
@@ -3508,6 +3719,9 @@ err_bt_coex_state: | |||
3508 | err_platform: | 3719 | err_platform: |
3509 | platform_device_unregister(wl->plat_dev); | 3720 | platform_device_unregister(wl->plat_dev); |
3510 | 3721 | ||
3722 | err_dummy_packet: | ||
3723 | dev_kfree_skb(wl->dummy_packet); | ||
3724 | |||
3511 | err_aggr: | 3725 | err_aggr: |
3512 | free_pages((unsigned long)wl->aggr_buf, order); | 3726 | free_pages((unsigned long)wl->aggr_buf, order); |
3513 | 3727 | ||
@@ -3527,6 +3741,7 @@ EXPORT_SYMBOL_GPL(wl1271_alloc_hw); | |||
3527 | int wl1271_free_hw(struct wl1271 *wl) | 3741 | int wl1271_free_hw(struct wl1271 *wl) |
3528 | { | 3742 | { |
3529 | platform_device_unregister(wl->plat_dev); | 3743 | platform_device_unregister(wl->plat_dev); |
3744 | dev_kfree_skb(wl->dummy_packet); | ||
3530 | free_pages((unsigned long)wl->aggr_buf, | 3745 | free_pages((unsigned long)wl->aggr_buf, |
3531 | get_order(WL1271_AGGR_BUFFER_SIZE)); | 3746 | get_order(WL1271_AGGR_BUFFER_SIZE)); |
3532 | kfree(wl->plat_dev); | 3747 | kfree(wl->plat_dev); |
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 971f13e792da..b8deada5d020 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c | |||
@@ -149,9 +149,6 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, | |||
149 | case STATION_ACTIVE_MODE: | 149 | case STATION_ACTIVE_MODE: |
150 | default: | 150 | default: |
151 | wl1271_debug(DEBUG_PSM, "leaving psm"); | 151 | wl1271_debug(DEBUG_PSM, "leaving psm"); |
152 | ret = wl1271_ps_elp_wakeup(wl); | ||
153 | if (ret < 0) | ||
154 | return ret; | ||
155 | 152 | ||
156 | /* disable beacon early termination */ | 153 | /* disable beacon early termination */ |
157 | ret = wl1271_acx_bet_enable(wl, false); | 154 | ret = wl1271_acx_bet_enable(wl, false); |
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h index 990960771528..440a4ee9cb42 100644 --- a/drivers/net/wireless/wl12xx/reg.h +++ b/drivers/net/wireless/wl12xx/reg.h | |||
@@ -207,6 +207,8 @@ | |||
207 | 207 | ||
208 | #define CHIP_ID_1271_PG10 (0x4030101) | 208 | #define CHIP_ID_1271_PG10 (0x4030101) |
209 | #define CHIP_ID_1271_PG20 (0x4030111) | 209 | #define CHIP_ID_1271_PG20 (0x4030111) |
210 | #define CHIP_ID_1283_PG10 (0x05030101) | ||
211 | #define CHIP_ID_1283_PG20 (0x05030111) | ||
210 | 212 | ||
211 | #define ENABLE (REGISTERS_BASE + 0x5450) | 213 | #define ENABLE (REGISTERS_BASE + 0x5450) |
212 | 214 | ||
@@ -452,24 +454,11 @@ | |||
452 | #define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200 | 454 | #define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200 |
453 | #define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400 | 455 | #define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400 |
454 | 456 | ||
455 | /* | ||
456 | * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile | ||
457 | * for platforms using active high interrupt level | ||
458 | */ | ||
459 | #ifdef USE_ACTIVE_HIGH | ||
460 | #define HI_CFG_DEF_VAL \ | 457 | #define HI_CFG_DEF_VAL \ |
461 | (HI_CFG_UART_ENABLE | \ | 458 | (HI_CFG_UART_ENABLE | \ |
462 | HI_CFG_RST232_ENABLE | \ | 459 | HI_CFG_RST232_ENABLE | \ |
463 | HI_CFG_CLOCK_REQ_SELECT | \ | 460 | HI_CFG_CLOCK_REQ_SELECT | \ |
464 | HI_CFG_HOST_INT_ENABLE) | 461 | HI_CFG_HOST_INT_ENABLE) |
465 | #else | ||
466 | #define HI_CFG_DEF_VAL \ | ||
467 | (HI_CFG_UART_ENABLE | \ | ||
468 | HI_CFG_RST232_ENABLE | \ | ||
469 | HI_CFG_CLOCK_REQ_SELECT | \ | ||
470 | HI_CFG_HOST_INT_ENABLE) | ||
471 | |||
472 | #endif | ||
473 | 462 | ||
474 | #define REF_FREQ_19_2 0 | 463 | #define REF_FREQ_19_2 0 |
475 | #define REF_FREQ_26_0 1 | 464 | #define REF_FREQ_26_0 1 |
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 919b59f00301..2a581495d5c9 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c | |||
@@ -48,18 +48,14 @@ static void wl1271_rx_status(struct wl1271 *wl, | |||
48 | struct ieee80211_rx_status *status, | 48 | struct ieee80211_rx_status *status, |
49 | u8 beacon) | 49 | u8 beacon) |
50 | { | 50 | { |
51 | enum ieee80211_band desc_band; | ||
52 | |||
53 | memset(status, 0, sizeof(struct ieee80211_rx_status)); | 51 | memset(status, 0, sizeof(struct ieee80211_rx_status)); |
54 | 52 | ||
55 | status->band = wl->band; | ||
56 | |||
57 | if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG) | 53 | if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG) |
58 | desc_band = IEEE80211_BAND_2GHZ; | 54 | status->band = IEEE80211_BAND_2GHZ; |
59 | else | 55 | else |
60 | desc_band = IEEE80211_BAND_5GHZ; | 56 | status->band = IEEE80211_BAND_5GHZ; |
61 | 57 | ||
62 | status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band); | 58 | status->rate_idx = wl1271_rate_to_idx(desc->rate, status->band); |
63 | 59 | ||
64 | #ifdef CONFIG_WL12XX_HT | 60 | #ifdef CONFIG_WL12XX_HT |
65 | /* 11n support */ | 61 | /* 11n support */ |
@@ -76,7 +72,8 @@ static void wl1271_rx_status(struct wl1271 *wl, | |||
76 | */ | 72 | */ |
77 | wl->noise = desc->rssi - (desc->snr >> 1); | 73 | wl->noise = desc->rssi - (desc->snr >> 1); |
78 | 74 | ||
79 | status->freq = ieee80211_channel_to_frequency(desc->channel, desc_band); | 75 | status->freq = ieee80211_channel_to_frequency(desc->channel, |
76 | status->band); | ||
80 | 77 | ||
81 | if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { | 78 | if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { |
82 | status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; | 79 | status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; |
@@ -163,18 +160,25 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) | |||
163 | break; | 160 | break; |
164 | } | 161 | } |
165 | 162 | ||
166 | /* | 163 | if (wl->chip.id != CHIP_ID_1283_PG20) { |
167 | * Choose the block we want to read | 164 | /* |
168 | * For aggregated packets, only the first memory block should | 165 | * Choose the block we want to read |
169 | * be retrieved. The FW takes care of the rest. | 166 | * For aggregated packets, only the first memory block |
170 | */ | 167 | * should be retrieved. The FW takes care of the rest. |
171 | mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter); | 168 | */ |
172 | wl->rx_mem_pool_addr.addr = (mem_block << 8) + | 169 | mem_block = wl1271_rx_get_mem_block(status, |
173 | le32_to_cpu(wl_mem_map->packet_memory_pool_start); | 170 | drv_rx_counter); |
174 | wl->rx_mem_pool_addr.addr_extra = | 171 | |
175 | wl->rx_mem_pool_addr.addr + 4; | 172 | wl->rx_mem_pool_addr.addr = (mem_block << 8) + |
176 | wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr, | 173 | le32_to_cpu(wl_mem_map->packet_memory_pool_start); |
177 | sizeof(wl->rx_mem_pool_addr), false); | 174 | |
175 | wl->rx_mem_pool_addr.addr_extra = | ||
176 | wl->rx_mem_pool_addr.addr + 4; | ||
177 | |||
178 | wl1271_write(wl, WL1271_SLV_REG_DATA, | ||
179 | &wl->rx_mem_pool_addr, | ||
180 | sizeof(wl->rx_mem_pool_addr), false); | ||
181 | } | ||
178 | 182 | ||
179 | /* Read all available packets at once */ | 183 | /* Read all available packets at once */ |
180 | wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, | 184 | wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, |
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 420653a2859c..5d0544c8f3f5 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -48,8 +48,7 @@ void wl1271_scan_complete_work(struct work_struct *work) | |||
48 | goto out; | 48 | goto out; |
49 | 49 | ||
50 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 50 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
51 | kfree(wl->scan.scanned_ch); | 51 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); |
52 | wl->scan.scanned_ch = NULL; | ||
53 | wl->scan.req = NULL; | 52 | wl->scan.req = NULL; |
54 | ieee80211_scan_completed(wl->hw, false); | 53 | ieee80211_scan_completed(wl->hw, false); |
55 | 54 | ||
@@ -87,7 +86,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl, | |||
87 | 86 | ||
88 | flags = req->channels[i]->flags; | 87 | flags = req->channels[i]->flags; |
89 | 88 | ||
90 | if (!wl->scan.scanned_ch[i] && | 89 | if (!test_bit(i, wl->scan.scanned_ch) && |
91 | !(flags & IEEE80211_CHAN_DISABLED) && | 90 | !(flags & IEEE80211_CHAN_DISABLED) && |
92 | ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) && | 91 | ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) && |
93 | (req->channels[i]->band == band)) { | 92 | (req->channels[i]->band == band)) { |
@@ -124,7 +123,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl, | |||
124 | memset(&channels[j].bssid_msb, 0xff, 2); | 123 | memset(&channels[j].bssid_msb, 0xff, 2); |
125 | 124 | ||
126 | /* Mark the channels we already used */ | 125 | /* Mark the channels we already used */ |
127 | wl->scan.scanned_ch[i] = true; | 126 | set_bit(i, wl->scan.scanned_ch); |
128 | 127 | ||
129 | j++; | 128 | j++; |
130 | } | 129 | } |
@@ -291,6 +290,12 @@ void wl1271_scan_stm(struct wl1271 *wl) | |||
291 | int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, | 290 | int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, |
292 | struct cfg80211_scan_request *req) | 291 | struct cfg80211_scan_request *req) |
293 | { | 292 | { |
293 | /* | ||
294 | * cfg80211 should guarantee that we don't get more channels | ||
295 | * than what we have registered. | ||
296 | */ | ||
297 | BUG_ON(req->n_channels > WL1271_MAX_CHANNELS); | ||
298 | |||
294 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE) | 299 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE) |
295 | return -EBUSY; | 300 | return -EBUSY; |
296 | 301 | ||
@@ -304,10 +309,8 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, | |||
304 | } | 309 | } |
305 | 310 | ||
306 | wl->scan.req = req; | 311 | wl->scan.req = req; |
312 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); | ||
307 | 313 | ||
308 | wl->scan.scanned_ch = kcalloc(req->n_channels, | ||
309 | sizeof(*wl->scan.scanned_ch), | ||
310 | GFP_KERNEL); | ||
311 | /* we assume failure so that timeout scenarios are handled correctly */ | 314 | /* we assume failure so that timeout scenarios are handled correctly */ |
312 | wl->scan.failed = true; | 315 | wl->scan.failed = true; |
313 | ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, | 316 | ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, |
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index b1c7d031c391..bcd4ad7ba90d 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c | |||
@@ -51,6 +51,13 @@ static const struct sdio_device_id wl1271_devices[] = { | |||
51 | }; | 51 | }; |
52 | MODULE_DEVICE_TABLE(sdio, wl1271_devices); | 52 | MODULE_DEVICE_TABLE(sdio, wl1271_devices); |
53 | 53 | ||
54 | static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz) | ||
55 | { | ||
56 | sdio_claim_host(wl->if_priv); | ||
57 | sdio_set_block_size(wl->if_priv, blksz); | ||
58 | sdio_release_host(wl->if_priv); | ||
59 | } | ||
60 | |||
54 | static inline struct sdio_func *wl_to_func(struct wl1271 *wl) | 61 | static inline struct sdio_func *wl_to_func(struct wl1271 *wl) |
55 | { | 62 | { |
56 | return wl->if_priv; | 63 | return wl->if_priv; |
@@ -203,7 +210,8 @@ static struct wl1271_if_operations sdio_ops = { | |||
203 | .power = wl1271_sdio_set_power, | 210 | .power = wl1271_sdio_set_power, |
204 | .dev = wl1271_sdio_wl_to_dev, | 211 | .dev = wl1271_sdio_wl_to_dev, |
205 | .enable_irq = wl1271_sdio_enable_interrupts, | 212 | .enable_irq = wl1271_sdio_enable_interrupts, |
206 | .disable_irq = wl1271_sdio_disable_interrupts | 213 | .disable_irq = wl1271_sdio_disable_interrupts, |
214 | .set_block_size = wl1271_sdio_set_block_size, | ||
207 | }; | 215 | }; |
208 | 216 | ||
209 | static int __devinit wl1271_probe(struct sdio_func *func, | 217 | static int __devinit wl1271_probe(struct sdio_func *func, |
@@ -212,6 +220,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
212 | struct ieee80211_hw *hw; | 220 | struct ieee80211_hw *hw; |
213 | const struct wl12xx_platform_data *wlan_data; | 221 | const struct wl12xx_platform_data *wlan_data; |
214 | struct wl1271 *wl; | 222 | struct wl1271 *wl; |
223 | unsigned long irqflags; | ||
215 | int ret; | 224 | int ret; |
216 | 225 | ||
217 | /* We are only able to handle the wlan function */ | 226 | /* We are only able to handle the wlan function */ |
@@ -230,6 +239,9 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
230 | /* Grab access to FN0 for ELP reg. */ | 239 | /* Grab access to FN0 for ELP reg. */ |
231 | func->card->quirks |= MMC_QUIRK_LENIENT_FN0; | 240 | func->card->quirks |= MMC_QUIRK_LENIENT_FN0; |
232 | 241 | ||
242 | /* Use block mode for transferring over one block size of data */ | ||
243 | func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; | ||
244 | |||
233 | wlan_data = wl12xx_get_platform_data(); | 245 | wlan_data = wl12xx_get_platform_data(); |
234 | if (IS_ERR(wlan_data)) { | 246 | if (IS_ERR(wlan_data)) { |
235 | ret = PTR_ERR(wlan_data); | 247 | ret = PTR_ERR(wlan_data); |
@@ -239,9 +251,16 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
239 | 251 | ||
240 | wl->irq = wlan_data->irq; | 252 | wl->irq = wlan_data->irq; |
241 | wl->ref_clock = wlan_data->board_ref_clock; | 253 | wl->ref_clock = wlan_data->board_ref_clock; |
254 | wl->tcxo_clock = wlan_data->board_tcxo_clock; | ||
255 | wl->platform_quirks = wlan_data->platform_quirks; | ||
256 | |||
257 | if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) | ||
258 | irqflags = IRQF_TRIGGER_RISING; | ||
259 | else | ||
260 | irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; | ||
242 | 261 | ||
243 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, | 262 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, |
244 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | 263 | irqflags, |
245 | DRIVER_NAME, wl); | 264 | DRIVER_NAME, wl); |
246 | if (ret < 0) { | 265 | if (ret < 0) { |
247 | wl1271_error("request_irq() failed: %d", ret); | 266 | wl1271_error("request_irq() failed: %d", ret); |
@@ -343,4 +362,6 @@ MODULE_LICENSE("GPL"); | |||
343 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 362 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
344 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 363 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
345 | MODULE_FIRMWARE(WL1271_FW_NAME); | 364 | MODULE_FIRMWARE(WL1271_FW_NAME); |
346 | MODULE_FIRMWARE(WL1271_AP_FW_NAME); | 365 | MODULE_FIRMWARE(WL128X_FW_NAME); |
366 | MODULE_FIRMWARE(WL127X_AP_FW_NAME); | ||
367 | MODULE_FIRMWARE(WL128X_AP_FW_NAME); | ||
diff --git a/drivers/net/wireless/wl12xx/sdio_test.c b/drivers/net/wireless/wl12xx/sdio_test.c index 9fcbd3dd8490..f28915392877 100644 --- a/drivers/net/wireless/wl12xx/sdio_test.c +++ b/drivers/net/wireless/wl12xx/sdio_test.c | |||
@@ -189,7 +189,12 @@ static int wl1271_fetch_firmware(struct wl1271 *wl) | |||
189 | const struct firmware *fw; | 189 | const struct firmware *fw; |
190 | int ret; | 190 | int ret; |
191 | 191 | ||
192 | ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl)); | 192 | if (wl->chip.id == CHIP_ID_1283_PG20) |
193 | ret = request_firmware(&fw, WL128X_FW_NAME, | ||
194 | wl1271_wl_to_dev(wl)); | ||
195 | else | ||
196 | ret = request_firmware(&fw, WL1271_FW_NAME, | ||
197 | wl1271_wl_to_dev(wl)); | ||
193 | 198 | ||
194 | if (ret < 0) { | 199 | if (ret < 0) { |
195 | wl1271_error("could not get firmware: %d", ret); | 200 | wl1271_error("could not get firmware: %d", ret); |
@@ -227,14 +232,14 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) | |||
227 | const struct firmware *fw; | 232 | const struct firmware *fw; |
228 | int ret; | 233 | int ret; |
229 | 234 | ||
230 | ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl)); | 235 | ret = request_firmware(&fw, WL12XX_NVS_NAME, wl1271_wl_to_dev(wl)); |
231 | 236 | ||
232 | if (ret < 0) { | 237 | if (ret < 0) { |
233 | wl1271_error("could not get nvs file: %d", ret); | 238 | wl1271_error("could not get nvs file: %d", ret); |
234 | return ret; | 239 | return ret; |
235 | } | 240 | } |
236 | 241 | ||
237 | wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); | 242 | wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL); |
238 | 243 | ||
239 | if (!wl->nvs) { | 244 | if (!wl->nvs) { |
240 | wl1271_error("could not allocate memory for the nvs file"); | 245 | wl1271_error("could not allocate memory for the nvs file"); |
@@ -288,6 +293,11 @@ static int wl1271_chip_wakeup(struct wl1271 *wl) | |||
288 | wl1271_notice("chip id 0x%x (1271 PG20)", | 293 | wl1271_notice("chip id 0x%x (1271 PG20)", |
289 | wl->chip.id); | 294 | wl->chip.id); |
290 | break; | 295 | break; |
296 | case CHIP_ID_1283_PG20: | ||
297 | wl1271_notice("chip id 0x%x (1283 PG20)", | ||
298 | wl->chip.id); | ||
299 | break; | ||
300 | case CHIP_ID_1283_PG10: | ||
291 | default: | 301 | default: |
292 | wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); | 302 | wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); |
293 | return -ENODEV; | 303 | return -ENODEV; |
@@ -407,6 +417,9 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
407 | /* Grab access to FN0 for ELP reg. */ | 417 | /* Grab access to FN0 for ELP reg. */ |
408 | func->card->quirks |= MMC_QUIRK_LENIENT_FN0; | 418 | func->card->quirks |= MMC_QUIRK_LENIENT_FN0; |
409 | 419 | ||
420 | /* Use block mode for transferring over one block size of data */ | ||
421 | func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; | ||
422 | |||
410 | wlan_data = wl12xx_get_platform_data(); | 423 | wlan_data = wl12xx_get_platform_data(); |
411 | if (IS_ERR(wlan_data)) { | 424 | if (IS_ERR(wlan_data)) { |
412 | ret = PTR_ERR(wlan_data); | 425 | ret = PTR_ERR(wlan_data); |
@@ -416,6 +429,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
416 | 429 | ||
417 | wl->irq = wlan_data->irq; | 430 | wl->irq = wlan_data->irq; |
418 | wl->ref_clock = wlan_data->board_ref_clock; | 431 | wl->ref_clock = wlan_data->board_ref_clock; |
432 | wl->tcxo_clock = wlan_data->board_tcxo_clock; | ||
419 | 433 | ||
420 | sdio_set_drvdata(func, wl_test); | 434 | sdio_set_drvdata(func, wl_test); |
421 | 435 | ||
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index ffc745b17f4d..51662bb68019 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c | |||
@@ -355,7 +355,8 @@ static struct wl1271_if_operations spi_ops = { | |||
355 | .power = wl1271_spi_set_power, | 355 | .power = wl1271_spi_set_power, |
356 | .dev = wl1271_spi_wl_to_dev, | 356 | .dev = wl1271_spi_wl_to_dev, |
357 | .enable_irq = wl1271_spi_enable_interrupts, | 357 | .enable_irq = wl1271_spi_enable_interrupts, |
358 | .disable_irq = wl1271_spi_disable_interrupts | 358 | .disable_irq = wl1271_spi_disable_interrupts, |
359 | .set_block_size = NULL, | ||
359 | }; | 360 | }; |
360 | 361 | ||
361 | static int __devinit wl1271_probe(struct spi_device *spi) | 362 | static int __devinit wl1271_probe(struct spi_device *spi) |
@@ -363,6 +364,7 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
363 | struct wl12xx_platform_data *pdata; | 364 | struct wl12xx_platform_data *pdata; |
364 | struct ieee80211_hw *hw; | 365 | struct ieee80211_hw *hw; |
365 | struct wl1271 *wl; | 366 | struct wl1271 *wl; |
367 | unsigned long irqflags; | ||
366 | int ret; | 368 | int ret; |
367 | 369 | ||
368 | pdata = spi->dev.platform_data; | 370 | pdata = spi->dev.platform_data; |
@@ -400,6 +402,13 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
400 | } | 402 | } |
401 | 403 | ||
402 | wl->ref_clock = pdata->board_ref_clock; | 404 | wl->ref_clock = pdata->board_ref_clock; |
405 | wl->tcxo_clock = pdata->board_tcxo_clock; | ||
406 | wl->platform_quirks = pdata->platform_quirks; | ||
407 | |||
408 | if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) | ||
409 | irqflags = IRQF_TRIGGER_RISING; | ||
410 | else | ||
411 | irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; | ||
403 | 412 | ||
404 | wl->irq = spi->irq; | 413 | wl->irq = spi->irq; |
405 | if (wl->irq < 0) { | 414 | if (wl->irq < 0) { |
@@ -409,7 +418,7 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
409 | } | 418 | } |
410 | 419 | ||
411 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, | 420 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, |
412 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | 421 | irqflags, |
413 | DRIVER_NAME, wl); | 422 | DRIVER_NAME, wl); |
414 | if (ret < 0) { | 423 | if (ret < 0) { |
415 | wl1271_error("request_irq() failed: %d", ret); | 424 | wl1271_error("request_irq() failed: %d", ret); |
@@ -490,5 +499,7 @@ MODULE_LICENSE("GPL"); | |||
490 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 499 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
491 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 500 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
492 | MODULE_FIRMWARE(WL1271_FW_NAME); | 501 | MODULE_FIRMWARE(WL1271_FW_NAME); |
493 | MODULE_FIRMWARE(WL1271_AP_FW_NAME); | 502 | MODULE_FIRMWARE(WL128X_FW_NAME); |
503 | MODULE_FIRMWARE(WL127X_AP_FW_NAME); | ||
504 | MODULE_FIRMWARE(WL128X_AP_FW_NAME); | ||
494 | MODULE_ALIAS("spi:wl1271"); | 505 | MODULE_ALIAS("spi:wl1271"); |
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c index 6ec06a4a4c6d..da351d7cd1f2 100644 --- a/drivers/net/wireless/wl12xx/testmode.c +++ b/drivers/net/wireless/wl12xx/testmode.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include "wl12xx.h" | 28 | #include "wl12xx.h" |
29 | #include "acx.h" | 29 | #include "acx.h" |
30 | #include "reg.h" | ||
30 | 31 | ||
31 | #define WL1271_TM_MAX_DATA_LENGTH 1024 | 32 | #define WL1271_TM_MAX_DATA_LENGTH 1024 |
32 | 33 | ||
@@ -204,7 +205,10 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) | |||
204 | 205 | ||
205 | kfree(wl->nvs); | 206 | kfree(wl->nvs); |
206 | 207 | ||
207 | if (len != sizeof(struct wl1271_nvs_file)) | 208 | if ((wl->chip.id == CHIP_ID_1283_PG20) && |
209 | (len != sizeof(struct wl128x_nvs_file))) | ||
210 | return -EINVAL; | ||
211 | else if (len != sizeof(struct wl1271_nvs_file)) | ||
208 | return -EINVAL; | 212 | return -EINVAL; |
209 | 213 | ||
210 | wl->nvs = kzalloc(len, GFP_KERNEL); | 214 | wl->nvs = kzalloc(len, GFP_KERNEL); |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 5e9ef7d53e7e..7a3339fd3415 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -70,6 +70,28 @@ static void wl1271_free_tx_id(struct wl1271 *wl, int id) | |||
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | static int wl1271_tx_update_filters(struct wl1271 *wl, | ||
74 | struct sk_buff *skb) | ||
75 | { | ||
76 | struct ieee80211_hdr *hdr; | ||
77 | |||
78 | hdr = (struct ieee80211_hdr *)(skb->data + | ||
79 | sizeof(struct wl1271_tx_hw_descr)); | ||
80 | |||
81 | /* | ||
82 | * stop bssid-based filtering before transmitting authentication | ||
83 | * requests. this way the hw will never drop authentication | ||
84 | * responses coming from BSSIDs it isn't familiar with (e.g. on | ||
85 | * roaming) | ||
86 | */ | ||
87 | if (!ieee80211_is_auth(hdr->frame_control)) | ||
88 | return 0; | ||
89 | |||
90 | wl1271_configure_filters(wl, FIF_OTHER_BSS); | ||
91 | |||
92 | return wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); | ||
93 | } | ||
94 | |||
73 | static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, | 95 | static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, |
74 | struct sk_buff *skb) | 96 | struct sk_buff *skb) |
75 | { | 97 | { |
@@ -127,13 +149,29 @@ u8 wl1271_tx_get_hlid(struct sk_buff *skb) | |||
127 | } | 149 | } |
128 | } | 150 | } |
129 | 151 | ||
152 | static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl, | ||
153 | unsigned int packet_length) | ||
154 | { | ||
155 | if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT) | ||
156 | return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE); | ||
157 | else | ||
158 | return ALIGN(packet_length, WL1271_TX_ALIGN_TO); | ||
159 | } | ||
160 | |||
130 | static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, | 161 | static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, |
131 | u32 buf_offset, u8 hlid) | 162 | u32 buf_offset, u8 hlid) |
132 | { | 163 | { |
133 | struct wl1271_tx_hw_descr *desc; | 164 | struct wl1271_tx_hw_descr *desc; |
134 | u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; | 165 | u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; |
166 | u32 len; | ||
135 | u32 total_blocks; | 167 | u32 total_blocks; |
136 | int id, ret = -EBUSY; | 168 | int id, ret = -EBUSY; |
169 | u32 spare_blocks; | ||
170 | |||
171 | if (unlikely(wl->quirks & WL12XX_QUIRK_USE_2_SPARE_BLOCKS)) | ||
172 | spare_blocks = 2; | ||
173 | else | ||
174 | spare_blocks = 1; | ||
137 | 175 | ||
138 | if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) | 176 | if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) |
139 | return -EAGAIN; | 177 | return -EAGAIN; |
@@ -145,17 +183,27 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, | |||
145 | 183 | ||
146 | /* approximate the number of blocks required for this packet | 184 | /* approximate the number of blocks required for this packet |
147 | in the firmware */ | 185 | in the firmware */ |
148 | total_blocks = total_len + TX_HW_BLOCK_SIZE - 1; | 186 | len = wl12xx_calc_packet_alignment(wl, total_len); |
149 | total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE; | 187 | |
188 | total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE + | ||
189 | spare_blocks; | ||
190 | |||
150 | if (total_blocks <= wl->tx_blocks_available) { | 191 | if (total_blocks <= wl->tx_blocks_available) { |
151 | desc = (struct wl1271_tx_hw_descr *)skb_push( | 192 | desc = (struct wl1271_tx_hw_descr *)skb_push( |
152 | skb, total_len - skb->len); | 193 | skb, total_len - skb->len); |
153 | 194 | ||
154 | desc->extra_mem_blocks = TX_HW_BLOCK_SPARE; | 195 | /* HW descriptor fields change between wl127x and wl128x */ |
155 | desc->total_mem_blocks = total_blocks; | 196 | if (wl->chip.id == CHIP_ID_1283_PG20) { |
197 | desc->wl128x_mem.total_mem_blocks = total_blocks; | ||
198 | } else { | ||
199 | desc->wl127x_mem.extra_blocks = spare_blocks; | ||
200 | desc->wl127x_mem.total_mem_blocks = total_blocks; | ||
201 | } | ||
202 | |||
156 | desc->id = id; | 203 | desc->id = id; |
157 | 204 | ||
158 | wl->tx_blocks_available -= total_blocks; | 205 | wl->tx_blocks_available -= total_blocks; |
206 | wl->tx_allocated_blocks += total_blocks; | ||
159 | 207 | ||
160 | if (wl->bss_type == BSS_TYPE_AP_BSS) | 208 | if (wl->bss_type == BSS_TYPE_AP_BSS) |
161 | wl->links[hlid].allocated_blks += total_blocks; | 209 | wl->links[hlid].allocated_blks += total_blocks; |
@@ -172,13 +220,18 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, | |||
172 | return ret; | 220 | return ret; |
173 | } | 221 | } |
174 | 222 | ||
223 | static bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb) | ||
224 | { | ||
225 | return wl->dummy_packet == skb; | ||
226 | } | ||
227 | |||
175 | static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, | 228 | static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, |
176 | u32 extra, struct ieee80211_tx_info *control, | 229 | u32 extra, struct ieee80211_tx_info *control, |
177 | u8 hlid) | 230 | u8 hlid) |
178 | { | 231 | { |
179 | struct timespec ts; | 232 | struct timespec ts; |
180 | struct wl1271_tx_hw_descr *desc; | 233 | struct wl1271_tx_hw_descr *desc; |
181 | int pad, ac, rate_idx; | 234 | int aligned_len, ac, rate_idx; |
182 | s64 hosttime; | 235 | s64 hosttime; |
183 | u16 tx_attr; | 236 | u16 tx_attr; |
184 | 237 | ||
@@ -202,12 +255,25 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, | |||
202 | else | 255 | else |
203 | desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU); | 256 | desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU); |
204 | 257 | ||
205 | /* configure the tx attributes */ | 258 | /* queue */ |
206 | tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; | ||
207 | |||
208 | /* queue (we use same identifiers for tid's and ac's */ | ||
209 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 259 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
210 | desc->tid = ac; | 260 | desc->tid = skb->priority; |
261 | |||
262 | if (wl12xx_is_dummy_packet(wl, skb)) { | ||
263 | /* | ||
264 | * FW expects the dummy packet to have an invalid session id - | ||
265 | * any session id that is different than the one set in the join | ||
266 | */ | ||
267 | tx_attr = ((~wl->session_counter) << | ||
268 | TX_HW_ATTR_OFST_SESSION_COUNTER) & | ||
269 | TX_HW_ATTR_SESSION_COUNTER; | ||
270 | |||
271 | tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ; | ||
272 | } else { | ||
273 | /* configure the tx attributes */ | ||
274 | tx_attr = | ||
275 | wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; | ||
276 | } | ||
211 | 277 | ||
212 | if (wl->bss_type != BSS_TYPE_AP_BSS) { | 278 | if (wl->bss_type != BSS_TYPE_AP_BSS) { |
213 | desc->aid = hlid; | 279 | desc->aid = hlid; |
@@ -237,20 +303,37 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, | |||
237 | tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; | 303 | tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; |
238 | desc->reserved = 0; | 304 | desc->reserved = 0; |
239 | 305 | ||
240 | /* align the length (and store in terms of words) */ | 306 | aligned_len = wl12xx_calc_packet_alignment(wl, skb->len); |
241 | pad = ALIGN(skb->len, WL1271_TX_ALIGN_TO); | ||
242 | desc->length = cpu_to_le16(pad >> 2); | ||
243 | 307 | ||
244 | /* calculate number of padding bytes */ | 308 | if (wl->chip.id == CHIP_ID_1283_PG20) { |
245 | pad = pad - skb->len; | 309 | desc->wl128x_mem.extra_bytes = aligned_len - skb->len; |
246 | tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD; | 310 | desc->length = cpu_to_le16(aligned_len >> 2); |
247 | 311 | ||
248 | desc->tx_attr = cpu_to_le16(tx_attr); | 312 | wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d " |
313 | "tx_attr: 0x%x len: %d life: %d mem: %d", | ||
314 | desc->hlid, tx_attr, | ||
315 | le16_to_cpu(desc->length), | ||
316 | le16_to_cpu(desc->life_time), | ||
317 | desc->wl128x_mem.total_mem_blocks); | ||
318 | } else { | ||
319 | int pad; | ||
320 | |||
321 | /* Store the aligned length in terms of words */ | ||
322 | desc->length = cpu_to_le16(aligned_len >> 2); | ||
323 | |||
324 | /* calculate number of padding bytes */ | ||
325 | pad = aligned_len - skb->len; | ||
326 | tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD; | ||
249 | 327 | ||
250 | wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d " | 328 | wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d " |
251 | "tx_attr: 0x%x len: %d life: %d mem: %d", pad, desc->hlid, | 329 | "tx_attr: 0x%x len: %d life: %d mem: %d", pad, |
252 | le16_to_cpu(desc->tx_attr), le16_to_cpu(desc->length), | 330 | desc->hlid, tx_attr, |
253 | le16_to_cpu(desc->life_time), desc->total_mem_blocks); | 331 | le16_to_cpu(desc->length), |
332 | le16_to_cpu(desc->life_time), | ||
333 | desc->wl127x_mem.total_mem_blocks); | ||
334 | } | ||
335 | |||
336 | desc->tx_attr = cpu_to_le16(tx_attr); | ||
254 | } | 337 | } |
255 | 338 | ||
256 | /* caller must hold wl->mutex */ | 339 | /* caller must hold wl->mutex */ |
@@ -300,19 +383,29 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, | |||
300 | if (wl->bss_type == BSS_TYPE_AP_BSS) { | 383 | if (wl->bss_type == BSS_TYPE_AP_BSS) { |
301 | wl1271_tx_ap_update_inconnection_sta(wl, skb); | 384 | wl1271_tx_ap_update_inconnection_sta(wl, skb); |
302 | wl1271_tx_regulate_link(wl, hlid); | 385 | wl1271_tx_regulate_link(wl, hlid); |
386 | } else { | ||
387 | wl1271_tx_update_filters(wl, skb); | ||
303 | } | 388 | } |
304 | 389 | ||
305 | wl1271_tx_fill_hdr(wl, skb, extra, info, hlid); | 390 | wl1271_tx_fill_hdr(wl, skb, extra, info, hlid); |
306 | 391 | ||
307 | /* | 392 | /* |
308 | * The length of each packet is stored in terms of words. Thus, we must | 393 | * The length of each packet is stored in terms of |
309 | * pad the skb data to make sure its length is aligned. | 394 | * words. Thus, we must pad the skb data to make sure its |
310 | * The number of padding bytes is computed and set in wl1271_tx_fill_hdr | 395 | * length is aligned. The number of padding bytes is computed |
396 | * and set in wl1271_tx_fill_hdr. | ||
397 | * In special cases, we want to align to a specific block size | ||
398 | * (eg. for wl128x with SDIO we align to 256). | ||
311 | */ | 399 | */ |
312 | total_len = ALIGN(skb->len, WL1271_TX_ALIGN_TO); | 400 | total_len = wl12xx_calc_packet_alignment(wl, skb->len); |
401 | |||
313 | memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); | 402 | memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); |
314 | memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); | 403 | memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); |
315 | 404 | ||
405 | /* Revert side effects in the dummy packet skb, so it can be reused */ | ||
406 | if (wl12xx_is_dummy_packet(wl, skb)) | ||
407 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); | ||
408 | |||
316 | return total_len; | 409 | return total_len; |
317 | } | 410 | } |
318 | 411 | ||
@@ -425,10 +518,23 @@ out: | |||
425 | 518 | ||
426 | static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) | 519 | static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) |
427 | { | 520 | { |
521 | unsigned long flags; | ||
522 | struct sk_buff *skb = NULL; | ||
523 | |||
428 | if (wl->bss_type == BSS_TYPE_AP_BSS) | 524 | if (wl->bss_type == BSS_TYPE_AP_BSS) |
429 | return wl1271_ap_skb_dequeue(wl); | 525 | skb = wl1271_ap_skb_dequeue(wl); |
526 | else | ||
527 | skb = wl1271_sta_skb_dequeue(wl); | ||
528 | |||
529 | if (!skb && | ||
530 | test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { | ||
531 | skb = wl->dummy_packet; | ||
532 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
533 | wl->tx_queue_count--; | ||
534 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
535 | } | ||
430 | 536 | ||
431 | return wl1271_sta_skb_dequeue(wl); | 537 | return skb; |
432 | } | 538 | } |
433 | 539 | ||
434 | static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb) | 540 | static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb) |
@@ -436,7 +542,9 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb) | |||
436 | unsigned long flags; | 542 | unsigned long flags; |
437 | int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 543 | int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
438 | 544 | ||
439 | if (wl->bss_type == BSS_TYPE_AP_BSS) { | 545 | if (wl12xx_is_dummy_packet(wl, skb)) { |
546 | set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags); | ||
547 | } else if (wl->bss_type == BSS_TYPE_AP_BSS) { | ||
440 | u8 hlid = wl1271_tx_get_hlid(skb); | 548 | u8 hlid = wl1271_tx_get_hlid(skb); |
441 | skb_queue_head(&wl->links[hlid].tx_queue[q], skb); | 549 | skb_queue_head(&wl->links[hlid].tx_queue[q], skb); |
442 | 550 | ||
@@ -454,22 +562,14 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb) | |||
454 | void wl1271_tx_work_locked(struct wl1271 *wl) | 562 | void wl1271_tx_work_locked(struct wl1271 *wl) |
455 | { | 563 | { |
456 | struct sk_buff *skb; | 564 | struct sk_buff *skb; |
457 | bool woken_up = false; | ||
458 | u32 buf_offset = 0; | 565 | u32 buf_offset = 0; |
459 | bool sent_packets = false; | 566 | bool sent_packets = false; |
460 | int ret; | 567 | int ret; |
461 | 568 | ||
462 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 569 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
463 | goto out; | 570 | return; |
464 | 571 | ||
465 | while ((skb = wl1271_skb_dequeue(wl))) { | 572 | while ((skb = wl1271_skb_dequeue(wl))) { |
466 | if (!woken_up) { | ||
467 | ret = wl1271_ps_elp_wakeup(wl); | ||
468 | if (ret < 0) | ||
469 | goto out_ack; | ||
470 | woken_up = true; | ||
471 | } | ||
472 | |||
473 | ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); | 573 | ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); |
474 | if (ret == -EAGAIN) { | 574 | if (ret == -EAGAIN) { |
475 | /* | 575 | /* |
@@ -516,18 +616,22 @@ out_ack: | |||
516 | 616 | ||
517 | wl1271_handle_tx_low_watermark(wl); | 617 | wl1271_handle_tx_low_watermark(wl); |
518 | } | 618 | } |
519 | |||
520 | out: | ||
521 | if (woken_up) | ||
522 | wl1271_ps_elp_sleep(wl); | ||
523 | } | 619 | } |
524 | 620 | ||
525 | void wl1271_tx_work(struct work_struct *work) | 621 | void wl1271_tx_work(struct work_struct *work) |
526 | { | 622 | { |
527 | struct wl1271 *wl = container_of(work, struct wl1271, tx_work); | 623 | struct wl1271 *wl = container_of(work, struct wl1271, tx_work); |
624 | int ret; | ||
528 | 625 | ||
529 | mutex_lock(&wl->mutex); | 626 | mutex_lock(&wl->mutex); |
627 | ret = wl1271_ps_elp_wakeup(wl); | ||
628 | if (ret < 0) | ||
629 | goto out; | ||
630 | |||
530 | wl1271_tx_work_locked(wl); | 631 | wl1271_tx_work_locked(wl); |
632 | |||
633 | wl1271_ps_elp_wakeup(wl); | ||
634 | out: | ||
531 | mutex_unlock(&wl->mutex); | 635 | mutex_unlock(&wl->mutex); |
532 | } | 636 | } |
533 | 637 | ||
@@ -549,6 +653,11 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, | |||
549 | skb = wl->tx_frames[id]; | 653 | skb = wl->tx_frames[id]; |
550 | info = IEEE80211_SKB_CB(skb); | 654 | info = IEEE80211_SKB_CB(skb); |
551 | 655 | ||
656 | if (wl12xx_is_dummy_packet(wl, skb)) { | ||
657 | wl1271_free_tx_id(wl, id); | ||
658 | return; | ||
659 | } | ||
660 | |||
552 | /* update the TX status info */ | 661 | /* update the TX status info */ |
553 | if (result->status == TX_SUCCESS) { | 662 | if (result->status == TX_SUCCESS) { |
554 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 663 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
@@ -678,10 +787,13 @@ void wl1271_tx_reset(struct wl1271 *wl) | |||
678 | while ((skb = skb_dequeue(&wl->tx_queue[i]))) { | 787 | while ((skb = skb_dequeue(&wl->tx_queue[i]))) { |
679 | wl1271_debug(DEBUG_TX, "freeing skb 0x%p", | 788 | wl1271_debug(DEBUG_TX, "freeing skb 0x%p", |
680 | skb); | 789 | skb); |
681 | info = IEEE80211_SKB_CB(skb); | 790 | |
682 | info->status.rates[0].idx = -1; | 791 | if (!wl12xx_is_dummy_packet(wl, skb)) { |
683 | info->status.rates[0].count = 0; | 792 | info = IEEE80211_SKB_CB(skb); |
684 | ieee80211_tx_status(wl->hw, skb); | 793 | info->status.rates[0].idx = -1; |
794 | info->status.rates[0].count = 0; | ||
795 | ieee80211_tx_status(wl->hw, skb); | ||
796 | } | ||
685 | } | 797 | } |
686 | } | 798 | } |
687 | } | 799 | } |
@@ -702,21 +814,27 @@ void wl1271_tx_reset(struct wl1271 *wl) | |||
702 | wl1271_free_tx_id(wl, i); | 814 | wl1271_free_tx_id(wl, i); |
703 | wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); | 815 | wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); |
704 | 816 | ||
705 | /* Remove private headers before passing the skb to mac80211 */ | 817 | if (!wl12xx_is_dummy_packet(wl, skb)) { |
706 | info = IEEE80211_SKB_CB(skb); | 818 | /* |
707 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); | 819 | * Remove private headers before passing the skb to |
708 | if (info->control.hw_key && | 820 | * mac80211 |
709 | info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { | 821 | */ |
710 | int hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 822 | info = IEEE80211_SKB_CB(skb); |
711 | memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, | 823 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); |
712 | hdrlen); | 824 | if (info->control.hw_key && |
713 | skb_pull(skb, WL1271_TKIP_IV_SPACE); | 825 | info->control.hw_key->cipher == |
714 | } | 826 | WLAN_CIPHER_SUITE_TKIP) { |
827 | int hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
828 | memmove(skb->data + WL1271_TKIP_IV_SPACE, | ||
829 | skb->data, hdrlen); | ||
830 | skb_pull(skb, WL1271_TKIP_IV_SPACE); | ||
831 | } | ||
715 | 832 | ||
716 | info->status.rates[0].idx = -1; | 833 | info->status.rates[0].idx = -1; |
717 | info->status.rates[0].count = 0; | 834 | info->status.rates[0].count = 0; |
718 | 835 | ||
719 | ieee80211_tx_status(wl->hw, skb); | 836 | ieee80211_tx_status(wl->hw, skb); |
837 | } | ||
720 | } | 838 | } |
721 | } | 839 | } |
722 | 840 | ||
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 02f07fa66e82..fc7835c4cf63 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h | |||
@@ -25,7 +25,6 @@ | |||
25 | #ifndef __TX_H__ | 25 | #ifndef __TX_H__ |
26 | #define __TX_H__ | 26 | #define __TX_H__ |
27 | 27 | ||
28 | #define TX_HW_BLOCK_SPARE 2 | ||
29 | #define TX_HW_BLOCK_SIZE 252 | 28 | #define TX_HW_BLOCK_SIZE 252 |
30 | 29 | ||
31 | #define TX_HW_MGMT_PKT_LIFETIME_TU 2000 | 30 | #define TX_HW_MGMT_PKT_LIFETIME_TU 2000 |
@@ -41,6 +40,7 @@ | |||
41 | BIT(8) | BIT(9)) | 40 | BIT(8) | BIT(9)) |
42 | #define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11)) | 41 | #define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11)) |
43 | #define TX_HW_ATTR_TX_CMPLT_REQ BIT(12) | 42 | #define TX_HW_ATTR_TX_CMPLT_REQ BIT(12) |
43 | #define TX_HW_ATTR_TX_DUMMY_REQ BIT(13) | ||
44 | 44 | ||
45 | #define TX_HW_ATTR_OFST_SAVE_RETRIES 0 | 45 | #define TX_HW_ATTR_OFST_SAVE_RETRIES 0 |
46 | #define TX_HW_ATTR_OFST_HEADER_PAD 1 | 46 | #define TX_HW_ATTR_OFST_HEADER_PAD 1 |
@@ -55,20 +55,60 @@ | |||
55 | #define WL1271_TX_ALIGN_TO 4 | 55 | #define WL1271_TX_ALIGN_TO 4 |
56 | #define WL1271_TKIP_IV_SPACE 4 | 56 | #define WL1271_TKIP_IV_SPACE 4 |
57 | 57 | ||
58 | /* Used for management frames and dummy packets */ | ||
59 | #define WL1271_TID_MGMT 7 | ||
60 | |||
61 | struct wl127x_tx_mem { | ||
62 | /* | ||
63 | * Number of extra memory blocks to allocate for this packet | ||
64 | * in addition to the number of blocks derived from the packet | ||
65 | * length. | ||
66 | */ | ||
67 | u8 extra_blocks; | ||
68 | /* | ||
69 | * Total number of memory blocks allocated by the host for | ||
70 | * this packet. Must be equal or greater than the actual | ||
71 | * blocks number allocated by HW. | ||
72 | */ | ||
73 | u8 total_mem_blocks; | ||
74 | } __packed; | ||
75 | |||
76 | struct wl128x_tx_mem { | ||
77 | /* | ||
78 | * Total number of memory blocks allocated by the host for | ||
79 | * this packet. | ||
80 | */ | ||
81 | u8 total_mem_blocks; | ||
82 | /* | ||
83 | * Number of extra bytes, at the end of the frame. the host | ||
84 | * uses this padding to complete each frame to integer number | ||
85 | * of SDIO blocks. | ||
86 | */ | ||
87 | u8 extra_bytes; | ||
88 | } __packed; | ||
89 | |||
90 | /* | ||
91 | * On wl128x based devices, when TX packets are aggregated, each packet | ||
92 | * size must be aligned to the SDIO block size. The maximum block size | ||
93 | * is bounded by the type of the padded bytes field that is sent to the | ||
94 | * FW. Currently the type is u8, so the maximum block size is 256 bytes. | ||
95 | */ | ||
96 | #define WL12XX_BUS_BLOCK_SIZE min(512u, \ | ||
97 | (1u << (8 * sizeof(((struct wl128x_tx_mem *) 0)->extra_bytes)))) | ||
98 | |||
58 | struct wl1271_tx_hw_descr { | 99 | struct wl1271_tx_hw_descr { |
59 | /* Length of packet in words, including descriptor+header+data */ | 100 | /* Length of packet in words, including descriptor+header+data */ |
60 | __le16 length; | 101 | __le16 length; |
61 | /* Number of extra memory blocks to allocate for this packet in | 102 | union { |
62 | addition to the number of blocks derived from the packet length */ | 103 | struct wl127x_tx_mem wl127x_mem; |
63 | u8 extra_mem_blocks; | 104 | struct wl128x_tx_mem wl128x_mem; |
64 | /* Total number of memory blocks allocated by the host for this packet. | 105 | } __packed; |
65 | Must be equal or greater than the actual blocks number allocated by | ||
66 | HW!! */ | ||
67 | u8 total_mem_blocks; | ||
68 | /* Device time (in us) when the packet arrived to the driver */ | 106 | /* Device time (in us) when the packet arrived to the driver */ |
69 | __le32 start_time; | 107 | __le32 start_time; |
70 | /* Max delay in TUs until transmission. The last device time the | 108 | /* |
71 | packet can be transmitted is: startTime+(1024*LifeTime) */ | 109 | * Max delay in TUs until transmission. The last device time the |
110 | * packet can be transmitted is: start_time + (1024 * life_time) | ||
111 | */ | ||
72 | __le16 life_time; | 112 | __le16 life_time; |
73 | /* Bitwise fields - see TX_ATTR... definitions above. */ | 113 | /* Bitwise fields - see TX_ATTR... definitions above. */ |
74 | __le16 tx_attr; | 114 | __le16 tx_attr; |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 86be83e25ec5..7c521af58e7d 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -131,9 +131,16 @@ extern u32 wl12xx_debug_level; | |||
131 | 131 | ||
132 | 132 | ||
133 | #define WL1271_FW_NAME "ti-connectivity/wl1271-fw-2.bin" | 133 | #define WL1271_FW_NAME "ti-connectivity/wl1271-fw-2.bin" |
134 | #define WL1271_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin" | 134 | #define WL128X_FW_NAME "ti-connectivity/wl128x-fw.bin" |
135 | #define WL127X_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin" | ||
136 | #define WL128X_AP_FW_NAME "ti-connectivity/wl128x-fw-ap.bin" | ||
135 | 137 | ||
136 | #define WL1271_NVS_NAME "ti-connectivity/wl1271-nvs.bin" | 138 | /* |
139 | * wl127x and wl128x are using the same NVS file name. However, the | ||
140 | * ini parameters between them are different. The driver validates | ||
141 | * the correct NVS size in wl1271_boot_upload_nvs(). | ||
142 | */ | ||
143 | #define WL12XX_NVS_NAME "ti-connectivity/wl1271-nvs.bin" | ||
137 | 144 | ||
138 | #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) | 145 | #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) |
139 | #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) | 146 | #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) |
@@ -165,7 +172,6 @@ extern u32 wl12xx_debug_level; | |||
165 | #define WL1271_PS_STA_MAX_BLOCKS (2 * 9) | 172 | #define WL1271_PS_STA_MAX_BLOCKS (2 * 9) |
166 | 173 | ||
167 | #define WL1271_AP_BSS_INDEX 0 | 174 | #define WL1271_AP_BSS_INDEX 0 |
168 | #define WL1271_AP_DEF_INACTIV_SEC 300 | ||
169 | #define WL1271_AP_DEF_BEACON_EXP 20 | 175 | #define WL1271_AP_DEF_BEACON_EXP 20 |
170 | 176 | ||
171 | #define ACX_TX_DESCRIPTORS 32 | 177 | #define ACX_TX_DESCRIPTORS 32 |
@@ -200,13 +206,29 @@ struct wl1271_partition_set { | |||
200 | 206 | ||
201 | struct wl1271; | 207 | struct wl1271; |
202 | 208 | ||
203 | #define WL12XX_NUM_FW_VER 5 | 209 | enum { |
210 | FW_VER_CHIP, | ||
211 | FW_VER_IF_TYPE, | ||
212 | FW_VER_MAJOR, | ||
213 | FW_VER_SUBTYPE, | ||
214 | FW_VER_MINOR, | ||
215 | |||
216 | NUM_FW_VER | ||
217 | }; | ||
218 | |||
219 | #define FW_VER_CHIP_WL127X 6 | ||
220 | #define FW_VER_CHIP_WL128X 7 | ||
221 | |||
222 | #define FW_VER_IF_TYPE_STA 1 | ||
223 | #define FW_VER_IF_TYPE_AP 2 | ||
224 | |||
225 | #define FW_VER_MINOR_1_SPARE_STA_MIN 58 | ||
226 | #define FW_VER_MINOR_1_SPARE_AP_MIN 47 | ||
204 | 227 | ||
205 | /* FIXME: I'm not sure about this structure name */ | ||
206 | struct wl1271_chip { | 228 | struct wl1271_chip { |
207 | u32 id; | 229 | u32 id; |
208 | char fw_ver_str[ETHTOOL_BUSINFO_LEN]; | 230 | char fw_ver_str[ETHTOOL_BUSINFO_LEN]; |
209 | unsigned int fw_ver[WL12XX_NUM_FW_VER]; | 231 | unsigned int fw_ver[NUM_FW_VER]; |
210 | }; | 232 | }; |
211 | 233 | ||
212 | struct wl1271_stats { | 234 | struct wl1271_stats { |
@@ -261,6 +283,8 @@ struct wl1271_fw_sta_status { | |||
261 | u8 tx_total; | 283 | u8 tx_total; |
262 | u8 reserved1; | 284 | u8 reserved1; |
263 | __le16 reserved2; | 285 | __le16 reserved2; |
286 | /* Total structure size is 68 bytes */ | ||
287 | u32 padding; | ||
264 | } __packed; | 288 | } __packed; |
265 | 289 | ||
266 | struct wl1271_fw_full_status { | 290 | struct wl1271_fw_full_status { |
@@ -277,9 +301,10 @@ struct wl1271_rx_mem_pool_addr { | |||
277 | u32 addr_extra; | 301 | u32 addr_extra; |
278 | }; | 302 | }; |
279 | 303 | ||
304 | #define WL1271_MAX_CHANNELS 64 | ||
280 | struct wl1271_scan { | 305 | struct wl1271_scan { |
281 | struct cfg80211_scan_request *req; | 306 | struct cfg80211_scan_request *req; |
282 | bool *scanned_ch; | 307 | unsigned long scanned_ch[BITS_TO_LONGS(WL1271_MAX_CHANNELS)]; |
283 | bool failed; | 308 | bool failed; |
284 | u8 state; | 309 | u8 state; |
285 | u8 ssid[IW_ESSID_MAX_SIZE+1]; | 310 | u8 ssid[IW_ESSID_MAX_SIZE+1]; |
@@ -297,6 +322,7 @@ struct wl1271_if_operations { | |||
297 | struct device* (*dev)(struct wl1271 *wl); | 322 | struct device* (*dev)(struct wl1271 *wl); |
298 | void (*enable_irq)(struct wl1271 *wl); | 323 | void (*enable_irq)(struct wl1271 *wl); |
299 | void (*disable_irq)(struct wl1271 *wl); | 324 | void (*disable_irq)(struct wl1271 *wl); |
325 | void (*set_block_size) (struct wl1271 *wl, unsigned int blksz); | ||
300 | }; | 326 | }; |
301 | 327 | ||
302 | #define MAX_NUM_KEYS 14 | 328 | #define MAX_NUM_KEYS 14 |
@@ -327,7 +353,9 @@ enum wl12xx_flags { | |||
327 | WL1271_FLAG_PSPOLL_FAILURE, | 353 | WL1271_FLAG_PSPOLL_FAILURE, |
328 | WL1271_FLAG_STA_STATE_SENT, | 354 | WL1271_FLAG_STA_STATE_SENT, |
329 | WL1271_FLAG_FW_TX_BUSY, | 355 | WL1271_FLAG_FW_TX_BUSY, |
330 | WL1271_FLAG_AP_STARTED | 356 | WL1271_FLAG_AP_STARTED, |
357 | WL1271_FLAG_IF_INITIALIZED, | ||
358 | WL1271_FLAG_DUMMY_PACKET_PENDING, | ||
331 | }; | 359 | }; |
332 | 360 | ||
333 | struct wl1271_link { | 361 | struct wl1271_link { |
@@ -371,7 +399,7 @@ struct wl1271 { | |||
371 | u8 *fw; | 399 | u8 *fw; |
372 | size_t fw_len; | 400 | size_t fw_len; |
373 | u8 fw_bss_type; | 401 | u8 fw_bss_type; |
374 | struct wl1271_nvs_file *nvs; | 402 | void *nvs; |
375 | size_t nvs_len; | 403 | size_t nvs_len; |
376 | 404 | ||
377 | s8 hw_pg_ver; | 405 | s8 hw_pg_ver; |
@@ -389,6 +417,7 @@ struct wl1271 { | |||
389 | /* Accounting for allocated / available TX blocks on HW */ | 417 | /* Accounting for allocated / available TX blocks on HW */ |
390 | u32 tx_blocks_freed[NUM_TX_QUEUES]; | 418 | u32 tx_blocks_freed[NUM_TX_QUEUES]; |
391 | u32 tx_blocks_available; | 419 | u32 tx_blocks_available; |
420 | u32 tx_allocated_blocks; | ||
392 | u32 tx_results_count; | 421 | u32 tx_results_count; |
393 | 422 | ||
394 | /* Transmitted TX packets counter for chipset interface */ | 423 | /* Transmitted TX packets counter for chipset interface */ |
@@ -430,6 +459,9 @@ struct wl1271 { | |||
430 | /* Intermediate buffer, used for packet aggregation */ | 459 | /* Intermediate buffer, used for packet aggregation */ |
431 | u8 *aggr_buf; | 460 | u8 *aggr_buf; |
432 | 461 | ||
462 | /* Reusable dummy packet template */ | ||
463 | struct sk_buff *dummy_packet; | ||
464 | |||
433 | /* Network stack work */ | 465 | /* Network stack work */ |
434 | struct work_struct netstack_work; | 466 | struct work_struct netstack_work; |
435 | 467 | ||
@@ -527,6 +559,8 @@ struct wl1271 { | |||
527 | bool ba_support; | 559 | bool ba_support; |
528 | u8 ba_rx_bitmap; | 560 | u8 ba_rx_bitmap; |
529 | 561 | ||
562 | int tcxo_clock; | ||
563 | |||
530 | /* | 564 | /* |
531 | * AP-mode - links indexed by HLID. The global and broadcast links | 565 | * AP-mode - links indexed by HLID. The global and broadcast links |
532 | * are always active. | 566 | * are always active. |
@@ -544,6 +578,9 @@ struct wl1271 { | |||
544 | 578 | ||
545 | /* Quirks of specific hardware revisions */ | 579 | /* Quirks of specific hardware revisions */ |
546 | unsigned int quirks; | 580 | unsigned int quirks; |
581 | |||
582 | /* Platform limitations */ | ||
583 | unsigned int platform_quirks; | ||
547 | }; | 584 | }; |
548 | 585 | ||
549 | struct wl1271_station { | 586 | struct wl1271_station { |
@@ -576,6 +613,15 @@ int wl1271_plt_stop(struct wl1271 *wl); | |||
576 | /* Quirks */ | 613 | /* Quirks */ |
577 | 614 | ||
578 | /* Each RX/TX transaction requires an end-of-transaction transfer */ | 615 | /* Each RX/TX transaction requires an end-of-transaction transfer */ |
579 | #define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0) | 616 | #define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0) |
617 | |||
618 | /* | ||
619 | * Older firmwares use 2 spare TX blocks | ||
620 | * (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47) | ||
621 | */ | ||
622 | #define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1) | ||
623 | |||
624 | /* WL128X requires aggregated packets to be aligned to the SDIO block size */ | ||
625 | #define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2) | ||
580 | 626 | ||
581 | #endif | 627 | #endif |
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 7c031fdc8205..06d15b6f2215 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c | |||
@@ -46,40 +46,66 @@ void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, | |||
46 | if (!ccdev) | 46 | if (!ccdev) |
47 | return; | 47 | return; |
48 | bus = ccdev->bus; | 48 | bus = ccdev->bus; |
49 | |||
50 | /* We support SLOW only on 6..9 */ | ||
51 | if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW) | ||
52 | mode = SSB_CLKMODE_DYNAMIC; | ||
53 | |||
54 | if (cc->capabilities & SSB_CHIPCO_CAP_PMU) | ||
55 | return; /* PMU controls clockmode, separated function needed */ | ||
56 | SSB_WARN_ON(ccdev->id.revision >= 20); | ||
57 | |||
49 | /* chipcommon cores prior to rev6 don't support dynamic clock control */ | 58 | /* chipcommon cores prior to rev6 don't support dynamic clock control */ |
50 | if (ccdev->id.revision < 6) | 59 | if (ccdev->id.revision < 6) |
51 | return; | 60 | return; |
52 | /* chipcommon cores rev10 are a whole new ball game */ | 61 | |
62 | /* ChipCommon cores rev10+ need testing */ | ||
53 | if (ccdev->id.revision >= 10) | 63 | if (ccdev->id.revision >= 10) |
54 | return; | 64 | return; |
65 | |||
55 | if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) | 66 | if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) |
56 | return; | 67 | return; |
57 | 68 | ||
58 | switch (mode) { | 69 | switch (mode) { |
59 | case SSB_CLKMODE_SLOW: | 70 | case SSB_CLKMODE_SLOW: /* For revs 6..9 only */ |
60 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); | 71 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); |
61 | tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW; | 72 | tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW; |
62 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); | 73 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); |
63 | break; | 74 | break; |
64 | case SSB_CLKMODE_FAST: | 75 | case SSB_CLKMODE_FAST: |
65 | ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */ | 76 | if (ccdev->id.revision < 10) { |
66 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); | 77 | ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */ |
67 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; | 78 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); |
68 | tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL; | 79 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; |
69 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); | 80 | tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL; |
81 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); | ||
82 | } else { | ||
83 | chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL, | ||
84 | (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) | | ||
85 | SSB_CHIPCO_SYSCLKCTL_FORCEHT)); | ||
86 | /* udelay(150); TODO: not available in early init */ | ||
87 | } | ||
70 | break; | 88 | break; |
71 | case SSB_CLKMODE_DYNAMIC: | 89 | case SSB_CLKMODE_DYNAMIC: |
72 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); | 90 | if (ccdev->id.revision < 10) { |
73 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; | 91 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); |
74 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL; | 92 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; |
75 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL; | 93 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL; |
76 | if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL) | 94 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL; |
77 | tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL; | 95 | if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != |
78 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); | 96 | SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL) |
79 | 97 | tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL; | |
80 | /* for dynamic control, we have to release our xtal_pu "force on" */ | 98 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); |
81 | if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL) | 99 | |
82 | ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0); | 100 | /* For dynamic control, we have to release our xtal_pu |
101 | * "force on" */ | ||
102 | if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL) | ||
103 | ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0); | ||
104 | } else { | ||
105 | chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL, | ||
106 | (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) & | ||
107 | ~SSB_CHIPCO_SYSCLKCTL_FORCEHT)); | ||
108 | } | ||
83 | break; | 109 | break; |
84 | default: | 110 | default: |
85 | SSB_WARN_ON(1); | 111 | SSB_WARN_ON(1); |
@@ -260,6 +286,12 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc) | |||
260 | if (cc->dev->id.revision >= 11) | 286 | if (cc->dev->id.revision >= 11) |
261 | cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); | 287 | cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); |
262 | ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); | 288 | ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); |
289 | |||
290 | if (cc->dev->id.revision >= 20) { | ||
291 | chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0); | ||
292 | chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0); | ||
293 | } | ||
294 | |||
263 | ssb_pmu_init(cc); | 295 | ssb_pmu_init(cc); |
264 | chipco_powercontrol_init(cc); | 296 | chipco_powercontrol_init(cc); |
265 | ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); | 297 | ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 5732bb2c3578..305ade7825f7 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
@@ -423,6 +423,8 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc) | |||
423 | 423 | ||
424 | switch (bus->chip_id) { | 424 | switch (bus->chip_id) { |
425 | case 0x4312: | 425 | case 0x4312: |
426 | min_msk = 0xCBB; | ||
427 | break; | ||
426 | case 0x4322: | 428 | case 0x4322: |
427 | /* We keep the default settings: | 429 | /* We keep the default settings: |
428 | * min_msk = 0xCBB | 430 | * min_msk = 0xCBB |
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 1ba9f0ee6f94..8fde1220bc89 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
@@ -21,6 +21,8 @@ static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address); | |||
21 | static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, | 21 | static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, |
22 | u8 address, u16 data); | 22 | u8 address, u16 data); |
23 | 23 | ||
24 | static void ssb_commit_settings(struct ssb_bus *bus); | ||
25 | |||
24 | static inline | 26 | static inline |
25 | u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) | 27 | u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) |
26 | { | 28 | { |
@@ -412,6 +414,16 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc) | |||
412 | * Workarounds. | 414 | * Workarounds. |
413 | **************************************************/ | 415 | **************************************************/ |
414 | 416 | ||
417 | static void ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc) | ||
418 | { | ||
419 | u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0)); | ||
420 | if (((tmp & 0xF000) >> 12) != pc->dev->core_index) { | ||
421 | tmp &= ~0xF000; | ||
422 | tmp |= (pc->dev->core_index << 12); | ||
423 | pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp); | ||
424 | } | ||
425 | } | ||
426 | |||
415 | static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc) | 427 | static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc) |
416 | { | 428 | { |
417 | return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80; | 429 | return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80; |
@@ -430,6 +442,76 @@ static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc) | |||
430 | ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000); | 442 | ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000); |
431 | } | 443 | } |
432 | 444 | ||
445 | static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc) | ||
446 | { | ||
447 | struct ssb_device *pdev = pc->dev; | ||
448 | struct ssb_bus *bus = pdev->bus; | ||
449 | u32 tmp; | ||
450 | |||
451 | tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); | ||
452 | tmp |= SSB_PCICORE_SBTOPCI_PREF; | ||
453 | tmp |= SSB_PCICORE_SBTOPCI_BURST; | ||
454 | pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp); | ||
455 | |||
456 | if (pdev->id.revision < 5) { | ||
457 | tmp = ssb_read32(pdev, SSB_IMCFGLO); | ||
458 | tmp &= ~SSB_IMCFGLO_SERTO; | ||
459 | tmp |= 2; | ||
460 | tmp &= ~SSB_IMCFGLO_REQTO; | ||
461 | tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT; | ||
462 | ssb_write32(pdev, SSB_IMCFGLO, tmp); | ||
463 | ssb_commit_settings(bus); | ||
464 | } else if (pdev->id.revision >= 11) { | ||
465 | tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); | ||
466 | tmp |= SSB_PCICORE_SBTOPCI_MRM; | ||
467 | pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp); | ||
468 | } | ||
469 | } | ||
470 | |||
471 | static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc) | ||
472 | { | ||
473 | u32 tmp; | ||
474 | u8 rev = pc->dev->id.revision; | ||
475 | |||
476 | if (rev == 0 || rev == 1) { | ||
477 | /* TLP Workaround register. */ | ||
478 | tmp = ssb_pcie_read(pc, 0x4); | ||
479 | tmp |= 0x8; | ||
480 | ssb_pcie_write(pc, 0x4, tmp); | ||
481 | } | ||
482 | if (rev == 1) { | ||
483 | /* DLLP Link Control register. */ | ||
484 | tmp = ssb_pcie_read(pc, 0x100); | ||
485 | tmp |= 0x40; | ||
486 | ssb_pcie_write(pc, 0x100, tmp); | ||
487 | } | ||
488 | |||
489 | if (rev == 0) { | ||
490 | const u8 serdes_rx_device = 0x1F; | ||
491 | |||
492 | ssb_pcie_mdio_write(pc, serdes_rx_device, | ||
493 | 2 /* Timer */, 0x8128); | ||
494 | ssb_pcie_mdio_write(pc, serdes_rx_device, | ||
495 | 6 /* CDR */, 0x0100); | ||
496 | ssb_pcie_mdio_write(pc, serdes_rx_device, | ||
497 | 7 /* CDR BW */, 0x1466); | ||
498 | } else if (rev == 3 || rev == 4 || rev == 5) { | ||
499 | /* TODO: DLLP Power Management Threshold */ | ||
500 | ssb_pcicore_serdes_workaround(pc); | ||
501 | /* TODO: ASPM */ | ||
502 | } else if (rev == 7) { | ||
503 | /* TODO: No PLL down */ | ||
504 | } | ||
505 | |||
506 | if (rev >= 6) { | ||
507 | /* Miscellaneous Configuration Fixup */ | ||
508 | tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5)); | ||
509 | if (!(tmp & 0x8000)) | ||
510 | pcicore_write16(pc, SSB_PCICORE_SPROM(5), | ||
511 | tmp | 0x8000); | ||
512 | } | ||
513 | } | ||
514 | |||
433 | /************************************************** | 515 | /************************************************** |
434 | * Generic and Clientmode operation code. | 516 | * Generic and Clientmode operation code. |
435 | **************************************************/ | 517 | **************************************************/ |
@@ -449,6 +531,8 @@ void ssb_pcicore_init(struct ssb_pcicore *pc) | |||
449 | if (!ssb_device_is_enabled(dev)) | 531 | if (!ssb_device_is_enabled(dev)) |
450 | ssb_device_enable(dev, 0); | 532 | ssb_device_enable(dev, 0); |
451 | 533 | ||
534 | ssb_pcicore_fix_sprom_core_index(pc); | ||
535 | |||
452 | #ifdef CONFIG_SSB_PCICORE_HOSTMODE | 536 | #ifdef CONFIG_SSB_PCICORE_HOSTMODE |
453 | pc->hostmode = pcicore_is_in_hostmode(pc); | 537 | pc->hostmode = pcicore_is_in_hostmode(pc); |
454 | if (pc->hostmode) | 538 | if (pc->hostmode) |
@@ -457,7 +541,10 @@ void ssb_pcicore_init(struct ssb_pcicore *pc) | |||
457 | if (!pc->hostmode) | 541 | if (!pc->hostmode) |
458 | ssb_pcicore_init_clientmode(pc); | 542 | ssb_pcicore_init_clientmode(pc); |
459 | 543 | ||
544 | /* Additional always once-executed workarounds */ | ||
460 | ssb_pcicore_serdes_workaround(pc); | 545 | ssb_pcicore_serdes_workaround(pc); |
546 | /* TODO: ASPM */ | ||
547 | /* TODO: Clock Request Update */ | ||
461 | } | 548 | } |
462 | 549 | ||
463 | static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) | 550 | static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) |
@@ -522,7 +609,7 @@ static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address) | |||
522 | pcicore_write32(pc, mdio_data, v); | 609 | pcicore_write32(pc, mdio_data, v); |
523 | /* Wait for the device to complete the transaction */ | 610 | /* Wait for the device to complete the transaction */ |
524 | udelay(10); | 611 | udelay(10); |
525 | for (i = 0; i < 200; i++) { | 612 | for (i = 0; i < max_retries; i++) { |
526 | v = pcicore_read32(pc, mdio_control); | 613 | v = pcicore_read32(pc, mdio_control); |
527 | if (v & 0x100 /* Trans complete */) { | 614 | if (v & 0x100 /* Trans complete */) { |
528 | udelay(10); | 615 | udelay(10); |
@@ -646,48 +733,10 @@ int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, | |||
646 | if (pc->setup_done) | 733 | if (pc->setup_done) |
647 | goto out; | 734 | goto out; |
648 | if (pdev->id.coreid == SSB_DEV_PCI) { | 735 | if (pdev->id.coreid == SSB_DEV_PCI) { |
649 | tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); | 736 | ssb_pcicore_pci_setup_workarounds(pc); |
650 | tmp |= SSB_PCICORE_SBTOPCI_PREF; | ||
651 | tmp |= SSB_PCICORE_SBTOPCI_BURST; | ||
652 | pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp); | ||
653 | |||
654 | if (pdev->id.revision < 5) { | ||
655 | tmp = ssb_read32(pdev, SSB_IMCFGLO); | ||
656 | tmp &= ~SSB_IMCFGLO_SERTO; | ||
657 | tmp |= 2; | ||
658 | tmp &= ~SSB_IMCFGLO_REQTO; | ||
659 | tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT; | ||
660 | ssb_write32(pdev, SSB_IMCFGLO, tmp); | ||
661 | ssb_commit_settings(bus); | ||
662 | } else if (pdev->id.revision >= 11) { | ||
663 | tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); | ||
664 | tmp |= SSB_PCICORE_SBTOPCI_MRM; | ||
665 | pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp); | ||
666 | } | ||
667 | } else { | 737 | } else { |
668 | WARN_ON(pdev->id.coreid != SSB_DEV_PCIE); | 738 | WARN_ON(pdev->id.coreid != SSB_DEV_PCIE); |
669 | //TODO: Better make defines for all these magic PCIE values. | 739 | ssb_pcicore_pcie_setup_workarounds(pc); |
670 | if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) { | ||
671 | /* TLP Workaround register. */ | ||
672 | tmp = ssb_pcie_read(pc, 0x4); | ||
673 | tmp |= 0x8; | ||
674 | ssb_pcie_write(pc, 0x4, tmp); | ||
675 | } | ||
676 | if (pdev->id.revision == 0) { | ||
677 | const u8 serdes_rx_device = 0x1F; | ||
678 | |||
679 | ssb_pcie_mdio_write(pc, serdes_rx_device, | ||
680 | 2 /* Timer */, 0x8128); | ||
681 | ssb_pcie_mdio_write(pc, serdes_rx_device, | ||
682 | 6 /* CDR */, 0x0100); | ||
683 | ssb_pcie_mdio_write(pc, serdes_rx_device, | ||
684 | 7 /* CDR BW */, 0x1466); | ||
685 | } else if (pdev->id.revision == 1) { | ||
686 | /* DLLP Link Control register. */ | ||
687 | tmp = ssb_pcie_read(pc, 0x100); | ||
688 | tmp |= 0x40; | ||
689 | ssb_pcie_write(pc, 0x100, tmp); | ||
690 | } | ||
691 | } | 740 | } |
692 | pc->setup_done = 1; | 741 | pc->setup_done = 1; |
693 | out: | 742 | out: |
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index e05ba6eefc7e..ad3da93a428c 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -1117,23 +1117,22 @@ static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev) | |||
1117 | { | 1117 | { |
1118 | u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV; | 1118 | u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV; |
1119 | 1119 | ||
1120 | /* The REJECT bit changed position in TMSLOW between | 1120 | /* The REJECT bit seems to be different for Backplane rev 2.3 */ |
1121 | * Backplane revisions. */ | ||
1122 | switch (rev) { | 1121 | switch (rev) { |
1123 | case SSB_IDLOW_SSBREV_22: | 1122 | case SSB_IDLOW_SSBREV_22: |
1124 | return SSB_TMSLOW_REJECT_22; | 1123 | case SSB_IDLOW_SSBREV_24: |
1124 | case SSB_IDLOW_SSBREV_26: | ||
1125 | return SSB_TMSLOW_REJECT; | ||
1125 | case SSB_IDLOW_SSBREV_23: | 1126 | case SSB_IDLOW_SSBREV_23: |
1126 | return SSB_TMSLOW_REJECT_23; | 1127 | return SSB_TMSLOW_REJECT_23; |
1127 | case SSB_IDLOW_SSBREV_24: /* TODO - find the proper REJECT bits */ | 1128 | case SSB_IDLOW_SSBREV_25: /* TODO - find the proper REJECT bit */ |
1128 | case SSB_IDLOW_SSBREV_25: /* same here */ | ||
1129 | case SSB_IDLOW_SSBREV_26: /* same here */ | ||
1130 | case SSB_IDLOW_SSBREV_27: /* same here */ | 1129 | case SSB_IDLOW_SSBREV_27: /* same here */ |
1131 | return SSB_TMSLOW_REJECT_23; /* this is a guess */ | 1130 | return SSB_TMSLOW_REJECT; /* this is a guess */ |
1132 | default: | 1131 | default: |
1133 | printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev); | 1132 | printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev); |
1134 | WARN_ON(1); | 1133 | WARN_ON(1); |
1135 | } | 1134 | } |
1136 | return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23); | 1135 | return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23); |
1137 | } | 1136 | } |
1138 | 1137 | ||
1139 | int ssb_device_is_enabled(struct ssb_device *dev) | 1138 | int ssb_device_is_enabled(struct ssb_device *dev) |
@@ -1309,20 +1308,20 @@ EXPORT_SYMBOL(ssb_bus_may_powerdown); | |||
1309 | 1308 | ||
1310 | int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl) | 1309 | int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl) |
1311 | { | 1310 | { |
1312 | struct ssb_chipcommon *cc; | ||
1313 | int err; | 1311 | int err; |
1314 | enum ssb_clkmode mode; | 1312 | enum ssb_clkmode mode; |
1315 | 1313 | ||
1316 | err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); | 1314 | err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); |
1317 | if (err) | 1315 | if (err) |
1318 | goto error; | 1316 | goto error; |
1319 | cc = &bus->chipco; | ||
1320 | mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST; | ||
1321 | ssb_chipco_set_clockmode(cc, mode); | ||
1322 | 1317 | ||
1323 | #ifdef CONFIG_SSB_DEBUG | 1318 | #ifdef CONFIG_SSB_DEBUG |
1324 | bus->powered_up = 1; | 1319 | bus->powered_up = 1; |
1325 | #endif | 1320 | #endif |
1321 | |||
1322 | mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST; | ||
1323 | ssb_chipco_set_clockmode(&bus->chipco, mode); | ||
1324 | |||
1326 | return 0; | 1325 | return 0; |
1327 | error: | 1326 | error: |
1328 | ssb_printk(KERN_ERR PFX "Bus powerup failed\n"); | 1327 | ssb_printk(KERN_ERR PFX "Bus powerup failed\n"); |
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index 020387a114e3..60a7c49dcb49 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h | |||
@@ -28,6 +28,8 @@ struct ath9k_platform_data { | |||
28 | int led_pin; | 28 | int led_pin; |
29 | u32 gpio_mask; | 29 | u32 gpio_mask; |
30 | u32 gpio_val; | 30 | u32 gpio_val; |
31 | |||
32 | bool is_clk_25mhz; | ||
31 | }; | 33 | }; |
32 | 34 | ||
33 | #endif /* _LINUX_ATH9K_PLATFORM_H */ | 35 | #endif /* _LINUX_ATH9K_PLATFORM_H */ |
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 2cdf249b4e5f..a08d693d8324 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h | |||
@@ -123,6 +123,8 @@ | |||
123 | #define SSB_CHIPCO_FLASHDATA 0x0048 | 123 | #define SSB_CHIPCO_FLASHDATA 0x0048 |
124 | #define SSB_CHIPCO_BCAST_ADDR 0x0050 | 124 | #define SSB_CHIPCO_BCAST_ADDR 0x0050 |
125 | #define SSB_CHIPCO_BCAST_DATA 0x0054 | 125 | #define SSB_CHIPCO_BCAST_DATA 0x0054 |
126 | #define SSB_CHIPCO_GPIOPULLUP 0x0058 /* Rev >= 20 only */ | ||
127 | #define SSB_CHIPCO_GPIOPULLDOWN 0x005C /* Rev >= 20 only */ | ||
126 | #define SSB_CHIPCO_GPIOIN 0x0060 | 128 | #define SSB_CHIPCO_GPIOIN 0x0060 |
127 | #define SSB_CHIPCO_GPIOOUT 0x0064 | 129 | #define SSB_CHIPCO_GPIOOUT 0x0064 |
128 | #define SSB_CHIPCO_GPIOOUTEN 0x0068 | 130 | #define SSB_CHIPCO_GPIOOUTEN 0x0068 |
@@ -131,6 +133,9 @@ | |||
131 | #define SSB_CHIPCO_GPIOIRQ 0x0074 | 133 | #define SSB_CHIPCO_GPIOIRQ 0x0074 |
132 | #define SSB_CHIPCO_WATCHDOG 0x0080 | 134 | #define SSB_CHIPCO_WATCHDOG 0x0080 |
133 | #define SSB_CHIPCO_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */ | 135 | #define SSB_CHIPCO_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */ |
136 | #define SSB_CHIPCO_GPIOTIMER_OFFTIME 0x0000FFFF | ||
137 | #define SSB_CHIPCO_GPIOTIMER_OFFTIME_SHIFT 0 | ||
138 | #define SSB_CHIPCO_GPIOTIMER_ONTIME 0xFFFF0000 | ||
134 | #define SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT 16 | 139 | #define SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT 16 |
135 | #define SSB_CHIPCO_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */ | 140 | #define SSB_CHIPCO_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */ |
136 | #define SSB_CHIPCO_CLOCK_N 0x0090 | 141 | #define SSB_CHIPCO_CLOCK_N 0x0090 |
@@ -189,8 +194,10 @@ | |||
189 | #define SSB_CHIPCO_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */ | 194 | #define SSB_CHIPCO_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */ |
190 | #define SSB_CHIPCO_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */ | 195 | #define SSB_CHIPCO_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */ |
191 | #define SSB_CHIPCO_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */ | 196 | #define SSB_CHIPCO_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */ |
192 | #define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00010000 /* HT available */ | 197 | #define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00010000 /* ALP available */ |
193 | #define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00020000 /* APL available */ | 198 | #define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00020000 /* HT available */ |
199 | #define SSB_CHIPCO_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */ | ||
200 | #define SSB_CHIPCO_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */ | ||
194 | #define SSB_CHIPCO_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */ | 201 | #define SSB_CHIPCO_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */ |
195 | #define SSB_CHIPCO_UART0_DATA 0x0300 | 202 | #define SSB_CHIPCO_UART0_DATA 0x0300 |
196 | #define SSB_CHIPCO_UART0_IMR 0x0304 | 203 | #define SSB_CHIPCO_UART0_IMR 0x0304 |
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index 402955ae48ce..efbf459d571c 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h | |||
@@ -97,7 +97,7 @@ | |||
97 | #define SSB_INTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */ | 97 | #define SSB_INTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */ |
98 | #define SSB_TMSLOW 0x0F98 /* SB Target State Low */ | 98 | #define SSB_TMSLOW 0x0F98 /* SB Target State Low */ |
99 | #define SSB_TMSLOW_RESET 0x00000001 /* Reset */ | 99 | #define SSB_TMSLOW_RESET 0x00000001 /* Reset */ |
100 | #define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */ | 100 | #define SSB_TMSLOW_REJECT 0x00000002 /* Reject (Standard Backplane) */ |
101 | #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */ | 101 | #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */ |
102 | #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */ | 102 | #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */ |
103 | #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ | 103 | #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ |
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index bebb8efea0a6..4b697395326e 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h | |||
@@ -24,12 +24,26 @@ | |||
24 | #ifndef _LINUX_WL12XX_H | 24 | #ifndef _LINUX_WL12XX_H |
25 | #define _LINUX_WL12XX_H | 25 | #define _LINUX_WL12XX_H |
26 | 26 | ||
27 | /* The board reference clock values */ | 27 | /* Reference clock values */ |
28 | enum { | 28 | enum { |
29 | WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ | 29 | WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ |
30 | WL12XX_REFCLOCK_26 = 1, /* 26 MHz */ | 30 | WL12XX_REFCLOCK_26 = 1, /* 26 MHz */ |
31 | WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */ | 31 | WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */ |
32 | WL12XX_REFCLOCK_54 = 3, /* 54 MHz */ | 32 | WL12XX_REFCLOCK_52 = 3, /* 52 MHz */ |
33 | WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */ | ||
34 | WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */ | ||
35 | }; | ||
36 | |||
37 | /* TCXO clock values */ | ||
38 | enum { | ||
39 | WL12XX_TCXOCLOCK_19_2 = 0, /* 19.2MHz */ | ||
40 | WL12XX_TCXOCLOCK_26 = 1, /* 26 MHz */ | ||
41 | WL12XX_TCXOCLOCK_38_4 = 2, /* 38.4MHz */ | ||
42 | WL12XX_TCXOCLOCK_52 = 3, /* 52 MHz */ | ||
43 | WL12XX_TCXOCLOCK_16_368 = 4, /* 16.368 MHz */ | ||
44 | WL12XX_TCXOCLOCK_32_736 = 5, /* 32.736 MHz */ | ||
45 | WL12XX_TCXOCLOCK_16_8 = 6, /* 16.8 MHz */ | ||
46 | WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */ | ||
33 | }; | 47 | }; |
34 | 48 | ||
35 | struct wl12xx_platform_data { | 49 | struct wl12xx_platform_data { |
@@ -38,8 +52,13 @@ struct wl12xx_platform_data { | |||
38 | int irq; | 52 | int irq; |
39 | bool use_eeprom; | 53 | bool use_eeprom; |
40 | int board_ref_clock; | 54 | int board_ref_clock; |
55 | int board_tcxo_clock; | ||
56 | unsigned long platform_quirks; | ||
41 | }; | 57 | }; |
42 | 58 | ||
59 | /* Platform does not support level trigger interrupts */ | ||
60 | #define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0) | ||
61 | |||
43 | #ifdef CONFIG_WL12XX_PLATFORM_DATA | 62 | #ifdef CONFIG_WL12XX_PLATFORM_DATA |
44 | 63 | ||
45 | int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); | 64 | int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 499b7b7c7c9a..0c20227e57f6 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -246,6 +246,15 @@ enum { | |||
246 | #define HCI_AT_GENERAL_BONDING 0x04 | 246 | #define HCI_AT_GENERAL_BONDING 0x04 |
247 | #define HCI_AT_GENERAL_BONDING_MITM 0x05 | 247 | #define HCI_AT_GENERAL_BONDING_MITM 0x05 |
248 | 248 | ||
249 | /* Link Key types */ | ||
250 | #define HCI_LK_COMBINATION 0x00 | ||
251 | #define HCI_LK_LOCAL_UNIT 0x01 | ||
252 | #define HCI_LK_REMOTE_UNIT 0x02 | ||
253 | #define HCI_LK_DEBUG_COMBINATION 0x03 | ||
254 | #define HCI_LK_UNAUTH_COMBINATION 0x04 | ||
255 | #define HCI_LK_AUTH_COMBINATION 0x05 | ||
256 | #define HCI_LK_CHANGED_COMBINATION 0x06 | ||
257 | |||
249 | /* ----- HCI Commands ---- */ | 258 | /* ----- HCI Commands ---- */ |
250 | #define HCI_OP_NOP 0x0000 | 259 | #define HCI_OP_NOP 0x0000 |
251 | 260 | ||
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 4093133c1283..14cc3249c1eb 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -126,6 +126,8 @@ struct hci_dev { | |||
126 | __u16 sniff_min_interval; | 126 | __u16 sniff_min_interval; |
127 | __u16 sniff_max_interval; | 127 | __u16 sniff_max_interval; |
128 | 128 | ||
129 | unsigned int auto_accept_delay; | ||
130 | |||
129 | unsigned long quirks; | 131 | unsigned long quirks; |
130 | 132 | ||
131 | atomic_t cmd_cnt; | 133 | atomic_t cmd_cnt; |
@@ -226,6 +228,7 @@ struct hci_conn { | |||
226 | __u16 pkt_type; | 228 | __u16 pkt_type; |
227 | __u16 link_policy; | 229 | __u16 link_policy; |
228 | __u32 link_mode; | 230 | __u32 link_mode; |
231 | __u8 key_type; | ||
229 | __u8 auth_type; | 232 | __u8 auth_type; |
230 | __u8 sec_level; | 233 | __u8 sec_level; |
231 | __u8 pending_sec_level; | 234 | __u8 pending_sec_level; |
@@ -245,6 +248,7 @@ struct hci_conn { | |||
245 | 248 | ||
246 | struct timer_list disc_timer; | 249 | struct timer_list disc_timer; |
247 | struct timer_list idle_timer; | 250 | struct timer_list idle_timer; |
251 | struct timer_list auto_accept_timer; | ||
248 | 252 | ||
249 | struct work_struct work_add; | 253 | struct work_struct work_add; |
250 | struct work_struct work_del; | 254 | struct work_struct work_del; |
@@ -511,8 +515,8 @@ int hci_uuids_clear(struct hci_dev *hdev); | |||
511 | 515 | ||
512 | int hci_link_keys_clear(struct hci_dev *hdev); | 516 | int hci_link_keys_clear(struct hci_dev *hdev); |
513 | struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); | 517 | struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); |
514 | int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | 518 | int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, |
515 | u8 *key, u8 type, u8 pin_len); | 519 | bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len); |
516 | int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); | 520 | int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); |
517 | 521 | ||
518 | int hci_remote_oob_data_clear(struct hci_dev *hdev); | 522 | int hci_remote_oob_data_clear(struct hci_dev *hdev); |
@@ -771,15 +775,16 @@ int mgmt_index_removed(u16 index); | |||
771 | int mgmt_powered(u16 index, u8 powered); | 775 | int mgmt_powered(u16 index, u8 powered); |
772 | int mgmt_discoverable(u16 index, u8 discoverable); | 776 | int mgmt_discoverable(u16 index, u8 discoverable); |
773 | int mgmt_connectable(u16 index, u8 connectable); | 777 | int mgmt_connectable(u16 index, u8 connectable); |
774 | int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type); | 778 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent); |
775 | int mgmt_connected(u16 index, bdaddr_t *bdaddr); | 779 | int mgmt_connected(u16 index, bdaddr_t *bdaddr); |
776 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr); | 780 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr); |
777 | int mgmt_disconnect_failed(u16 index); | 781 | int mgmt_disconnect_failed(u16 index); |
778 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status); | 782 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status); |
779 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr); | 783 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure); |
780 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | 784 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); |
781 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | 785 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); |
782 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value); | 786 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value, |
787 | u8 confirm_hint); | ||
783 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | 788 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); |
784 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, | 789 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, |
785 | u8 status); | 790 | u8 status); |
@@ -790,6 +795,7 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | |||
790 | int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, | 795 | int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, |
791 | u8 *eir); | 796 | u8 *eir); |
792 | int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name); | 797 | int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name); |
798 | int mgmt_discovering(u16 index, u8 discovering); | ||
793 | 799 | ||
794 | /* HCI info for socket */ | 800 | /* HCI info for socket */ |
795 | #define hci_pi(sk) ((struct hci_pinfo *) sk) | 801 | #define hci_pi(sk) ((struct hci_pinfo *) sk) |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7a215a7f9e39..c34b1c126363 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -284,6 +284,25 @@ struct srej_list { | |||
284 | 284 | ||
285 | struct l2cap_chan { | 285 | struct l2cap_chan { |
286 | struct sock *sk; | 286 | struct sock *sk; |
287 | |||
288 | struct l2cap_conn *conn; | ||
289 | |||
290 | __le16 psm; | ||
291 | __u16 dcid; | ||
292 | __u16 scid; | ||
293 | |||
294 | __u16 imtu; | ||
295 | __u16 omtu; | ||
296 | __u16 flush_to; | ||
297 | __u8 mode; | ||
298 | |||
299 | __le16 sport; | ||
300 | |||
301 | __u8 sec_level; | ||
302 | __u8 role_switch; | ||
303 | __u8 force_reliable; | ||
304 | __u8 flushable; | ||
305 | |||
287 | __u8 ident; | 306 | __u8 ident; |
288 | 307 | ||
289 | __u8 conf_req[64]; | 308 | __u8 conf_req[64]; |
@@ -291,6 +310,15 @@ struct l2cap_chan { | |||
291 | __u8 num_conf_req; | 310 | __u8 num_conf_req; |
292 | __u8 num_conf_rsp; | 311 | __u8 num_conf_rsp; |
293 | 312 | ||
313 | __u8 fcs; | ||
314 | |||
315 | __u8 tx_win; | ||
316 | __u8 max_tx; | ||
317 | __u16 retrans_timeout; | ||
318 | __u16 monitor_timeout; | ||
319 | __u16 mps; | ||
320 | |||
321 | __u8 conf_state; | ||
294 | __u16 conn_state; | 322 | __u16 conn_state; |
295 | 323 | ||
296 | __u8 next_tx_seq; | 324 | __u8 next_tx_seq; |
@@ -360,32 +388,6 @@ struct l2cap_conn { | |||
360 | 388 | ||
361 | struct l2cap_pinfo { | 389 | struct l2cap_pinfo { |
362 | struct bt_sock bt; | 390 | struct bt_sock bt; |
363 | __le16 psm; | ||
364 | __u16 dcid; | ||
365 | __u16 scid; | ||
366 | |||
367 | __u16 imtu; | ||
368 | __u16 omtu; | ||
369 | __u16 flush_to; | ||
370 | __u8 mode; | ||
371 | |||
372 | __u8 fcs; | ||
373 | __u8 sec_level; | ||
374 | __u8 role_switch; | ||
375 | __u8 force_reliable; | ||
376 | __u8 flushable; | ||
377 | |||
378 | __u8 conf_state; | ||
379 | |||
380 | __u8 tx_win; | ||
381 | __u8 max_tx; | ||
382 | __u16 retrans_timeout; | ||
383 | __u16 monitor_timeout; | ||
384 | __u16 mps; | ||
385 | |||
386 | __le16 sport; | ||
387 | |||
388 | struct l2cap_conn *conn; | ||
389 | struct l2cap_chan *chan; | 391 | struct l2cap_chan *chan; |
390 | }; | 392 | }; |
391 | 393 | ||
@@ -439,21 +441,20 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch) | |||
439 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) | 441 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) |
440 | 442 | ||
441 | extern int disable_ertm; | 443 | extern int disable_ertm; |
442 | extern const struct proto_ops l2cap_sock_ops; | ||
443 | extern struct bt_sock_list l2cap_sk_list; | 444 | extern struct bt_sock_list l2cap_sk_list; |
444 | 445 | ||
445 | int l2cap_init_sockets(void); | 446 | int l2cap_init_sockets(void); |
446 | void l2cap_cleanup_sockets(void); | 447 | void l2cap_cleanup_sockets(void); |
447 | 448 | ||
448 | void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); | 449 | void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); |
449 | void __l2cap_connect_rsp_defer(struct sock *sk); | 450 | void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); |
450 | int __l2cap_wait_ack(struct sock *sk); | 451 | int __l2cap_wait_ack(struct sock *sk); |
451 | 452 | ||
452 | struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len); | 453 | struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); |
453 | struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len); | 454 | struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); |
454 | struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen); | 455 | struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen); |
455 | int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); | 456 | int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); |
456 | void l2cap_do_send(struct sock *sk, struct sk_buff *skb); | 457 | void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb); |
457 | void l2cap_streaming_send(struct l2cap_chan *chan); | 458 | void l2cap_streaming_send(struct l2cap_chan *chan); |
458 | int l2cap_ertm_send(struct l2cap_chan *chan); | 459 | int l2cap_ertm_send(struct l2cap_chan *chan); |
459 | 460 | ||
@@ -465,7 +466,9 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent); | |||
465 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | 466 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, |
466 | int proto, gfp_t prio); | 467 | int proto, gfp_t prio); |
467 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); | 468 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); |
469 | struct l2cap_chan *l2cap_chan_alloc(struct sock *sk); | ||
468 | void l2cap_chan_del(struct l2cap_chan *chan, int err); | 470 | void l2cap_chan_del(struct l2cap_chan *chan, int err); |
469 | int l2cap_do_connect(struct sock *sk); | 471 | void l2cap_chan_free(struct l2cap_chan *chan); |
472 | int l2cap_chan_connect(struct l2cap_chan *chan); | ||
470 | 473 | ||
471 | #endif /* __L2CAP_H */ | 474 | #endif /* __L2CAP_H */ |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 6b6ff92ab499..4899286ed4e4 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -195,6 +195,10 @@ struct mgmt_cp_remove_remote_oob_data { | |||
195 | bdaddr_t bdaddr; | 195 | bdaddr_t bdaddr; |
196 | } __packed; | 196 | } __packed; |
197 | 197 | ||
198 | #define MGMT_OP_START_DISCOVERY 0x001B | ||
199 | |||
200 | #define MGMT_OP_STOP_DISCOVERY 0x001C | ||
201 | |||
198 | #define MGMT_EV_CMD_COMPLETE 0x0001 | 202 | #define MGMT_EV_CMD_COMPLETE 0x0001 |
199 | struct mgmt_ev_cmd_complete { | 203 | struct mgmt_ev_cmd_complete { |
200 | __le16 opcode; | 204 | __le16 opcode; |
@@ -226,8 +230,8 @@ struct mgmt_ev_controller_error { | |||
226 | 230 | ||
227 | #define MGMT_EV_NEW_KEY 0x000A | 231 | #define MGMT_EV_NEW_KEY 0x000A |
228 | struct mgmt_ev_new_key { | 232 | struct mgmt_ev_new_key { |
233 | __u8 store_hint; | ||
229 | struct mgmt_key_info key; | 234 | struct mgmt_key_info key; |
230 | __u8 old_key_type; | ||
231 | } __packed; | 235 | } __packed; |
232 | 236 | ||
233 | #define MGMT_EV_CONNECTED 0x000B | 237 | #define MGMT_EV_CONNECTED 0x000B |
@@ -249,11 +253,13 @@ struct mgmt_ev_connect_failed { | |||
249 | #define MGMT_EV_PIN_CODE_REQUEST 0x000E | 253 | #define MGMT_EV_PIN_CODE_REQUEST 0x000E |
250 | struct mgmt_ev_pin_code_request { | 254 | struct mgmt_ev_pin_code_request { |
251 | bdaddr_t bdaddr; | 255 | bdaddr_t bdaddr; |
256 | __u8 secure; | ||
252 | } __packed; | 257 | } __packed; |
253 | 258 | ||
254 | #define MGMT_EV_USER_CONFIRM_REQUEST 0x000F | 259 | #define MGMT_EV_USER_CONFIRM_REQUEST 0x000F |
255 | struct mgmt_ev_user_confirm_request { | 260 | struct mgmt_ev_user_confirm_request { |
256 | bdaddr_t bdaddr; | 261 | bdaddr_t bdaddr; |
262 | __u8 confirm_hint; | ||
257 | __le32 value; | 263 | __le32 value; |
258 | } __packed; | 264 | } __packed; |
259 | 265 | ||
@@ -281,3 +287,5 @@ struct mgmt_ev_remote_name { | |||
281 | bdaddr_t bdaddr; | 287 | bdaddr_t bdaddr; |
282 | __u8 name[MGMT_MAX_NAME_LENGTH]; | 288 | __u8 name[MGMT_MAX_NAME_LENGTH]; |
283 | } __packed; | 289 | } __packed; |
290 | |||
291 | #define MGMT_EV_DISCOVERING 0x0014 | ||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d23dd6c1329c..db4b6b9f3977 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1822,6 +1822,10 @@ enum ieee80211_ampdu_mlme_action { | |||
1822 | * | 1822 | * |
1823 | * @tx_frames_pending: Check if there is any pending frame in the hardware | 1823 | * @tx_frames_pending: Check if there is any pending frame in the hardware |
1824 | * queues before entering power save. | 1824 | * queues before entering power save. |
1825 | * | ||
1826 | * @set_bitrate_mask: Set a mask of rates to be used for rate control selection | ||
1827 | * when transmitting a frame. Currently only legacy rates are handled. | ||
1828 | * The callback can sleep. | ||
1825 | */ | 1829 | */ |
1826 | struct ieee80211_ops { | 1830 | struct ieee80211_ops { |
1827 | void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); | 1831 | void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); |
@@ -1910,6 +1914,8 @@ struct ieee80211_ops { | |||
1910 | void (*get_ringparam)(struct ieee80211_hw *hw, | 1914 | void (*get_ringparam)(struct ieee80211_hw *hw, |
1911 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); | 1915 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); |
1912 | bool (*tx_frames_pending)(struct ieee80211_hw *hw); | 1916 | bool (*tx_frames_pending)(struct ieee80211_hw *hw); |
1917 | int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
1918 | const struct cfg80211_bitrate_mask *mask); | ||
1913 | }; | 1919 | }; |
1914 | 1920 | ||
1915 | /** | 1921 | /** |
@@ -2292,6 +2298,17 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | |||
2292 | struct sk_buff *skb); | 2298 | struct sk_buff *skb); |
2293 | 2299 | ||
2294 | /** | 2300 | /** |
2301 | * ieee80211_report_low_ack - report non-responding station | ||
2302 | * | ||
2303 | * When operating in AP-mode, call this function to report a non-responding | ||
2304 | * connected STA. | ||
2305 | * | ||
2306 | * @sta: the non-responding connected sta | ||
2307 | * @num_packets: number of packets sent to @sta without a response | ||
2308 | */ | ||
2309 | void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets); | ||
2310 | |||
2311 | /** | ||
2295 | * ieee80211_beacon_get_tim - beacon generation function | 2312 | * ieee80211_beacon_get_tim - beacon generation function |
2296 | * @hw: pointer obtained from ieee80211_alloc_hw(). | 2313 | * @hw: pointer obtained from ieee80211_alloc_hw(). |
2297 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | 2314 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index cce99b0919f5..c5b11af908be 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -346,7 +346,8 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
346 | 346 | ||
347 | bacpy(&session->bdaddr, &bt_sk(sock->sk)->dst); | 347 | bacpy(&session->bdaddr, &bt_sk(sock->sk)->dst); |
348 | 348 | ||
349 | session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu); | 349 | session->mtu = min_t(uint, l2cap_pi(sock->sk)->chan->omtu, |
350 | l2cap_pi(sock->sk)->chan->imtu); | ||
350 | 351 | ||
351 | BT_DBG("mtu %d", session->mtu); | 352 | BT_DBG("mtu %d", session->mtu); |
352 | 353 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 7a6f56b2f49d..7f5ad8a2b22d 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -269,6 +269,19 @@ static void hci_conn_idle(unsigned long arg) | |||
269 | hci_conn_enter_sniff_mode(conn); | 269 | hci_conn_enter_sniff_mode(conn); |
270 | } | 270 | } |
271 | 271 | ||
272 | static void hci_conn_auto_accept(unsigned long arg) | ||
273 | { | ||
274 | struct hci_conn *conn = (void *) arg; | ||
275 | struct hci_dev *hdev = conn->hdev; | ||
276 | |||
277 | hci_dev_lock(hdev); | ||
278 | |||
279 | hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst), | ||
280 | &conn->dst); | ||
281 | |||
282 | hci_dev_unlock(hdev); | ||
283 | } | ||
284 | |||
272 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | 285 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) |
273 | { | 286 | { |
274 | struct hci_conn *conn; | 287 | struct hci_conn *conn; |
@@ -287,6 +300,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
287 | conn->auth_type = HCI_AT_GENERAL_BONDING; | 300 | conn->auth_type = HCI_AT_GENERAL_BONDING; |
288 | conn->io_capability = hdev->io_capability; | 301 | conn->io_capability = hdev->io_capability; |
289 | conn->remote_auth = 0xff; | 302 | conn->remote_auth = 0xff; |
303 | conn->key_type = 0xff; | ||
290 | 304 | ||
291 | conn->power_save = 1; | 305 | conn->power_save = 1; |
292 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 306 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
@@ -311,6 +325,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
311 | 325 | ||
312 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); | 326 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); |
313 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); | 327 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); |
328 | setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, | ||
329 | (unsigned long) conn); | ||
314 | 330 | ||
315 | atomic_set(&conn->refcnt, 0); | 331 | atomic_set(&conn->refcnt, 0); |
316 | 332 | ||
@@ -341,6 +357,8 @@ int hci_conn_del(struct hci_conn *conn) | |||
341 | 357 | ||
342 | del_timer(&conn->disc_timer); | 358 | del_timer(&conn->disc_timer); |
343 | 359 | ||
360 | del_timer(&conn->auto_accept_timer); | ||
361 | |||
344 | if (conn->type == ACL_LINK) { | 362 | if (conn->type == ACL_LINK) { |
345 | struct hci_conn *sco = conn->link; | 363 | struct hci_conn *sco = conn->link; |
346 | if (sco) | 364 | if (sco) |
@@ -535,32 +553,72 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
535 | return 0; | 553 | return 0; |
536 | } | 554 | } |
537 | 555 | ||
556 | /* Encrypt the the link */ | ||
557 | static void hci_conn_encrypt(struct hci_conn *conn) | ||
558 | { | ||
559 | BT_DBG("conn %p", conn); | ||
560 | |||
561 | if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { | ||
562 | struct hci_cp_set_conn_encrypt cp; | ||
563 | cp.handle = cpu_to_le16(conn->handle); | ||
564 | cp.encrypt = 0x01; | ||
565 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), | ||
566 | &cp); | ||
567 | } | ||
568 | } | ||
569 | |||
538 | /* Enable security */ | 570 | /* Enable security */ |
539 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | 571 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) |
540 | { | 572 | { |
541 | BT_DBG("conn %p", conn); | 573 | BT_DBG("conn %p", conn); |
542 | 574 | ||
575 | /* For sdp we don't need the link key. */ | ||
543 | if (sec_level == BT_SECURITY_SDP) | 576 | if (sec_level == BT_SECURITY_SDP) |
544 | return 1; | 577 | return 1; |
545 | 578 | ||
579 | /* For non 2.1 devices and low security level we don't need the link | ||
580 | key. */ | ||
546 | if (sec_level == BT_SECURITY_LOW && | 581 | if (sec_level == BT_SECURITY_LOW && |
547 | (!conn->ssp_mode || !conn->hdev->ssp_mode)) | 582 | (!conn->ssp_mode || !conn->hdev->ssp_mode)) |
548 | return 1; | 583 | return 1; |
549 | 584 | ||
550 | if (conn->link_mode & HCI_LM_ENCRYPT) | 585 | /* For other security levels we need the link key. */ |
551 | return hci_conn_auth(conn, sec_level, auth_type); | 586 | if (!(conn->link_mode & HCI_LM_AUTH)) |
552 | 587 | goto auth; | |
588 | |||
589 | /* An authenticated combination key has sufficient security for any | ||
590 | security level. */ | ||
591 | if (conn->key_type == HCI_LK_AUTH_COMBINATION) | ||
592 | goto encrypt; | ||
593 | |||
594 | /* An unauthenticated combination key has sufficient security for | ||
595 | security level 1 and 2. */ | ||
596 | if (conn->key_type == HCI_LK_UNAUTH_COMBINATION && | ||
597 | (sec_level == BT_SECURITY_MEDIUM || | ||
598 | sec_level == BT_SECURITY_LOW)) | ||
599 | goto encrypt; | ||
600 | |||
601 | /* A combination key has always sufficient security for the security | ||
602 | levels 1 or 2. High security level requires the combination key | ||
603 | is generated using maximum PIN code length (16). | ||
604 | For pre 2.1 units. */ | ||
605 | if (conn->key_type == HCI_LK_COMBINATION && | ||
606 | (sec_level != BT_SECURITY_HIGH || | ||
607 | conn->pin_length == 16)) | ||
608 | goto encrypt; | ||
609 | |||
610 | auth: | ||
553 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 611 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
554 | return 0; | 612 | return 0; |
555 | 613 | ||
556 | if (hci_conn_auth(conn, sec_level, auth_type)) { | 614 | hci_conn_auth(conn, sec_level, auth_type); |
557 | struct hci_cp_set_conn_encrypt cp; | 615 | return 0; |
558 | cp.handle = cpu_to_le16(conn->handle); | 616 | |
559 | cp.encrypt = 1; | 617 | encrypt: |
560 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, | 618 | if (conn->link_mode & HCI_LM_ENCRYPT) |
561 | sizeof(cp), &cp); | 619 | return 1; |
562 | } | ||
563 | 620 | ||
621 | hci_conn_encrypt(conn); | ||
564 | return 0; | 622 | return 0; |
565 | } | 623 | } |
566 | EXPORT_SYMBOL(hci_conn_security); | 624 | EXPORT_SYMBOL(hci_conn_security); |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e057d1235996..815269b07f20 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1020,18 +1020,54 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1020 | return NULL; | 1020 | return NULL; |
1021 | } | 1021 | } |
1022 | 1022 | ||
1023 | int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | 1023 | static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, |
1024 | u8 *val, u8 type, u8 pin_len) | 1024 | u8 key_type, u8 old_key_type) |
1025 | { | ||
1026 | /* Legacy key */ | ||
1027 | if (key_type < 0x03) | ||
1028 | return 1; | ||
1029 | |||
1030 | /* Debug keys are insecure so don't store them persistently */ | ||
1031 | if (key_type == HCI_LK_DEBUG_COMBINATION) | ||
1032 | return 0; | ||
1033 | |||
1034 | /* Changed combination key and there's no previous one */ | ||
1035 | if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) | ||
1036 | return 0; | ||
1037 | |||
1038 | /* Security mode 3 case */ | ||
1039 | if (!conn) | ||
1040 | return 1; | ||
1041 | |||
1042 | /* Neither local nor remote side had no-bonding as requirement */ | ||
1043 | if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) | ||
1044 | return 1; | ||
1045 | |||
1046 | /* Local side had dedicated bonding as requirement */ | ||
1047 | if (conn->auth_type == 0x02 || conn->auth_type == 0x03) | ||
1048 | return 1; | ||
1049 | |||
1050 | /* Remote side had dedicated bonding as requirement */ | ||
1051 | if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) | ||
1052 | return 1; | ||
1053 | |||
1054 | /* If none of the above criteria match, then don't store the key | ||
1055 | * persistently */ | ||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, | ||
1060 | bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) | ||
1025 | { | 1061 | { |
1026 | struct link_key *key, *old_key; | 1062 | struct link_key *key, *old_key; |
1027 | u8 old_key_type; | 1063 | u8 old_key_type, persistent; |
1028 | 1064 | ||
1029 | old_key = hci_find_link_key(hdev, bdaddr); | 1065 | old_key = hci_find_link_key(hdev, bdaddr); |
1030 | if (old_key) { | 1066 | if (old_key) { |
1031 | old_key_type = old_key->type; | 1067 | old_key_type = old_key->type; |
1032 | key = old_key; | 1068 | key = old_key; |
1033 | } else { | 1069 | } else { |
1034 | old_key_type = 0xff; | 1070 | old_key_type = conn ? conn->key_type : 0xff; |
1035 | key = kzalloc(sizeof(*key), GFP_ATOMIC); | 1071 | key = kzalloc(sizeof(*key), GFP_ATOMIC); |
1036 | if (!key) | 1072 | if (!key) |
1037 | return -ENOMEM; | 1073 | return -ENOMEM; |
@@ -1040,16 +1076,37 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | |||
1040 | 1076 | ||
1041 | BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); | 1077 | BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); |
1042 | 1078 | ||
1079 | /* Some buggy controller combinations generate a changed | ||
1080 | * combination key for legacy pairing even when there's no | ||
1081 | * previous key */ | ||
1082 | if (type == HCI_LK_CHANGED_COMBINATION && | ||
1083 | (!conn || conn->remote_auth == 0xff) && | ||
1084 | old_key_type == 0xff) { | ||
1085 | type = HCI_LK_COMBINATION; | ||
1086 | if (conn) | ||
1087 | conn->key_type = type; | ||
1088 | } | ||
1089 | |||
1043 | bacpy(&key->bdaddr, bdaddr); | 1090 | bacpy(&key->bdaddr, bdaddr); |
1044 | memcpy(key->val, val, 16); | 1091 | memcpy(key->val, val, 16); |
1045 | key->type = type; | ||
1046 | key->pin_len = pin_len; | 1092 | key->pin_len = pin_len; |
1047 | 1093 | ||
1048 | if (new_key) | 1094 | if (type == HCI_LK_CHANGED_COMBINATION) |
1049 | mgmt_new_key(hdev->id, key, old_key_type); | ||
1050 | |||
1051 | if (type == 0x06) | ||
1052 | key->type = old_key_type; | 1095 | key->type = old_key_type; |
1096 | else | ||
1097 | key->type = type; | ||
1098 | |||
1099 | if (!new_key) | ||
1100 | return 0; | ||
1101 | |||
1102 | persistent = hci_persistent_key(hdev, conn, type, old_key_type); | ||
1103 | |||
1104 | mgmt_new_key(hdev->id, key, persistent); | ||
1105 | |||
1106 | if (!persistent) { | ||
1107 | list_del(&key->list); | ||
1108 | kfree(key); | ||
1109 | } | ||
1053 | 1110 | ||
1054 | return 0; | 1111 | return 0; |
1055 | } | 1112 | } |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index cb25628c0583..d5aa97ee6ffa 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -56,7 +56,9 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
56 | if (status) | 56 | if (status) |
57 | return; | 57 | return; |
58 | 58 | ||
59 | clear_bit(HCI_INQUIRY, &hdev->flags); | 59 | if (test_bit(HCI_MGMT, &hdev->flags) && |
60 | test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | ||
61 | mgmt_discovering(hdev->id, 0); | ||
60 | 62 | ||
61 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); | 63 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); |
62 | 64 | ||
@@ -72,7 +74,9 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) | |||
72 | if (status) | 74 | if (status) |
73 | return; | 75 | return; |
74 | 76 | ||
75 | clear_bit(HCI_INQUIRY, &hdev->flags); | 77 | if (test_bit(HCI_MGMT, &hdev->flags) && |
78 | test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | ||
79 | mgmt_discovering(hdev->id, 0); | ||
76 | 80 | ||
77 | hci_conn_check_pending(hdev); | 81 | hci_conn_check_pending(hdev); |
78 | } | 82 | } |
@@ -841,10 +845,14 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | |||
841 | 845 | ||
842 | if (status) { | 846 | if (status) { |
843 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 847 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
844 | |||
845 | hci_conn_check_pending(hdev); | 848 | hci_conn_check_pending(hdev); |
846 | } else | 849 | return; |
847 | set_bit(HCI_INQUIRY, &hdev->flags); | 850 | } |
851 | |||
852 | if (test_bit(HCI_MGMT, &hdev->flags) && | ||
853 | !test_and_set_bit(HCI_INQUIRY, | ||
854 | &hdev->flags)) | ||
855 | mgmt_discovering(hdev->id, 1); | ||
848 | } | 856 | } |
849 | 857 | ||
850 | static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | 858 | static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) |
@@ -1013,12 +1021,19 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) | |||
1013 | hci_dev_lock(hdev); | 1021 | hci_dev_lock(hdev); |
1014 | 1022 | ||
1015 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | 1023 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); |
1016 | if (conn && hci_outgoing_auth_needed(hdev, conn)) { | 1024 | if (!conn) |
1025 | goto unlock; | ||
1026 | |||
1027 | if (!hci_outgoing_auth_needed(hdev, conn)) | ||
1028 | goto unlock; | ||
1029 | |||
1030 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | ||
1017 | struct hci_cp_auth_requested cp; | 1031 | struct hci_cp_auth_requested cp; |
1018 | cp.handle = __cpu_to_le16(conn->handle); | 1032 | cp.handle = __cpu_to_le16(conn->handle); |
1019 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); | 1033 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); |
1020 | } | 1034 | } |
1021 | 1035 | ||
1036 | unlock: | ||
1022 | hci_dev_unlock(hdev); | 1037 | hci_dev_unlock(hdev); |
1023 | } | 1038 | } |
1024 | 1039 | ||
@@ -1208,7 +1223,9 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1208 | 1223 | ||
1209 | BT_DBG("%s status %d", hdev->name, status); | 1224 | BT_DBG("%s status %d", hdev->name, status); |
1210 | 1225 | ||
1211 | clear_bit(HCI_INQUIRY, &hdev->flags); | 1226 | if (test_bit(HCI_MGMT, &hdev->flags) && |
1227 | test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | ||
1228 | mgmt_discovering(hdev->id, 0); | ||
1212 | 1229 | ||
1213 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 1230 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
1214 | 1231 | ||
@@ -1228,6 +1245,12 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * | |||
1228 | 1245 | ||
1229 | hci_dev_lock(hdev); | 1246 | hci_dev_lock(hdev); |
1230 | 1247 | ||
1248 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) { | ||
1249 | |||
1250 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
1251 | mgmt_discovering(hdev->id, 1); | ||
1252 | } | ||
1253 | |||
1231 | for (; num_rsp; num_rsp--, info++) { | 1254 | for (; num_rsp; num_rsp--, info++) { |
1232 | bacpy(&data.bdaddr, &info->bdaddr); | 1255 | bacpy(&data.bdaddr, &info->bdaddr); |
1233 | data.pscan_rep_mode = info->pscan_rep_mode; | 1256 | data.pscan_rep_mode = info->pscan_rep_mode; |
@@ -1443,7 +1466,6 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1443 | conn->sec_level = conn->pending_sec_level; | 1466 | conn->sec_level = conn->pending_sec_level; |
1444 | } else { | 1467 | } else { |
1445 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | 1468 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); |
1446 | conn->sec_level = BT_SECURITY_LOW; | ||
1447 | } | 1469 | } |
1448 | 1470 | ||
1449 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1471 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
@@ -1501,12 +1523,19 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
1501 | mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name); | 1523 | mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name); |
1502 | 1524 | ||
1503 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 1525 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
1504 | if (conn && hci_outgoing_auth_needed(hdev, conn)) { | 1526 | if (!conn) |
1527 | goto unlock; | ||
1528 | |||
1529 | if (!hci_outgoing_auth_needed(hdev, conn)) | ||
1530 | goto unlock; | ||
1531 | |||
1532 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | ||
1505 | struct hci_cp_auth_requested cp; | 1533 | struct hci_cp_auth_requested cp; |
1506 | cp.handle = __cpu_to_le16(conn->handle); | 1534 | cp.handle = __cpu_to_le16(conn->handle); |
1507 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); | 1535 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); |
1508 | } | 1536 | } |
1509 | 1537 | ||
1538 | unlock: | ||
1510 | hci_dev_unlock(hdev); | 1539 | hci_dev_unlock(hdev); |
1511 | } | 1540 | } |
1512 | 1541 | ||
@@ -2006,9 +2035,16 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff | |||
2006 | if (!test_bit(HCI_PAIRABLE, &hdev->flags)) | 2035 | if (!test_bit(HCI_PAIRABLE, &hdev->flags)) |
2007 | hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, | 2036 | hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, |
2008 | sizeof(ev->bdaddr), &ev->bdaddr); | 2037 | sizeof(ev->bdaddr), &ev->bdaddr); |
2038 | else if (test_bit(HCI_MGMT, &hdev->flags)) { | ||
2039 | u8 secure; | ||
2009 | 2040 | ||
2010 | if (test_bit(HCI_MGMT, &hdev->flags)) | 2041 | if (conn->pending_sec_level == BT_SECURITY_HIGH) |
2011 | mgmt_pin_code_request(hdev->id, &ev->bdaddr); | 2042 | secure = 1; |
2043 | else | ||
2044 | secure = 0; | ||
2045 | |||
2046 | mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure); | ||
2047 | } | ||
2012 | 2048 | ||
2013 | hci_dev_unlock(hdev); | 2049 | hci_dev_unlock(hdev); |
2014 | } | 2050 | } |
@@ -2037,17 +2073,30 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff | |||
2037 | BT_DBG("%s found key type %u for %s", hdev->name, key->type, | 2073 | BT_DBG("%s found key type %u for %s", hdev->name, key->type, |
2038 | batostr(&ev->bdaddr)); | 2074 | batostr(&ev->bdaddr)); |
2039 | 2075 | ||
2040 | if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) { | 2076 | if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && |
2077 | key->type == HCI_LK_DEBUG_COMBINATION) { | ||
2041 | BT_DBG("%s ignoring debug key", hdev->name); | 2078 | BT_DBG("%s ignoring debug key", hdev->name); |
2042 | goto not_found; | 2079 | goto not_found; |
2043 | } | 2080 | } |
2044 | 2081 | ||
2045 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 2082 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
2083 | if (conn) { | ||
2084 | if (key->type == HCI_LK_UNAUTH_COMBINATION && | ||
2085 | conn->auth_type != 0xff && | ||
2086 | (conn->auth_type & 0x01)) { | ||
2087 | BT_DBG("%s ignoring unauthenticated key", hdev->name); | ||
2088 | goto not_found; | ||
2089 | } | ||
2046 | 2090 | ||
2047 | if (key->type == 0x04 && conn && conn->auth_type != 0xff && | 2091 | if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && |
2048 | (conn->auth_type & 0x01)) { | 2092 | conn->pending_sec_level == BT_SECURITY_HIGH) { |
2049 | BT_DBG("%s ignoring unauthenticated key", hdev->name); | 2093 | BT_DBG("%s ignoring key unauthenticated for high \ |
2050 | goto not_found; | 2094 | security", hdev->name); |
2095 | goto not_found; | ||
2096 | } | ||
2097 | |||
2098 | conn->key_type = key->type; | ||
2099 | conn->pin_length = key->pin_len; | ||
2051 | } | 2100 | } |
2052 | 2101 | ||
2053 | bacpy(&cp.bdaddr, &ev->bdaddr); | 2102 | bacpy(&cp.bdaddr, &ev->bdaddr); |
@@ -2079,11 +2128,15 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff | |||
2079 | hci_conn_hold(conn); | 2128 | hci_conn_hold(conn); |
2080 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 2129 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
2081 | pin_len = conn->pin_length; | 2130 | pin_len = conn->pin_length; |
2131 | |||
2132 | if (ev->key_type != HCI_LK_CHANGED_COMBINATION) | ||
2133 | conn->key_type = ev->key_type; | ||
2134 | |||
2082 | hci_conn_put(conn); | 2135 | hci_conn_put(conn); |
2083 | } | 2136 | } |
2084 | 2137 | ||
2085 | if (test_bit(HCI_LINK_KEYS, &hdev->flags)) | 2138 | if (test_bit(HCI_LINK_KEYS, &hdev->flags)) |
2086 | hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key, | 2139 | hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, |
2087 | ev->key_type, pin_len); | 2140 | ev->key_type, pin_len); |
2088 | 2141 | ||
2089 | hci_dev_unlock(hdev); | 2142 | hci_dev_unlock(hdev); |
@@ -2158,6 +2211,12 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2158 | 2211 | ||
2159 | hci_dev_lock(hdev); | 2212 | hci_dev_lock(hdev); |
2160 | 2213 | ||
2214 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) { | ||
2215 | |||
2216 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
2217 | mgmt_discovering(hdev->id, 1); | ||
2218 | } | ||
2219 | |||
2161 | if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { | 2220 | if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { |
2162 | struct inquiry_info_with_rssi_and_pscan_mode *info; | 2221 | struct inquiry_info_with_rssi_and_pscan_mode *info; |
2163 | info = (void *) (skb->data + 1); | 2222 | info = (void *) (skb->data + 1); |
@@ -2320,6 +2379,12 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
2320 | if (!num_rsp) | 2379 | if (!num_rsp) |
2321 | return; | 2380 | return; |
2322 | 2381 | ||
2382 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) { | ||
2383 | |||
2384 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
2385 | mgmt_discovering(hdev->id, 1); | ||
2386 | } | ||
2387 | |||
2323 | hci_dev_lock(hdev); | 2388 | hci_dev_lock(hdev); |
2324 | 2389 | ||
2325 | for (; num_rsp; num_rsp--, info++) { | 2390 | for (; num_rsp; num_rsp--, info++) { |
@@ -2353,7 +2418,7 @@ static inline u8 hci_get_auth_req(struct hci_conn *conn) | |||
2353 | 2418 | ||
2354 | /* If remote requests no-bonding follow that lead */ | 2419 | /* If remote requests no-bonding follow that lead */ |
2355 | if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01) | 2420 | if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01) |
2356 | return 0x00; | 2421 | return conn->remote_auth | (conn->auth_type & 0x01); |
2357 | 2422 | ||
2358 | return conn->auth_type; | 2423 | return conn->auth_type; |
2359 | } | 2424 | } |
@@ -2382,7 +2447,8 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff | |||
2382 | 2447 | ||
2383 | bacpy(&cp.bdaddr, &ev->bdaddr); | 2448 | bacpy(&cp.bdaddr, &ev->bdaddr); |
2384 | cp.capability = conn->io_capability; | 2449 | cp.capability = conn->io_capability; |
2385 | cp.authentication = hci_get_auth_req(conn); | 2450 | conn->auth_type = hci_get_auth_req(conn); |
2451 | cp.authentication = conn->auth_type; | ||
2386 | 2452 | ||
2387 | if ((conn->out == 0x01 || conn->remote_oob == 0x01) && | 2453 | if ((conn->out == 0x01 || conn->remote_oob == 0x01) && |
2388 | hci_find_remote_oob_data(hdev, &conn->dst)) | 2454 | hci_find_remote_oob_data(hdev, &conn->dst)) |
@@ -2396,7 +2462,7 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff | |||
2396 | struct hci_cp_io_capability_neg_reply cp; | 2462 | struct hci_cp_io_capability_neg_reply cp; |
2397 | 2463 | ||
2398 | bacpy(&cp.bdaddr, &ev->bdaddr); | 2464 | bacpy(&cp.bdaddr, &ev->bdaddr); |
2399 | cp.reason = 0x16; /* Pairing not allowed */ | 2465 | cp.reason = 0x18; /* Pairing not allowed */ |
2400 | 2466 | ||
2401 | hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, | 2467 | hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, |
2402 | sizeof(cp), &cp); | 2468 | sizeof(cp), &cp); |
@@ -2431,14 +2497,67 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, | |||
2431 | struct sk_buff *skb) | 2497 | struct sk_buff *skb) |
2432 | { | 2498 | { |
2433 | struct hci_ev_user_confirm_req *ev = (void *) skb->data; | 2499 | struct hci_ev_user_confirm_req *ev = (void *) skb->data; |
2500 | int loc_mitm, rem_mitm, confirm_hint = 0; | ||
2501 | struct hci_conn *conn; | ||
2434 | 2502 | ||
2435 | BT_DBG("%s", hdev->name); | 2503 | BT_DBG("%s", hdev->name); |
2436 | 2504 | ||
2437 | hci_dev_lock(hdev); | 2505 | hci_dev_lock(hdev); |
2438 | 2506 | ||
2439 | if (test_bit(HCI_MGMT, &hdev->flags)) | 2507 | if (!test_bit(HCI_MGMT, &hdev->flags)) |
2440 | mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey); | 2508 | goto unlock; |
2509 | |||
2510 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
2511 | if (!conn) | ||
2512 | goto unlock; | ||
2513 | |||
2514 | loc_mitm = (conn->auth_type & 0x01); | ||
2515 | rem_mitm = (conn->remote_auth & 0x01); | ||
2516 | |||
2517 | /* If we require MITM but the remote device can't provide that | ||
2518 | * (it has NoInputNoOutput) then reject the confirmation | ||
2519 | * request. The only exception is when we're dedicated bonding | ||
2520 | * initiators (connect_cfm_cb set) since then we always have the MITM | ||
2521 | * bit set. */ | ||
2522 | if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) { | ||
2523 | BT_DBG("Rejecting request: remote device can't provide MITM"); | ||
2524 | hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, | ||
2525 | sizeof(ev->bdaddr), &ev->bdaddr); | ||
2526 | goto unlock; | ||
2527 | } | ||
2528 | |||
2529 | /* If no side requires MITM protection; auto-accept */ | ||
2530 | if ((!loc_mitm || conn->remote_cap == 0x03) && | ||
2531 | (!rem_mitm || conn->io_capability == 0x03)) { | ||
2441 | 2532 | ||
2533 | /* If we're not the initiators request authorization to | ||
2534 | * proceed from user space (mgmt_user_confirm with | ||
2535 | * confirm_hint set to 1). */ | ||
2536 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | ||
2537 | BT_DBG("Confirming auto-accept as acceptor"); | ||
2538 | confirm_hint = 1; | ||
2539 | goto confirm; | ||
2540 | } | ||
2541 | |||
2542 | BT_DBG("Auto-accept of user confirmation with %ums delay", | ||
2543 | hdev->auto_accept_delay); | ||
2544 | |||
2545 | if (hdev->auto_accept_delay > 0) { | ||
2546 | int delay = msecs_to_jiffies(hdev->auto_accept_delay); | ||
2547 | mod_timer(&conn->auto_accept_timer, jiffies + delay); | ||
2548 | goto unlock; | ||
2549 | } | ||
2550 | |||
2551 | hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, | ||
2552 | sizeof(ev->bdaddr), &ev->bdaddr); | ||
2553 | goto unlock; | ||
2554 | } | ||
2555 | |||
2556 | confirm: | ||
2557 | mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey, | ||
2558 | confirm_hint); | ||
2559 | |||
2560 | unlock: | ||
2442 | hci_dev_unlock(hdev); | 2561 | hci_dev_unlock(hdev); |
2443 | } | 2562 | } |
2444 | 2563 | ||
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 8775933ea837..a6c3aa8be1f7 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -511,6 +511,35 @@ static const struct file_operations uuids_fops = { | |||
511 | .release = single_release, | 511 | .release = single_release, |
512 | }; | 512 | }; |
513 | 513 | ||
514 | static int auto_accept_delay_set(void *data, u64 val) | ||
515 | { | ||
516 | struct hci_dev *hdev = data; | ||
517 | |||
518 | hci_dev_lock_bh(hdev); | ||
519 | |||
520 | hdev->auto_accept_delay = val; | ||
521 | |||
522 | hci_dev_unlock_bh(hdev); | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int auto_accept_delay_get(void *data, u64 *val) | ||
528 | { | ||
529 | struct hci_dev *hdev = data; | ||
530 | |||
531 | hci_dev_lock_bh(hdev); | ||
532 | |||
533 | *val = hdev->auto_accept_delay; | ||
534 | |||
535 | hci_dev_unlock_bh(hdev); | ||
536 | |||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, | ||
541 | auto_accept_delay_set, "%llu\n"); | ||
542 | |||
514 | int hci_register_sysfs(struct hci_dev *hdev) | 543 | int hci_register_sysfs(struct hci_dev *hdev) |
515 | { | 544 | { |
516 | struct device *dev = &hdev->dev; | 545 | struct device *dev = &hdev->dev; |
@@ -545,6 +574,8 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
545 | 574 | ||
546 | debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); | 575 | debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); |
547 | 576 | ||
577 | debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev, | ||
578 | &auto_accept_delay_fops); | ||
548 | return 0; | 579 | return 0; |
549 | } | 580 | } |
550 | 581 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index ae6ebc6c3481..c405a954a603 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -979,8 +979,10 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
979 | 979 | ||
980 | bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst); | 980 | bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst); |
981 | 981 | ||
982 | session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu); | 982 | session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->chan->omtu, |
983 | session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu); | 983 | l2cap_pi(ctrl_sock->sk)->chan->imtu); |
984 | session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->chan->omtu, | ||
985 | l2cap_pi(intr_sock->sk)->chan->imtu); | ||
984 | 986 | ||
985 | BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu); | 987 | BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu); |
986 | 988 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index fd3c1f35aa00..a378acc491ec 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -80,8 +80,7 @@ static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 | |||
80 | struct l2cap_chan *c; | 80 | struct l2cap_chan *c; |
81 | 81 | ||
82 | list_for_each_entry(c, &conn->chan_l, list) { | 82 | list_for_each_entry(c, &conn->chan_l, list) { |
83 | struct sock *s = c->sk; | 83 | if (c->dcid == cid) |
84 | if (l2cap_pi(s)->dcid == cid) | ||
85 | return c; | 84 | return c; |
86 | } | 85 | } |
87 | return NULL; | 86 | return NULL; |
@@ -93,8 +92,7 @@ static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 | |||
93 | struct l2cap_chan *c; | 92 | struct l2cap_chan *c; |
94 | 93 | ||
95 | list_for_each_entry(c, &conn->chan_l, list) { | 94 | list_for_each_entry(c, &conn->chan_l, list) { |
96 | struct sock *s = c->sk; | 95 | if (c->scid == cid) |
97 | if (l2cap_pi(s)->scid == cid) | ||
98 | return c; | 96 | return c; |
99 | } | 97 | } |
100 | return NULL; | 98 | return NULL; |
@@ -149,7 +147,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) | |||
149 | return 0; | 147 | return 0; |
150 | } | 148 | } |
151 | 149 | ||
152 | static struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) | 150 | struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) |
153 | { | 151 | { |
154 | struct l2cap_chan *chan; | 152 | struct l2cap_chan *chan; |
155 | 153 | ||
@@ -162,38 +160,43 @@ static struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) | |||
162 | return chan; | 160 | return chan; |
163 | } | 161 | } |
164 | 162 | ||
163 | void l2cap_chan_free(struct l2cap_chan *chan) | ||
164 | { | ||
165 | kfree(chan); | ||
166 | } | ||
167 | |||
165 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | 168 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
166 | { | 169 | { |
167 | struct sock *sk = chan->sk; | 170 | struct sock *sk = chan->sk; |
168 | 171 | ||
169 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, | 172 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, |
170 | l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); | 173 | chan->psm, chan->dcid); |
171 | 174 | ||
172 | conn->disc_reason = 0x13; | 175 | conn->disc_reason = 0x13; |
173 | 176 | ||
174 | l2cap_pi(sk)->conn = conn; | 177 | chan->conn = conn; |
175 | 178 | ||
176 | if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) { | 179 | if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) { |
177 | if (conn->hcon->type == LE_LINK) { | 180 | if (conn->hcon->type == LE_LINK) { |
178 | /* LE connection */ | 181 | /* LE connection */ |
179 | l2cap_pi(sk)->omtu = L2CAP_LE_DEFAULT_MTU; | 182 | chan->omtu = L2CAP_LE_DEFAULT_MTU; |
180 | l2cap_pi(sk)->scid = L2CAP_CID_LE_DATA; | 183 | chan->scid = L2CAP_CID_LE_DATA; |
181 | l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA; | 184 | chan->dcid = L2CAP_CID_LE_DATA; |
182 | } else { | 185 | } else { |
183 | /* Alloc CID for connection-oriented socket */ | 186 | /* Alloc CID for connection-oriented socket */ |
184 | l2cap_pi(sk)->scid = l2cap_alloc_cid(conn); | 187 | chan->scid = l2cap_alloc_cid(conn); |
185 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | 188 | chan->omtu = L2CAP_DEFAULT_MTU; |
186 | } | 189 | } |
187 | } else if (sk->sk_type == SOCK_DGRAM) { | 190 | } else if (sk->sk_type == SOCK_DGRAM) { |
188 | /* Connectionless socket */ | 191 | /* Connectionless socket */ |
189 | l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS; | 192 | chan->scid = L2CAP_CID_CONN_LESS; |
190 | l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS; | 193 | chan->dcid = L2CAP_CID_CONN_LESS; |
191 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | 194 | chan->omtu = L2CAP_DEFAULT_MTU; |
192 | } else { | 195 | } else { |
193 | /* Raw socket can send/recv signalling messages only */ | 196 | /* Raw socket can send/recv signalling messages only */ |
194 | l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING; | 197 | chan->scid = L2CAP_CID_SIGNALING; |
195 | l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING; | 198 | chan->dcid = L2CAP_CID_SIGNALING; |
196 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | 199 | chan->omtu = L2CAP_DEFAULT_MTU; |
197 | } | 200 | } |
198 | 201 | ||
199 | sock_hold(sk); | 202 | sock_hold(sk); |
@@ -206,7 +209,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
206 | void l2cap_chan_del(struct l2cap_chan *chan, int err) | 209 | void l2cap_chan_del(struct l2cap_chan *chan, int err) |
207 | { | 210 | { |
208 | struct sock *sk = chan->sk; | 211 | struct sock *sk = chan->sk; |
209 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 212 | struct l2cap_conn *conn = chan->conn; |
210 | struct sock *parent = bt_sk(sk)->parent; | 213 | struct sock *parent = bt_sk(sk)->parent; |
211 | 214 | ||
212 | l2cap_sock_clear_timer(sk); | 215 | l2cap_sock_clear_timer(sk); |
@@ -220,7 +223,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
220 | write_unlock_bh(&conn->chan_lock); | 223 | write_unlock_bh(&conn->chan_lock); |
221 | __sock_put(sk); | 224 | __sock_put(sk); |
222 | 225 | ||
223 | l2cap_pi(sk)->conn = NULL; | 226 | chan->conn = NULL; |
224 | hci_conn_put(conn->hcon); | 227 | hci_conn_put(conn->hcon); |
225 | } | 228 | } |
226 | 229 | ||
@@ -236,13 +239,13 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
236 | } else | 239 | } else |
237 | sk->sk_state_change(sk); | 240 | sk->sk_state_change(sk); |
238 | 241 | ||
239 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE && | 242 | if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE && |
240 | l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE)) | 243 | chan->conf_state & L2CAP_CONF_INPUT_DONE)) |
241 | goto free; | 244 | return; |
242 | 245 | ||
243 | skb_queue_purge(&chan->tx_q); | 246 | skb_queue_purge(&chan->tx_q); |
244 | 247 | ||
245 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { | 248 | if (chan->mode == L2CAP_MODE_ERTM) { |
246 | struct srej_list *l, *tmp; | 249 | struct srej_list *l, *tmp; |
247 | 250 | ||
248 | del_timer(&chan->retrans_timer); | 251 | del_timer(&chan->retrans_timer); |
@@ -257,15 +260,14 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
257 | kfree(l); | 260 | kfree(l); |
258 | } | 261 | } |
259 | } | 262 | } |
260 | |||
261 | free: | ||
262 | kfree(chan); | ||
263 | } | 263 | } |
264 | 264 | ||
265 | static inline u8 l2cap_get_auth_type(struct sock *sk) | 265 | static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) |
266 | { | 266 | { |
267 | struct sock *sk = chan->sk; | ||
268 | |||
267 | if (sk->sk_type == SOCK_RAW) { | 269 | if (sk->sk_type == SOCK_RAW) { |
268 | switch (l2cap_pi(sk)->sec_level) { | 270 | switch (chan->sec_level) { |
269 | case BT_SECURITY_HIGH: | 271 | case BT_SECURITY_HIGH: |
270 | return HCI_AT_DEDICATED_BONDING_MITM; | 272 | return HCI_AT_DEDICATED_BONDING_MITM; |
271 | case BT_SECURITY_MEDIUM: | 273 | case BT_SECURITY_MEDIUM: |
@@ -273,16 +275,16 @@ static inline u8 l2cap_get_auth_type(struct sock *sk) | |||
273 | default: | 275 | default: |
274 | return HCI_AT_NO_BONDING; | 276 | return HCI_AT_NO_BONDING; |
275 | } | 277 | } |
276 | } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { | 278 | } else if (chan->psm == cpu_to_le16(0x0001)) { |
277 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) | 279 | if (chan->sec_level == BT_SECURITY_LOW) |
278 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | 280 | chan->sec_level = BT_SECURITY_SDP; |
279 | 281 | ||
280 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) | 282 | if (chan->sec_level == BT_SECURITY_HIGH) |
281 | return HCI_AT_NO_BONDING_MITM; | 283 | return HCI_AT_NO_BONDING_MITM; |
282 | else | 284 | else |
283 | return HCI_AT_NO_BONDING; | 285 | return HCI_AT_NO_BONDING; |
284 | } else { | 286 | } else { |
285 | switch (l2cap_pi(sk)->sec_level) { | 287 | switch (chan->sec_level) { |
286 | case BT_SECURITY_HIGH: | 288 | case BT_SECURITY_HIGH: |
287 | return HCI_AT_GENERAL_BONDING_MITM; | 289 | return HCI_AT_GENERAL_BONDING_MITM; |
288 | case BT_SECURITY_MEDIUM: | 290 | case BT_SECURITY_MEDIUM: |
@@ -294,15 +296,14 @@ static inline u8 l2cap_get_auth_type(struct sock *sk) | |||
294 | } | 296 | } |
295 | 297 | ||
296 | /* Service level security */ | 298 | /* Service level security */ |
297 | static inline int l2cap_check_security(struct sock *sk) | 299 | static inline int l2cap_check_security(struct l2cap_chan *chan) |
298 | { | 300 | { |
299 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 301 | struct l2cap_conn *conn = chan->conn; |
300 | __u8 auth_type; | 302 | __u8 auth_type; |
301 | 303 | ||
302 | auth_type = l2cap_get_auth_type(sk); | 304 | auth_type = l2cap_get_auth_type(chan); |
303 | 305 | ||
304 | return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level, | 306 | return hci_conn_security(conn->hcon, chan->sec_level, auth_type); |
305 | auth_type); | ||
306 | } | 307 | } |
307 | 308 | ||
308 | u8 l2cap_get_ident(struct l2cap_conn *conn) | 309 | u8 l2cap_get_ident(struct l2cap_conn *conn) |
@@ -350,7 +351,7 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | |||
350 | struct sk_buff *skb; | 351 | struct sk_buff *skb; |
351 | struct l2cap_hdr *lh; | 352 | struct l2cap_hdr *lh; |
352 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | 353 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); |
353 | struct l2cap_conn *conn = pi->conn; | 354 | struct l2cap_conn *conn = chan->conn; |
354 | struct sock *sk = (struct sock *)pi; | 355 | struct sock *sk = (struct sock *)pi; |
355 | int count, hlen = L2CAP_HDR_SIZE + 2; | 356 | int count, hlen = L2CAP_HDR_SIZE + 2; |
356 | u8 flags; | 357 | u8 flags; |
@@ -358,7 +359,7 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | |||
358 | if (sk->sk_state != BT_CONNECTED) | 359 | if (sk->sk_state != BT_CONNECTED) |
359 | return; | 360 | return; |
360 | 361 | ||
361 | if (pi->fcs == L2CAP_FCS_CRC16) | 362 | if (chan->fcs == L2CAP_FCS_CRC16) |
362 | hlen += 2; | 363 | hlen += 2; |
363 | 364 | ||
364 | BT_DBG("chan %p, control 0x%2.2x", chan, control); | 365 | BT_DBG("chan %p, control 0x%2.2x", chan, control); |
@@ -382,10 +383,10 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | |||
382 | 383 | ||
383 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 384 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
384 | lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE); | 385 | lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE); |
385 | lh->cid = cpu_to_le16(pi->dcid); | 386 | lh->cid = cpu_to_le16(chan->dcid); |
386 | put_unaligned_le16(control, skb_put(skb, 2)); | 387 | put_unaligned_le16(control, skb_put(skb, 2)); |
387 | 388 | ||
388 | if (pi->fcs == L2CAP_FCS_CRC16) { | 389 | if (chan->fcs == L2CAP_FCS_CRC16) { |
389 | u16 fcs = crc16(0, (u8 *)lh, count - 2); | 390 | u16 fcs = crc16(0, (u8 *)lh, count - 2); |
390 | put_unaligned_le16(fcs, skb_put(skb, 2)); | 391 | put_unaligned_le16(fcs, skb_put(skb, 2)); |
391 | } | 392 | } |
@@ -395,7 +396,7 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | |||
395 | else | 396 | else |
396 | flags = ACL_START; | 397 | flags = ACL_START; |
397 | 398 | ||
398 | hci_send_acl(pi->conn->hcon, skb, flags); | 399 | hci_send_acl(chan->conn->hcon, skb, flags); |
399 | } | 400 | } |
400 | 401 | ||
401 | static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) | 402 | static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) |
@@ -411,27 +412,27 @@ static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) | |||
411 | l2cap_send_sframe(chan, control); | 412 | l2cap_send_sframe(chan, control); |
412 | } | 413 | } |
413 | 414 | ||
414 | static inline int __l2cap_no_conn_pending(struct sock *sk) | 415 | static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) |
415 | { | 416 | { |
416 | return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND); | 417 | return !(chan->conf_state & L2CAP_CONF_CONNECT_PEND); |
417 | } | 418 | } |
418 | 419 | ||
419 | static void l2cap_do_start(struct l2cap_chan *chan) | 420 | static void l2cap_do_start(struct l2cap_chan *chan) |
420 | { | 421 | { |
421 | struct sock *sk = chan->sk; | 422 | struct l2cap_conn *conn = chan->conn; |
422 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
423 | 423 | ||
424 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { | 424 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { |
425 | if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) | 425 | if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) |
426 | return; | 426 | return; |
427 | 427 | ||
428 | if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) { | 428 | if (l2cap_check_security(chan) && |
429 | __l2cap_no_conn_pending(chan)) { | ||
429 | struct l2cap_conn_req req; | 430 | struct l2cap_conn_req req; |
430 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 431 | req.scid = cpu_to_le16(chan->scid); |
431 | req.psm = l2cap_pi(sk)->psm; | 432 | req.psm = chan->psm; |
432 | 433 | ||
433 | chan->ident = l2cap_get_ident(conn); | 434 | chan->ident = l2cap_get_ident(conn); |
434 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; | 435 | chan->conf_state |= L2CAP_CONF_CONNECT_PEND; |
435 | 436 | ||
436 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, | 437 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, |
437 | sizeof(req), &req); | 438 | sizeof(req), &req); |
@@ -477,14 +478,14 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, in | |||
477 | 478 | ||
478 | sk = chan->sk; | 479 | sk = chan->sk; |
479 | 480 | ||
480 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { | 481 | if (chan->mode == L2CAP_MODE_ERTM) { |
481 | del_timer(&chan->retrans_timer); | 482 | del_timer(&chan->retrans_timer); |
482 | del_timer(&chan->monitor_timer); | 483 | del_timer(&chan->monitor_timer); |
483 | del_timer(&chan->ack_timer); | 484 | del_timer(&chan->ack_timer); |
484 | } | 485 | } |
485 | 486 | ||
486 | req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid); | 487 | req.dcid = cpu_to_le16(chan->dcid); |
487 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 488 | req.scid = cpu_to_le16(chan->scid); |
488 | l2cap_send_cmd(conn, l2cap_get_ident(conn), | 489 | l2cap_send_cmd(conn, l2cap_get_ident(conn), |
489 | L2CAP_DISCONN_REQ, sizeof(req), &req); | 490 | L2CAP_DISCONN_REQ, sizeof(req), &req); |
490 | 491 | ||
@@ -515,15 +516,15 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
515 | if (sk->sk_state == BT_CONNECT) { | 516 | if (sk->sk_state == BT_CONNECT) { |
516 | struct l2cap_conn_req req; | 517 | struct l2cap_conn_req req; |
517 | 518 | ||
518 | if (!l2cap_check_security(sk) || | 519 | if (!l2cap_check_security(chan) || |
519 | !__l2cap_no_conn_pending(sk)) { | 520 | !__l2cap_no_conn_pending(chan)) { |
520 | bh_unlock_sock(sk); | 521 | bh_unlock_sock(sk); |
521 | continue; | 522 | continue; |
522 | } | 523 | } |
523 | 524 | ||
524 | if (!l2cap_mode_supported(l2cap_pi(sk)->mode, | 525 | if (!l2cap_mode_supported(chan->mode, |
525 | conn->feat_mask) | 526 | conn->feat_mask) |
526 | && l2cap_pi(sk)->conf_state & | 527 | && chan->conf_state & |
527 | L2CAP_CONF_STATE2_DEVICE) { | 528 | L2CAP_CONF_STATE2_DEVICE) { |
528 | /* __l2cap_sock_close() calls list_del(chan) | 529 | /* __l2cap_sock_close() calls list_del(chan) |
529 | * so release the lock */ | 530 | * so release the lock */ |
@@ -534,11 +535,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
534 | continue; | 535 | continue; |
535 | } | 536 | } |
536 | 537 | ||
537 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 538 | req.scid = cpu_to_le16(chan->scid); |
538 | req.psm = l2cap_pi(sk)->psm; | 539 | req.psm = chan->psm; |
539 | 540 | ||
540 | chan->ident = l2cap_get_ident(conn); | 541 | chan->ident = l2cap_get_ident(conn); |
541 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; | 542 | chan->conf_state |= L2CAP_CONF_CONNECT_PEND; |
542 | 543 | ||
543 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, | 544 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, |
544 | sizeof(req), &req); | 545 | sizeof(req), &req); |
@@ -546,10 +547,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
546 | } else if (sk->sk_state == BT_CONNECT2) { | 547 | } else if (sk->sk_state == BT_CONNECT2) { |
547 | struct l2cap_conn_rsp rsp; | 548 | struct l2cap_conn_rsp rsp; |
548 | char buf[128]; | 549 | char buf[128]; |
549 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 550 | rsp.scid = cpu_to_le16(chan->dcid); |
550 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 551 | rsp.dcid = cpu_to_le16(chan->scid); |
551 | 552 | ||
552 | if (l2cap_check_security(sk)) { | 553 | if (l2cap_check_security(chan)) { |
553 | if (bt_sk(sk)->defer_setup) { | 554 | if (bt_sk(sk)->defer_setup) { |
554 | struct sock *parent = bt_sk(sk)->parent; | 555 | struct sock *parent = bt_sk(sk)->parent; |
555 | rsp.result = cpu_to_le16(L2CAP_CR_PEND); | 556 | rsp.result = cpu_to_le16(L2CAP_CR_PEND); |
@@ -569,13 +570,13 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
569 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | 570 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
570 | sizeof(rsp), &rsp); | 571 | sizeof(rsp), &rsp); |
571 | 572 | ||
572 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT || | 573 | if (chan->conf_state & L2CAP_CONF_REQ_SENT || |
573 | rsp.result != L2CAP_CR_SUCCESS) { | 574 | rsp.result != L2CAP_CR_SUCCESS) { |
574 | bh_unlock_sock(sk); | 575 | bh_unlock_sock(sk); |
575 | continue; | 576 | continue; |
576 | } | 577 | } |
577 | 578 | ||
578 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 579 | chan->conf_state |= L2CAP_CONF_REQ_SENT; |
579 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 580 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
580 | l2cap_build_conf_req(chan, buf), buf); | 581 | l2cap_build_conf_req(chan, buf), buf); |
581 | chan->num_conf_req++; | 582 | chan->num_conf_req++; |
@@ -598,10 +599,12 @@ static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) | |||
598 | read_lock(&l2cap_sk_list.lock); | 599 | read_lock(&l2cap_sk_list.lock); |
599 | 600 | ||
600 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 601 | sk_for_each(sk, node, &l2cap_sk_list.head) { |
602 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
603 | |||
601 | if (state && sk->sk_state != state) | 604 | if (state && sk->sk_state != state) |
602 | continue; | 605 | continue; |
603 | 606 | ||
604 | if (l2cap_pi(sk)->scid == cid) { | 607 | if (chan->scid == cid) { |
605 | /* Exact match. */ | 608 | /* Exact match. */ |
606 | if (!bacmp(&bt_sk(sk)->src, src)) | 609 | if (!bacmp(&bt_sk(sk)->src, src)) |
607 | break; | 610 | break; |
@@ -648,6 +651,8 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
648 | goto clean; | 651 | goto clean; |
649 | } | 652 | } |
650 | 653 | ||
654 | l2cap_pi(sk)->chan = chan; | ||
655 | |||
651 | write_lock_bh(&conn->chan_lock); | 656 | write_lock_bh(&conn->chan_lock); |
652 | 657 | ||
653 | hci_conn_hold(conn->hcon); | 658 | hci_conn_hold(conn->hcon); |
@@ -661,8 +666,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
661 | 666 | ||
662 | __l2cap_chan_add(conn, chan); | 667 | __l2cap_chan_add(conn, chan); |
663 | 668 | ||
664 | l2cap_pi(sk)->chan = chan; | ||
665 | |||
666 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 669 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); |
667 | 670 | ||
668 | sk->sk_state = BT_CONNECTED; | 671 | sk->sk_state = BT_CONNECTED; |
@@ -722,7 +725,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) | |||
722 | list_for_each_entry(chan, &conn->chan_l, list) { | 725 | list_for_each_entry(chan, &conn->chan_l, list) { |
723 | struct sock *sk = chan->sk; | 726 | struct sock *sk = chan->sk; |
724 | 727 | ||
725 | if (l2cap_pi(sk)->force_reliable) | 728 | if (chan->force_reliable) |
726 | sk->sk_err = err; | 729 | sk->sk_err = err; |
727 | } | 730 | } |
728 | 731 | ||
@@ -828,10 +831,12 @@ static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) | |||
828 | read_lock(&l2cap_sk_list.lock); | 831 | read_lock(&l2cap_sk_list.lock); |
829 | 832 | ||
830 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 833 | sk_for_each(sk, node, &l2cap_sk_list.head) { |
834 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
835 | |||
831 | if (state && sk->sk_state != state) | 836 | if (state && sk->sk_state != state) |
832 | continue; | 837 | continue; |
833 | 838 | ||
834 | if (l2cap_pi(sk)->psm == psm) { | 839 | if (chan->psm == psm) { |
835 | /* Exact match. */ | 840 | /* Exact match. */ |
836 | if (!bacmp(&bt_sk(sk)->src, src)) | 841 | if (!bacmp(&bt_sk(sk)->src, src)) |
837 | break; | 842 | break; |
@@ -847,19 +852,19 @@ static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) | |||
847 | return node ? sk : sk1; | 852 | return node ? sk : sk1; |
848 | } | 853 | } |
849 | 854 | ||
850 | int l2cap_do_connect(struct sock *sk) | 855 | int l2cap_chan_connect(struct l2cap_chan *chan) |
851 | { | 856 | { |
857 | struct sock *sk = chan->sk; | ||
852 | bdaddr_t *src = &bt_sk(sk)->src; | 858 | bdaddr_t *src = &bt_sk(sk)->src; |
853 | bdaddr_t *dst = &bt_sk(sk)->dst; | 859 | bdaddr_t *dst = &bt_sk(sk)->dst; |
854 | struct l2cap_conn *conn; | 860 | struct l2cap_conn *conn; |
855 | struct l2cap_chan *chan; | ||
856 | struct hci_conn *hcon; | 861 | struct hci_conn *hcon; |
857 | struct hci_dev *hdev; | 862 | struct hci_dev *hdev; |
858 | __u8 auth_type; | 863 | __u8 auth_type; |
859 | int err; | 864 | int err; |
860 | 865 | ||
861 | BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), | 866 | BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), |
862 | l2cap_pi(sk)->psm); | 867 | chan->psm); |
863 | 868 | ||
864 | hdev = hci_get_route(dst, src); | 869 | hdev = hci_get_route(dst, src); |
865 | if (!hdev) | 870 | if (!hdev) |
@@ -867,14 +872,14 @@ int l2cap_do_connect(struct sock *sk) | |||
867 | 872 | ||
868 | hci_dev_lock_bh(hdev); | 873 | hci_dev_lock_bh(hdev); |
869 | 874 | ||
870 | auth_type = l2cap_get_auth_type(sk); | 875 | auth_type = l2cap_get_auth_type(chan); |
871 | 876 | ||
872 | if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA) | 877 | if (chan->dcid == L2CAP_CID_LE_DATA) |
873 | hcon = hci_connect(hdev, LE_LINK, dst, | 878 | hcon = hci_connect(hdev, LE_LINK, dst, |
874 | l2cap_pi(sk)->sec_level, auth_type); | 879 | chan->sec_level, auth_type); |
875 | else | 880 | else |
876 | hcon = hci_connect(hdev, ACL_LINK, dst, | 881 | hcon = hci_connect(hdev, ACL_LINK, dst, |
877 | l2cap_pi(sk)->sec_level, auth_type); | 882 | chan->sec_level, auth_type); |
878 | 883 | ||
879 | if (IS_ERR(hcon)) { | 884 | if (IS_ERR(hcon)) { |
880 | err = PTR_ERR(hcon); | 885 | err = PTR_ERR(hcon); |
@@ -888,20 +893,11 @@ int l2cap_do_connect(struct sock *sk) | |||
888 | goto done; | 893 | goto done; |
889 | } | 894 | } |
890 | 895 | ||
891 | chan = l2cap_chan_alloc(sk); | ||
892 | if (!chan) { | ||
893 | hci_conn_put(hcon); | ||
894 | err = -ENOMEM; | ||
895 | goto done; | ||
896 | } | ||
897 | |||
898 | /* Update source addr of the socket */ | 896 | /* Update source addr of the socket */ |
899 | bacpy(src, conn->src); | 897 | bacpy(src, conn->src); |
900 | 898 | ||
901 | l2cap_chan_add(conn, chan); | 899 | l2cap_chan_add(conn, chan); |
902 | 900 | ||
903 | l2cap_pi(sk)->chan = chan; | ||
904 | |||
905 | sk->sk_state = BT_CONNECT; | 901 | sk->sk_state = BT_CONNECT; |
906 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 902 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); |
907 | 903 | ||
@@ -909,7 +905,7 @@ int l2cap_do_connect(struct sock *sk) | |||
909 | if (sk->sk_type != SOCK_SEQPACKET && | 905 | if (sk->sk_type != SOCK_SEQPACKET && |
910 | sk->sk_type != SOCK_STREAM) { | 906 | sk->sk_type != SOCK_STREAM) { |
911 | l2cap_sock_clear_timer(sk); | 907 | l2cap_sock_clear_timer(sk); |
912 | if (l2cap_check_security(sk)) | 908 | if (l2cap_check_security(chan)) |
913 | sk->sk_state = BT_CONNECTED; | 909 | sk->sk_state = BT_CONNECTED; |
914 | } else | 910 | } else |
915 | l2cap_do_start(chan); | 911 | l2cap_do_start(chan); |
@@ -925,12 +921,13 @@ done: | |||
925 | 921 | ||
926 | int __l2cap_wait_ack(struct sock *sk) | 922 | int __l2cap_wait_ack(struct sock *sk) |
927 | { | 923 | { |
924 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
928 | DECLARE_WAITQUEUE(wait, current); | 925 | DECLARE_WAITQUEUE(wait, current); |
929 | int err = 0; | 926 | int err = 0; |
930 | int timeo = HZ/5; | 927 | int timeo = HZ/5; |
931 | 928 | ||
932 | add_wait_queue(sk_sleep(sk), &wait); | 929 | add_wait_queue(sk_sleep(sk), &wait); |
933 | while ((l2cap_pi(sk)->chan->unacked_frames > 0 && l2cap_pi(sk)->conn)) { | 930 | while ((chan->unacked_frames > 0 && chan->conn)) { |
934 | set_current_state(TASK_INTERRUPTIBLE); | 931 | set_current_state(TASK_INTERRUPTIBLE); |
935 | 932 | ||
936 | if (!timeo) | 933 | if (!timeo) |
@@ -963,7 +960,7 @@ static void l2cap_monitor_timeout(unsigned long arg) | |||
963 | 960 | ||
964 | bh_lock_sock(sk); | 961 | bh_lock_sock(sk); |
965 | if (chan->retry_count >= chan->remote_max_tx) { | 962 | if (chan->retry_count >= chan->remote_max_tx) { |
966 | l2cap_send_disconn_req(l2cap_pi(sk)->conn, chan, ECONNABORTED); | 963 | l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); |
967 | bh_unlock_sock(sk); | 964 | bh_unlock_sock(sk); |
968 | return; | 965 | return; |
969 | } | 966 | } |
@@ -1011,15 +1008,14 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan) | |||
1011 | del_timer(&chan->retrans_timer); | 1008 | del_timer(&chan->retrans_timer); |
1012 | } | 1009 | } |
1013 | 1010 | ||
1014 | void l2cap_do_send(struct sock *sk, struct sk_buff *skb) | 1011 | void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) |
1015 | { | 1012 | { |
1016 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1013 | struct hci_conn *hcon = chan->conn->hcon; |
1017 | struct hci_conn *hcon = pi->conn->hcon; | ||
1018 | u16 flags; | 1014 | u16 flags; |
1019 | 1015 | ||
1020 | BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len); | 1016 | BT_DBG("chan %p, skb %p len %d", chan, skb, skb->len); |
1021 | 1017 | ||
1022 | if (!pi->flushable && lmp_no_flush_capable(hcon->hdev)) | 1018 | if (!chan->flushable && lmp_no_flush_capable(hcon->hdev)) |
1023 | flags = ACL_START_NO_FLUSH; | 1019 | flags = ACL_START_NO_FLUSH; |
1024 | else | 1020 | else |
1025 | flags = ACL_START; | 1021 | flags = ACL_START; |
@@ -1029,9 +1025,7 @@ void l2cap_do_send(struct sock *sk, struct sk_buff *skb) | |||
1029 | 1025 | ||
1030 | void l2cap_streaming_send(struct l2cap_chan *chan) | 1026 | void l2cap_streaming_send(struct l2cap_chan *chan) |
1031 | { | 1027 | { |
1032 | struct sock *sk = chan->sk; | ||
1033 | struct sk_buff *skb; | 1028 | struct sk_buff *skb; |
1034 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
1035 | u16 control, fcs; | 1029 | u16 control, fcs; |
1036 | 1030 | ||
1037 | while ((skb = skb_dequeue(&chan->tx_q))) { | 1031 | while ((skb = skb_dequeue(&chan->tx_q))) { |
@@ -1039,12 +1033,12 @@ void l2cap_streaming_send(struct l2cap_chan *chan) | |||
1039 | control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; | 1033 | control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; |
1040 | put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); | 1034 | put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); |
1041 | 1035 | ||
1042 | if (pi->fcs == L2CAP_FCS_CRC16) { | 1036 | if (chan->fcs == L2CAP_FCS_CRC16) { |
1043 | fcs = crc16(0, (u8 *)skb->data, skb->len - 2); | 1037 | fcs = crc16(0, (u8 *)skb->data, skb->len - 2); |
1044 | put_unaligned_le16(fcs, skb->data + skb->len - 2); | 1038 | put_unaligned_le16(fcs, skb->data + skb->len - 2); |
1045 | } | 1039 | } |
1046 | 1040 | ||
1047 | l2cap_do_send(sk, skb); | 1041 | l2cap_do_send(chan, skb); |
1048 | 1042 | ||
1049 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; | 1043 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; |
1050 | } | 1044 | } |
@@ -1052,8 +1046,6 @@ void l2cap_streaming_send(struct l2cap_chan *chan) | |||
1052 | 1046 | ||
1053 | static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | 1047 | static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) |
1054 | { | 1048 | { |
1055 | struct sock *sk = chan->sk; | ||
1056 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
1057 | struct sk_buff *skb, *tx_skb; | 1049 | struct sk_buff *skb, *tx_skb; |
1058 | u16 control, fcs; | 1050 | u16 control, fcs; |
1059 | 1051 | ||
@@ -1072,7 +1064,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | |||
1072 | 1064 | ||
1073 | if (chan->remote_max_tx && | 1065 | if (chan->remote_max_tx && |
1074 | bt_cb(skb)->retries == chan->remote_max_tx) { | 1066 | bt_cb(skb)->retries == chan->remote_max_tx) { |
1075 | l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED); | 1067 | l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); |
1076 | return; | 1068 | return; |
1077 | } | 1069 | } |
1078 | 1070 | ||
@@ -1091,19 +1083,18 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | |||
1091 | 1083 | ||
1092 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1084 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
1093 | 1085 | ||
1094 | if (pi->fcs == L2CAP_FCS_CRC16) { | 1086 | if (chan->fcs == L2CAP_FCS_CRC16) { |
1095 | fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); | 1087 | fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); |
1096 | put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); | 1088 | put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); |
1097 | } | 1089 | } |
1098 | 1090 | ||
1099 | l2cap_do_send(sk, tx_skb); | 1091 | l2cap_do_send(chan, tx_skb); |
1100 | } | 1092 | } |
1101 | 1093 | ||
1102 | int l2cap_ertm_send(struct l2cap_chan *chan) | 1094 | int l2cap_ertm_send(struct l2cap_chan *chan) |
1103 | { | 1095 | { |
1104 | struct sk_buff *skb, *tx_skb; | 1096 | struct sk_buff *skb, *tx_skb; |
1105 | struct sock *sk = chan->sk; | 1097 | struct sock *sk = chan->sk; |
1106 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
1107 | u16 control, fcs; | 1098 | u16 control, fcs; |
1108 | int nsent = 0; | 1099 | int nsent = 0; |
1109 | 1100 | ||
@@ -1114,7 +1105,7 @@ int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1114 | 1105 | ||
1115 | if (chan->remote_max_tx && | 1106 | if (chan->remote_max_tx && |
1116 | bt_cb(skb)->retries == chan->remote_max_tx) { | 1107 | bt_cb(skb)->retries == chan->remote_max_tx) { |
1117 | l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED); | 1108 | l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); |
1118 | break; | 1109 | break; |
1119 | } | 1110 | } |
1120 | 1111 | ||
@@ -1134,12 +1125,12 @@ int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1134 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1125 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
1135 | 1126 | ||
1136 | 1127 | ||
1137 | if (pi->fcs == L2CAP_FCS_CRC16) { | 1128 | if (chan->fcs == L2CAP_FCS_CRC16) { |
1138 | fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2); | 1129 | fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2); |
1139 | put_unaligned_le16(fcs, skb->data + tx_skb->len - 2); | 1130 | put_unaligned_le16(fcs, skb->data + tx_skb->len - 2); |
1140 | } | 1131 | } |
1141 | 1132 | ||
1142 | l2cap_do_send(sk, tx_skb); | 1133 | l2cap_do_send(chan, tx_skb); |
1143 | 1134 | ||
1144 | __mod_retrans_timer(); | 1135 | __mod_retrans_timer(); |
1145 | 1136 | ||
@@ -1210,7 +1201,7 @@ static void l2cap_send_srejtail(struct l2cap_chan *chan) | |||
1210 | 1201 | ||
1211 | static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb) | 1202 | static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb) |
1212 | { | 1203 | { |
1213 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1204 | struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; |
1214 | struct sk_buff **frag; | 1205 | struct sk_buff **frag; |
1215 | int err, sent = 0; | 1206 | int err, sent = 0; |
1216 | 1207 | ||
@@ -1240,9 +1231,10 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in | |||
1240 | return sent; | 1231 | return sent; |
1241 | } | 1232 | } |
1242 | 1233 | ||
1243 | struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len) | 1234 | struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) |
1244 | { | 1235 | { |
1245 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1236 | struct sock *sk = chan->sk; |
1237 | struct l2cap_conn *conn = chan->conn; | ||
1246 | struct sk_buff *skb; | 1238 | struct sk_buff *skb; |
1247 | int err, count, hlen = L2CAP_HDR_SIZE + 2; | 1239 | int err, count, hlen = L2CAP_HDR_SIZE + 2; |
1248 | struct l2cap_hdr *lh; | 1240 | struct l2cap_hdr *lh; |
@@ -1257,9 +1249,9 @@ struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, s | |||
1257 | 1249 | ||
1258 | /* Create L2CAP header */ | 1250 | /* Create L2CAP header */ |
1259 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1251 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
1260 | lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid); | 1252 | lh->cid = cpu_to_le16(chan->dcid); |
1261 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); | 1253 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); |
1262 | put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2)); | 1254 | put_unaligned_le16(chan->psm, skb_put(skb, 2)); |
1263 | 1255 | ||
1264 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); | 1256 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); |
1265 | if (unlikely(err < 0)) { | 1257 | if (unlikely(err < 0)) { |
@@ -1269,9 +1261,10 @@ struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, s | |||
1269 | return skb; | 1261 | return skb; |
1270 | } | 1262 | } |
1271 | 1263 | ||
1272 | struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len) | 1264 | struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) |
1273 | { | 1265 | { |
1274 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1266 | struct sock *sk = chan->sk; |
1267 | struct l2cap_conn *conn = chan->conn; | ||
1275 | struct sk_buff *skb; | 1268 | struct sk_buff *skb; |
1276 | int err, count, hlen = L2CAP_HDR_SIZE; | 1269 | int err, count, hlen = L2CAP_HDR_SIZE; |
1277 | struct l2cap_hdr *lh; | 1270 | struct l2cap_hdr *lh; |
@@ -1286,7 +1279,7 @@ struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size | |||
1286 | 1279 | ||
1287 | /* Create L2CAP header */ | 1280 | /* Create L2CAP header */ |
1288 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1281 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
1289 | lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid); | 1282 | lh->cid = cpu_to_le16(chan->dcid); |
1290 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); | 1283 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); |
1291 | 1284 | ||
1292 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); | 1285 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); |
@@ -1297,9 +1290,10 @@ struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size | |||
1297 | return skb; | 1290 | return skb; |
1298 | } | 1291 | } |
1299 | 1292 | ||
1300 | struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen) | 1293 | struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen) |
1301 | { | 1294 | { |
1302 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1295 | struct sock *sk = chan->sk; |
1296 | struct l2cap_conn *conn = chan->conn; | ||
1303 | struct sk_buff *skb; | 1297 | struct sk_buff *skb; |
1304 | int err, count, hlen = L2CAP_HDR_SIZE + 2; | 1298 | int err, count, hlen = L2CAP_HDR_SIZE + 2; |
1305 | struct l2cap_hdr *lh; | 1299 | struct l2cap_hdr *lh; |
@@ -1312,7 +1306,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz | |||
1312 | if (sdulen) | 1306 | if (sdulen) |
1313 | hlen += 2; | 1307 | hlen += 2; |
1314 | 1308 | ||
1315 | if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) | 1309 | if (chan->fcs == L2CAP_FCS_CRC16) |
1316 | hlen += 2; | 1310 | hlen += 2; |
1317 | 1311 | ||
1318 | count = min_t(unsigned int, (conn->mtu - hlen), len); | 1312 | count = min_t(unsigned int, (conn->mtu - hlen), len); |
@@ -1323,7 +1317,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz | |||
1323 | 1317 | ||
1324 | /* Create L2CAP header */ | 1318 | /* Create L2CAP header */ |
1325 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1319 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
1326 | lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid); | 1320 | lh->cid = cpu_to_le16(chan->dcid); |
1327 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); | 1321 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); |
1328 | put_unaligned_le16(control, skb_put(skb, 2)); | 1322 | put_unaligned_le16(control, skb_put(skb, 2)); |
1329 | if (sdulen) | 1323 | if (sdulen) |
@@ -1335,7 +1329,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz | |||
1335 | return ERR_PTR(err); | 1329 | return ERR_PTR(err); |
1336 | } | 1330 | } |
1337 | 1331 | ||
1338 | if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) | 1332 | if (chan->fcs == L2CAP_FCS_CRC16) |
1339 | put_unaligned_le16(0, skb_put(skb, 2)); | 1333 | put_unaligned_le16(0, skb_put(skb, 2)); |
1340 | 1334 | ||
1341 | bt_cb(skb)->retries = 0; | 1335 | bt_cb(skb)->retries = 0; |
@@ -1344,7 +1338,6 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz | |||
1344 | 1338 | ||
1345 | int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1339 | int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) |
1346 | { | 1340 | { |
1347 | struct sock *sk = chan->sk; | ||
1348 | struct sk_buff *skb; | 1341 | struct sk_buff *skb; |
1349 | struct sk_buff_head sar_queue; | 1342 | struct sk_buff_head sar_queue; |
1350 | u16 control; | 1343 | u16 control; |
@@ -1352,7 +1345,7 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le | |||
1352 | 1345 | ||
1353 | skb_queue_head_init(&sar_queue); | 1346 | skb_queue_head_init(&sar_queue); |
1354 | control = L2CAP_SDU_START; | 1347 | control = L2CAP_SDU_START; |
1355 | skb = l2cap_create_iframe_pdu(sk, msg, chan->remote_mps, control, len); | 1348 | skb = l2cap_create_iframe_pdu(chan, msg, chan->remote_mps, control, len); |
1356 | if (IS_ERR(skb)) | 1349 | if (IS_ERR(skb)) |
1357 | return PTR_ERR(skb); | 1350 | return PTR_ERR(skb); |
1358 | 1351 | ||
@@ -1371,7 +1364,7 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le | |||
1371 | buflen = len; | 1364 | buflen = len; |
1372 | } | 1365 | } |
1373 | 1366 | ||
1374 | skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0); | 1367 | skb = l2cap_create_iframe_pdu(chan, msg, buflen, control, 0); |
1375 | if (IS_ERR(skb)) { | 1368 | if (IS_ERR(skb)) { |
1376 | skb_queue_purge(&sar_queue); | 1369 | skb_queue_purge(&sar_queue); |
1377 | return PTR_ERR(skb); | 1370 | return PTR_ERR(skb); |
@@ -1391,10 +1384,11 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le | |||
1391 | static void l2cap_chan_ready(struct sock *sk) | 1384 | static void l2cap_chan_ready(struct sock *sk) |
1392 | { | 1385 | { |
1393 | struct sock *parent = bt_sk(sk)->parent; | 1386 | struct sock *parent = bt_sk(sk)->parent; |
1387 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
1394 | 1388 | ||
1395 | BT_DBG("sk %p, parent %p", sk, parent); | 1389 | BT_DBG("sk %p, parent %p", sk, parent); |
1396 | 1390 | ||
1397 | l2cap_pi(sk)->conf_state = 0; | 1391 | chan->conf_state = 0; |
1398 | l2cap_sock_clear_timer(sk); | 1392 | l2cap_sock_clear_timer(sk); |
1399 | 1393 | ||
1400 | if (!parent) { | 1394 | if (!parent) { |
@@ -1615,9 +1609,8 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) | |||
1615 | 1609 | ||
1616 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | 1610 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) |
1617 | { | 1611 | { |
1618 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | ||
1619 | struct l2cap_conf_req *req = data; | 1612 | struct l2cap_conf_req *req = data; |
1620 | struct l2cap_conf_rfc rfc = { .mode = pi->mode }; | 1613 | struct l2cap_conf_rfc rfc = { .mode = chan->mode }; |
1621 | void *ptr = req->data; | 1614 | void *ptr = req->data; |
1622 | 1615 | ||
1623 | BT_DBG("chan %p", chan); | 1616 | BT_DBG("chan %p", chan); |
@@ -1625,26 +1618,26 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | |||
1625 | if (chan->num_conf_req || chan->num_conf_rsp) | 1618 | if (chan->num_conf_req || chan->num_conf_rsp) |
1626 | goto done; | 1619 | goto done; |
1627 | 1620 | ||
1628 | switch (pi->mode) { | 1621 | switch (chan->mode) { |
1629 | case L2CAP_MODE_STREAMING: | 1622 | case L2CAP_MODE_STREAMING: |
1630 | case L2CAP_MODE_ERTM: | 1623 | case L2CAP_MODE_ERTM: |
1631 | if (pi->conf_state & L2CAP_CONF_STATE2_DEVICE) | 1624 | if (chan->conf_state & L2CAP_CONF_STATE2_DEVICE) |
1632 | break; | 1625 | break; |
1633 | 1626 | ||
1634 | /* fall through */ | 1627 | /* fall through */ |
1635 | default: | 1628 | default: |
1636 | pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask); | 1629 | chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask); |
1637 | break; | 1630 | break; |
1638 | } | 1631 | } |
1639 | 1632 | ||
1640 | done: | 1633 | done: |
1641 | if (pi->imtu != L2CAP_DEFAULT_MTU) | 1634 | if (chan->imtu != L2CAP_DEFAULT_MTU) |
1642 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); | 1635 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); |
1643 | 1636 | ||
1644 | switch (pi->mode) { | 1637 | switch (chan->mode) { |
1645 | case L2CAP_MODE_BASIC: | 1638 | case L2CAP_MODE_BASIC: |
1646 | if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) && | 1639 | if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) && |
1647 | !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING)) | 1640 | !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING)) |
1648 | break; | 1641 | break; |
1649 | 1642 | ||
1650 | rfc.mode = L2CAP_MODE_BASIC; | 1643 | rfc.mode = L2CAP_MODE_BASIC; |
@@ -1660,24 +1653,24 @@ done: | |||
1660 | 1653 | ||
1661 | case L2CAP_MODE_ERTM: | 1654 | case L2CAP_MODE_ERTM: |
1662 | rfc.mode = L2CAP_MODE_ERTM; | 1655 | rfc.mode = L2CAP_MODE_ERTM; |
1663 | rfc.txwin_size = pi->tx_win; | 1656 | rfc.txwin_size = chan->tx_win; |
1664 | rfc.max_transmit = pi->max_tx; | 1657 | rfc.max_transmit = chan->max_tx; |
1665 | rfc.retrans_timeout = 0; | 1658 | rfc.retrans_timeout = 0; |
1666 | rfc.monitor_timeout = 0; | 1659 | rfc.monitor_timeout = 0; |
1667 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); | 1660 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); |
1668 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) | 1661 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10) |
1669 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 1662 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); |
1670 | 1663 | ||
1671 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | 1664 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
1672 | (unsigned long) &rfc); | 1665 | (unsigned long) &rfc); |
1673 | 1666 | ||
1674 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) | 1667 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) |
1675 | break; | 1668 | break; |
1676 | 1669 | ||
1677 | if (pi->fcs == L2CAP_FCS_NONE || | 1670 | if (chan->fcs == L2CAP_FCS_NONE || |
1678 | pi->conf_state & L2CAP_CONF_NO_FCS_RECV) { | 1671 | chan->conf_state & L2CAP_CONF_NO_FCS_RECV) { |
1679 | pi->fcs = L2CAP_FCS_NONE; | 1672 | chan->fcs = L2CAP_FCS_NONE; |
1680 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs); | 1673 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); |
1681 | } | 1674 | } |
1682 | break; | 1675 | break; |
1683 | 1676 | ||
@@ -1688,24 +1681,24 @@ done: | |||
1688 | rfc.retrans_timeout = 0; | 1681 | rfc.retrans_timeout = 0; |
1689 | rfc.monitor_timeout = 0; | 1682 | rfc.monitor_timeout = 0; |
1690 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); | 1683 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); |
1691 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) | 1684 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10) |
1692 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 1685 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); |
1693 | 1686 | ||
1694 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | 1687 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
1695 | (unsigned long) &rfc); | 1688 | (unsigned long) &rfc); |
1696 | 1689 | ||
1697 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) | 1690 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) |
1698 | break; | 1691 | break; |
1699 | 1692 | ||
1700 | if (pi->fcs == L2CAP_FCS_NONE || | 1693 | if (chan->fcs == L2CAP_FCS_NONE || |
1701 | pi->conf_state & L2CAP_CONF_NO_FCS_RECV) { | 1694 | chan->conf_state & L2CAP_CONF_NO_FCS_RECV) { |
1702 | pi->fcs = L2CAP_FCS_NONE; | 1695 | chan->fcs = L2CAP_FCS_NONE; |
1703 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs); | 1696 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); |
1704 | } | 1697 | } |
1705 | break; | 1698 | break; |
1706 | } | 1699 | } |
1707 | 1700 | ||
1708 | req->dcid = cpu_to_le16(pi->dcid); | 1701 | req->dcid = cpu_to_le16(chan->dcid); |
1709 | req->flags = cpu_to_le16(0); | 1702 | req->flags = cpu_to_le16(0); |
1710 | 1703 | ||
1711 | return ptr - data; | 1704 | return ptr - data; |
@@ -1713,7 +1706,6 @@ done: | |||
1713 | 1706 | ||
1714 | static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | 1707 | static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) |
1715 | { | 1708 | { |
1716 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | ||
1717 | struct l2cap_conf_rsp *rsp = data; | 1709 | struct l2cap_conf_rsp *rsp = data; |
1718 | void *ptr = rsp->data; | 1710 | void *ptr = rsp->data; |
1719 | void *req = chan->conf_req; | 1711 | void *req = chan->conf_req; |
@@ -1738,7 +1730,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
1738 | break; | 1730 | break; |
1739 | 1731 | ||
1740 | case L2CAP_CONF_FLUSH_TO: | 1732 | case L2CAP_CONF_FLUSH_TO: |
1741 | pi->flush_to = val; | 1733 | chan->flush_to = val; |
1742 | break; | 1734 | break; |
1743 | 1735 | ||
1744 | case L2CAP_CONF_QOS: | 1736 | case L2CAP_CONF_QOS: |
@@ -1751,7 +1743,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
1751 | 1743 | ||
1752 | case L2CAP_CONF_FCS: | 1744 | case L2CAP_CONF_FCS: |
1753 | if (val == L2CAP_FCS_NONE) | 1745 | if (val == L2CAP_FCS_NONE) |
1754 | pi->conf_state |= L2CAP_CONF_NO_FCS_RECV; | 1746 | chan->conf_state |= L2CAP_CONF_NO_FCS_RECV; |
1755 | 1747 | ||
1756 | break; | 1748 | break; |
1757 | 1749 | ||
@@ -1768,25 +1760,25 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
1768 | if (chan->num_conf_rsp || chan->num_conf_req > 1) | 1760 | if (chan->num_conf_rsp || chan->num_conf_req > 1) |
1769 | goto done; | 1761 | goto done; |
1770 | 1762 | ||
1771 | switch (pi->mode) { | 1763 | switch (chan->mode) { |
1772 | case L2CAP_MODE_STREAMING: | 1764 | case L2CAP_MODE_STREAMING: |
1773 | case L2CAP_MODE_ERTM: | 1765 | case L2CAP_MODE_ERTM: |
1774 | if (!(pi->conf_state & L2CAP_CONF_STATE2_DEVICE)) { | 1766 | if (!(chan->conf_state & L2CAP_CONF_STATE2_DEVICE)) { |
1775 | pi->mode = l2cap_select_mode(rfc.mode, | 1767 | chan->mode = l2cap_select_mode(rfc.mode, |
1776 | pi->conn->feat_mask); | 1768 | chan->conn->feat_mask); |
1777 | break; | 1769 | break; |
1778 | } | 1770 | } |
1779 | 1771 | ||
1780 | if (pi->mode != rfc.mode) | 1772 | if (chan->mode != rfc.mode) |
1781 | return -ECONNREFUSED; | 1773 | return -ECONNREFUSED; |
1782 | 1774 | ||
1783 | break; | 1775 | break; |
1784 | } | 1776 | } |
1785 | 1777 | ||
1786 | done: | 1778 | done: |
1787 | if (pi->mode != rfc.mode) { | 1779 | if (chan->mode != rfc.mode) { |
1788 | result = L2CAP_CONF_UNACCEPT; | 1780 | result = L2CAP_CONF_UNACCEPT; |
1789 | rfc.mode = pi->mode; | 1781 | rfc.mode = chan->mode; |
1790 | 1782 | ||
1791 | if (chan->num_conf_rsp == 1) | 1783 | if (chan->num_conf_rsp == 1) |
1792 | return -ECONNREFUSED; | 1784 | return -ECONNREFUSED; |
@@ -1803,23 +1795,23 @@ done: | |||
1803 | if (mtu < L2CAP_DEFAULT_MIN_MTU) | 1795 | if (mtu < L2CAP_DEFAULT_MIN_MTU) |
1804 | result = L2CAP_CONF_UNACCEPT; | 1796 | result = L2CAP_CONF_UNACCEPT; |
1805 | else { | 1797 | else { |
1806 | pi->omtu = mtu; | 1798 | chan->omtu = mtu; |
1807 | pi->conf_state |= L2CAP_CONF_MTU_DONE; | 1799 | chan->conf_state |= L2CAP_CONF_MTU_DONE; |
1808 | } | 1800 | } |
1809 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); | 1801 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); |
1810 | 1802 | ||
1811 | switch (rfc.mode) { | 1803 | switch (rfc.mode) { |
1812 | case L2CAP_MODE_BASIC: | 1804 | case L2CAP_MODE_BASIC: |
1813 | pi->fcs = L2CAP_FCS_NONE; | 1805 | chan->fcs = L2CAP_FCS_NONE; |
1814 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 1806 | chan->conf_state |= L2CAP_CONF_MODE_DONE; |
1815 | break; | 1807 | break; |
1816 | 1808 | ||
1817 | case L2CAP_MODE_ERTM: | 1809 | case L2CAP_MODE_ERTM: |
1818 | chan->remote_tx_win = rfc.txwin_size; | 1810 | chan->remote_tx_win = rfc.txwin_size; |
1819 | chan->remote_max_tx = rfc.max_transmit; | 1811 | chan->remote_max_tx = rfc.max_transmit; |
1820 | 1812 | ||
1821 | if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) | 1813 | if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10) |
1822 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 1814 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); |
1823 | 1815 | ||
1824 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); | 1816 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); |
1825 | 1817 | ||
@@ -1828,7 +1820,7 @@ done: | |||
1828 | rfc.monitor_timeout = | 1820 | rfc.monitor_timeout = |
1829 | le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO); | 1821 | le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO); |
1830 | 1822 | ||
1831 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 1823 | chan->conf_state |= L2CAP_CONF_MODE_DONE; |
1832 | 1824 | ||
1833 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 1825 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
1834 | sizeof(rfc), (unsigned long) &rfc); | 1826 | sizeof(rfc), (unsigned long) &rfc); |
@@ -1836,12 +1828,12 @@ done: | |||
1836 | break; | 1828 | break; |
1837 | 1829 | ||
1838 | case L2CAP_MODE_STREAMING: | 1830 | case L2CAP_MODE_STREAMING: |
1839 | if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) | 1831 | if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10) |
1840 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 1832 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); |
1841 | 1833 | ||
1842 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); | 1834 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); |
1843 | 1835 | ||
1844 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 1836 | chan->conf_state |= L2CAP_CONF_MODE_DONE; |
1845 | 1837 | ||
1846 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 1838 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
1847 | sizeof(rfc), (unsigned long) &rfc); | 1839 | sizeof(rfc), (unsigned long) &rfc); |
@@ -1852,29 +1844,28 @@ done: | |||
1852 | result = L2CAP_CONF_UNACCEPT; | 1844 | result = L2CAP_CONF_UNACCEPT; |
1853 | 1845 | ||
1854 | memset(&rfc, 0, sizeof(rfc)); | 1846 | memset(&rfc, 0, sizeof(rfc)); |
1855 | rfc.mode = pi->mode; | 1847 | rfc.mode = chan->mode; |
1856 | } | 1848 | } |
1857 | 1849 | ||
1858 | if (result == L2CAP_CONF_SUCCESS) | 1850 | if (result == L2CAP_CONF_SUCCESS) |
1859 | pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; | 1851 | chan->conf_state |= L2CAP_CONF_OUTPUT_DONE; |
1860 | } | 1852 | } |
1861 | rsp->scid = cpu_to_le16(pi->dcid); | 1853 | rsp->scid = cpu_to_le16(chan->dcid); |
1862 | rsp->result = cpu_to_le16(result); | 1854 | rsp->result = cpu_to_le16(result); |
1863 | rsp->flags = cpu_to_le16(0x0000); | 1855 | rsp->flags = cpu_to_le16(0x0000); |
1864 | 1856 | ||
1865 | return ptr - data; | 1857 | return ptr - data; |
1866 | } | 1858 | } |
1867 | 1859 | ||
1868 | static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result) | 1860 | static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, void *data, u16 *result) |
1869 | { | 1861 | { |
1870 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
1871 | struct l2cap_conf_req *req = data; | 1862 | struct l2cap_conf_req *req = data; |
1872 | void *ptr = req->data; | 1863 | void *ptr = req->data; |
1873 | int type, olen; | 1864 | int type, olen; |
1874 | unsigned long val; | 1865 | unsigned long val; |
1875 | struct l2cap_conf_rfc rfc; | 1866 | struct l2cap_conf_rfc rfc; |
1876 | 1867 | ||
1877 | BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data); | 1868 | BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); |
1878 | 1869 | ||
1879 | while (len >= L2CAP_CONF_OPT_SIZE) { | 1870 | while (len >= L2CAP_CONF_OPT_SIZE) { |
1880 | len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); | 1871 | len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); |
@@ -1883,27 +1874,27 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, | |||
1883 | case L2CAP_CONF_MTU: | 1874 | case L2CAP_CONF_MTU: |
1884 | if (val < L2CAP_DEFAULT_MIN_MTU) { | 1875 | if (val < L2CAP_DEFAULT_MIN_MTU) { |
1885 | *result = L2CAP_CONF_UNACCEPT; | 1876 | *result = L2CAP_CONF_UNACCEPT; |
1886 | pi->imtu = L2CAP_DEFAULT_MIN_MTU; | 1877 | chan->imtu = L2CAP_DEFAULT_MIN_MTU; |
1887 | } else | 1878 | } else |
1888 | pi->imtu = val; | 1879 | chan->imtu = val; |
1889 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); | 1880 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu); |
1890 | break; | 1881 | break; |
1891 | 1882 | ||
1892 | case L2CAP_CONF_FLUSH_TO: | 1883 | case L2CAP_CONF_FLUSH_TO: |
1893 | pi->flush_to = val; | 1884 | chan->flush_to = val; |
1894 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, | 1885 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, |
1895 | 2, pi->flush_to); | 1886 | 2, chan->flush_to); |
1896 | break; | 1887 | break; |
1897 | 1888 | ||
1898 | case L2CAP_CONF_RFC: | 1889 | case L2CAP_CONF_RFC: |
1899 | if (olen == sizeof(rfc)) | 1890 | if (olen == sizeof(rfc)) |
1900 | memcpy(&rfc, (void *)val, olen); | 1891 | memcpy(&rfc, (void *)val, olen); |
1901 | 1892 | ||
1902 | if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) && | 1893 | if ((chan->conf_state & L2CAP_CONF_STATE2_DEVICE) && |
1903 | rfc.mode != pi->mode) | 1894 | rfc.mode != chan->mode) |
1904 | return -ECONNREFUSED; | 1895 | return -ECONNREFUSED; |
1905 | 1896 | ||
1906 | pi->fcs = 0; | 1897 | chan->fcs = 0; |
1907 | 1898 | ||
1908 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 1899 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
1909 | sizeof(rfc), (unsigned long) &rfc); | 1900 | sizeof(rfc), (unsigned long) &rfc); |
@@ -1911,78 +1902,74 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, | |||
1911 | } | 1902 | } |
1912 | } | 1903 | } |
1913 | 1904 | ||
1914 | if (pi->mode == L2CAP_MODE_BASIC && pi->mode != rfc.mode) | 1905 | if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode) |
1915 | return -ECONNREFUSED; | 1906 | return -ECONNREFUSED; |
1916 | 1907 | ||
1917 | pi->mode = rfc.mode; | 1908 | chan->mode = rfc.mode; |
1918 | 1909 | ||
1919 | if (*result == L2CAP_CONF_SUCCESS) { | 1910 | if (*result == L2CAP_CONF_SUCCESS) { |
1920 | switch (rfc.mode) { | 1911 | switch (rfc.mode) { |
1921 | case L2CAP_MODE_ERTM: | 1912 | case L2CAP_MODE_ERTM: |
1922 | pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); | 1913 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); |
1923 | pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); | 1914 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); |
1924 | pi->mps = le16_to_cpu(rfc.max_pdu_size); | 1915 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
1925 | break; | 1916 | break; |
1926 | case L2CAP_MODE_STREAMING: | 1917 | case L2CAP_MODE_STREAMING: |
1927 | pi->mps = le16_to_cpu(rfc.max_pdu_size); | 1918 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
1928 | } | 1919 | } |
1929 | } | 1920 | } |
1930 | 1921 | ||
1931 | req->dcid = cpu_to_le16(pi->dcid); | 1922 | req->dcid = cpu_to_le16(chan->dcid); |
1932 | req->flags = cpu_to_le16(0x0000); | 1923 | req->flags = cpu_to_le16(0x0000); |
1933 | 1924 | ||
1934 | return ptr - data; | 1925 | return ptr - data; |
1935 | } | 1926 | } |
1936 | 1927 | ||
1937 | static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags) | 1928 | static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags) |
1938 | { | 1929 | { |
1939 | struct l2cap_conf_rsp *rsp = data; | 1930 | struct l2cap_conf_rsp *rsp = data; |
1940 | void *ptr = rsp->data; | 1931 | void *ptr = rsp->data; |
1941 | 1932 | ||
1942 | BT_DBG("sk %p", sk); | 1933 | BT_DBG("chan %p", chan); |
1943 | 1934 | ||
1944 | rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 1935 | rsp->scid = cpu_to_le16(chan->dcid); |
1945 | rsp->result = cpu_to_le16(result); | 1936 | rsp->result = cpu_to_le16(result); |
1946 | rsp->flags = cpu_to_le16(flags); | 1937 | rsp->flags = cpu_to_le16(flags); |
1947 | 1938 | ||
1948 | return ptr - data; | 1939 | return ptr - data; |
1949 | } | 1940 | } |
1950 | 1941 | ||
1951 | void __l2cap_connect_rsp_defer(struct sock *sk) | 1942 | void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) |
1952 | { | 1943 | { |
1953 | struct l2cap_conn_rsp rsp; | 1944 | struct l2cap_conn_rsp rsp; |
1954 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1945 | struct l2cap_conn *conn = chan->conn; |
1955 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
1956 | u8 buf[128]; | 1946 | u8 buf[128]; |
1957 | 1947 | ||
1958 | sk->sk_state = BT_CONFIG; | 1948 | rsp.scid = cpu_to_le16(chan->dcid); |
1959 | 1949 | rsp.dcid = cpu_to_le16(chan->scid); | |
1960 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
1961 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
1962 | rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); | 1950 | rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); |
1963 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | 1951 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); |
1964 | l2cap_send_cmd(conn, chan->ident, | 1952 | l2cap_send_cmd(conn, chan->ident, |
1965 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 1953 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); |
1966 | 1954 | ||
1967 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) | 1955 | if (chan->conf_state & L2CAP_CONF_REQ_SENT) |
1968 | return; | 1956 | return; |
1969 | 1957 | ||
1970 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 1958 | chan->conf_state |= L2CAP_CONF_REQ_SENT; |
1971 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 1959 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
1972 | l2cap_build_conf_req(chan, buf), buf); | 1960 | l2cap_build_conf_req(chan, buf), buf); |
1973 | chan->num_conf_req++; | 1961 | chan->num_conf_req++; |
1974 | } | 1962 | } |
1975 | 1963 | ||
1976 | static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len) | 1964 | static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) |
1977 | { | 1965 | { |
1978 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
1979 | int type, olen; | 1966 | int type, olen; |
1980 | unsigned long val; | 1967 | unsigned long val; |
1981 | struct l2cap_conf_rfc rfc; | 1968 | struct l2cap_conf_rfc rfc; |
1982 | 1969 | ||
1983 | BT_DBG("sk %p, rsp %p, len %d", sk, rsp, len); | 1970 | BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len); |
1984 | 1971 | ||
1985 | if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING)) | 1972 | if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING)) |
1986 | return; | 1973 | return; |
1987 | 1974 | ||
1988 | while (len >= L2CAP_CONF_OPT_SIZE) { | 1975 | while (len >= L2CAP_CONF_OPT_SIZE) { |
@@ -1999,12 +1986,12 @@ static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len) | |||
1999 | done: | 1986 | done: |
2000 | switch (rfc.mode) { | 1987 | switch (rfc.mode) { |
2001 | case L2CAP_MODE_ERTM: | 1988 | case L2CAP_MODE_ERTM: |
2002 | pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); | 1989 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); |
2003 | pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); | 1990 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); |
2004 | pi->mps = le16_to_cpu(rfc.max_pdu_size); | 1991 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
2005 | break; | 1992 | break; |
2006 | case L2CAP_MODE_STREAMING: | 1993 | case L2CAP_MODE_STREAMING: |
2007 | pi->mps = le16_to_cpu(rfc.max_pdu_size); | 1994 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
2008 | } | 1995 | } |
2009 | } | 1996 | } |
2010 | 1997 | ||
@@ -2076,6 +2063,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2076 | goto response; | 2063 | goto response; |
2077 | } | 2064 | } |
2078 | 2065 | ||
2066 | l2cap_pi(sk)->chan = chan; | ||
2067 | |||
2079 | write_lock_bh(&conn->chan_lock); | 2068 | write_lock_bh(&conn->chan_lock); |
2080 | 2069 | ||
2081 | /* Check if we already have channel with that dcid */ | 2070 | /* Check if we already have channel with that dcid */ |
@@ -2091,23 +2080,21 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2091 | l2cap_sock_init(sk, parent); | 2080 | l2cap_sock_init(sk, parent); |
2092 | bacpy(&bt_sk(sk)->src, conn->src); | 2081 | bacpy(&bt_sk(sk)->src, conn->src); |
2093 | bacpy(&bt_sk(sk)->dst, conn->dst); | 2082 | bacpy(&bt_sk(sk)->dst, conn->dst); |
2094 | l2cap_pi(sk)->psm = psm; | 2083 | chan->psm = psm; |
2095 | l2cap_pi(sk)->dcid = scid; | 2084 | chan->dcid = scid; |
2096 | 2085 | ||
2097 | bt_accept_enqueue(parent, sk); | 2086 | bt_accept_enqueue(parent, sk); |
2098 | 2087 | ||
2099 | __l2cap_chan_add(conn, chan); | 2088 | __l2cap_chan_add(conn, chan); |
2100 | 2089 | ||
2101 | l2cap_pi(sk)->chan = chan; | 2090 | dcid = chan->scid; |
2102 | |||
2103 | dcid = l2cap_pi(sk)->scid; | ||
2104 | 2091 | ||
2105 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | 2092 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); |
2106 | 2093 | ||
2107 | chan->ident = cmd->ident; | 2094 | chan->ident = cmd->ident; |
2108 | 2095 | ||
2109 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { | 2096 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { |
2110 | if (l2cap_check_security(sk)) { | 2097 | if (l2cap_check_security(chan)) { |
2111 | if (bt_sk(sk)->defer_setup) { | 2098 | if (bt_sk(sk)->defer_setup) { |
2112 | sk->sk_state = BT_CONNECT2; | 2099 | sk->sk_state = BT_CONNECT2; |
2113 | result = L2CAP_CR_PEND; | 2100 | result = L2CAP_CR_PEND; |
@@ -2155,10 +2142,10 @@ sendresp: | |||
2155 | L2CAP_INFO_REQ, sizeof(info), &info); | 2142 | L2CAP_INFO_REQ, sizeof(info), &info); |
2156 | } | 2143 | } |
2157 | 2144 | ||
2158 | if (chan && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && | 2145 | if (chan && !(chan->conf_state & L2CAP_CONF_REQ_SENT) && |
2159 | result == L2CAP_CR_SUCCESS) { | 2146 | result == L2CAP_CR_SUCCESS) { |
2160 | u8 buf[128]; | 2147 | u8 buf[128]; |
2161 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 2148 | chan->conf_state |= L2CAP_CONF_REQ_SENT; |
2162 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2149 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2163 | l2cap_build_conf_req(chan, buf), buf); | 2150 | l2cap_build_conf_req(chan, buf), buf); |
2164 | chan->num_conf_req++; | 2151 | chan->num_conf_req++; |
@@ -2198,13 +2185,13 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2198 | case L2CAP_CR_SUCCESS: | 2185 | case L2CAP_CR_SUCCESS: |
2199 | sk->sk_state = BT_CONFIG; | 2186 | sk->sk_state = BT_CONFIG; |
2200 | chan->ident = 0; | 2187 | chan->ident = 0; |
2201 | l2cap_pi(sk)->dcid = dcid; | 2188 | chan->dcid = dcid; |
2202 | l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; | 2189 | chan->conf_state &= ~L2CAP_CONF_CONNECT_PEND; |
2203 | 2190 | ||
2204 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) | 2191 | if (chan->conf_state & L2CAP_CONF_REQ_SENT) |
2205 | break; | 2192 | break; |
2206 | 2193 | ||
2207 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 2194 | chan->conf_state |= L2CAP_CONF_REQ_SENT; |
2208 | 2195 | ||
2209 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2196 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2210 | l2cap_build_conf_req(chan, req), req); | 2197 | l2cap_build_conf_req(chan, req), req); |
@@ -2212,7 +2199,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2212 | break; | 2199 | break; |
2213 | 2200 | ||
2214 | case L2CAP_CR_PEND: | 2201 | case L2CAP_CR_PEND: |
2215 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; | 2202 | chan->conf_state |= L2CAP_CONF_CONNECT_PEND; |
2216 | break; | 2203 | break; |
2217 | 2204 | ||
2218 | default: | 2205 | default: |
@@ -2232,15 +2219,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2232 | return 0; | 2219 | return 0; |
2233 | } | 2220 | } |
2234 | 2221 | ||
2235 | static inline void set_default_fcs(struct l2cap_pinfo *pi) | 2222 | static inline void set_default_fcs(struct l2cap_chan *chan) |
2236 | { | 2223 | { |
2224 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | ||
2225 | |||
2237 | /* FCS is enabled only in ERTM or streaming mode, if one or both | 2226 | /* FCS is enabled only in ERTM or streaming mode, if one or both |
2238 | * sides request it. | 2227 | * sides request it. |
2239 | */ | 2228 | */ |
2240 | if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING) | 2229 | if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING) |
2241 | pi->fcs = L2CAP_FCS_NONE; | 2230 | chan->fcs = L2CAP_FCS_NONE; |
2242 | else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV)) | 2231 | else if (!(pi->chan->conf_state & L2CAP_CONF_NO_FCS_RECV)) |
2243 | pi->fcs = L2CAP_FCS_CRC16; | 2232 | chan->fcs = L2CAP_FCS_CRC16; |
2244 | } | 2233 | } |
2245 | 2234 | ||
2246 | static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) | 2235 | static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) |
@@ -2276,7 +2265,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2276 | len = cmd_len - sizeof(*req); | 2265 | len = cmd_len - sizeof(*req); |
2277 | if (chan->conf_len + len > sizeof(chan->conf_req)) { | 2266 | if (chan->conf_len + len > sizeof(chan->conf_req)) { |
2278 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 2267 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
2279 | l2cap_build_conf_rsp(sk, rsp, | 2268 | l2cap_build_conf_rsp(chan, rsp, |
2280 | L2CAP_CONF_REJECT, flags), rsp); | 2269 | L2CAP_CONF_REJECT, flags), rsp); |
2281 | goto unlock; | 2270 | goto unlock; |
2282 | } | 2271 | } |
@@ -2288,7 +2277,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2288 | if (flags & 0x0001) { | 2277 | if (flags & 0x0001) { |
2289 | /* Incomplete config. Send empty response. */ | 2278 | /* Incomplete config. Send empty response. */ |
2290 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 2279 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
2291 | l2cap_build_conf_rsp(sk, rsp, | 2280 | l2cap_build_conf_rsp(chan, rsp, |
2292 | L2CAP_CONF_SUCCESS, 0x0001), rsp); | 2281 | L2CAP_CONF_SUCCESS, 0x0001), rsp); |
2293 | goto unlock; | 2282 | goto unlock; |
2294 | } | 2283 | } |
@@ -2306,27 +2295,27 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2306 | /* Reset config buffer. */ | 2295 | /* Reset config buffer. */ |
2307 | chan->conf_len = 0; | 2296 | chan->conf_len = 0; |
2308 | 2297 | ||
2309 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE)) | 2298 | if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE)) |
2310 | goto unlock; | 2299 | goto unlock; |
2311 | 2300 | ||
2312 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { | 2301 | if (chan->conf_state & L2CAP_CONF_INPUT_DONE) { |
2313 | set_default_fcs(l2cap_pi(sk)); | 2302 | set_default_fcs(chan); |
2314 | 2303 | ||
2315 | sk->sk_state = BT_CONNECTED; | 2304 | sk->sk_state = BT_CONNECTED; |
2316 | 2305 | ||
2317 | chan->next_tx_seq = 0; | 2306 | chan->next_tx_seq = 0; |
2318 | chan->expected_tx_seq = 0; | 2307 | chan->expected_tx_seq = 0; |
2319 | skb_queue_head_init(&chan->tx_q); | 2308 | skb_queue_head_init(&chan->tx_q); |
2320 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) | 2309 | if (chan->mode == L2CAP_MODE_ERTM) |
2321 | l2cap_ertm_init(chan); | 2310 | l2cap_ertm_init(chan); |
2322 | 2311 | ||
2323 | l2cap_chan_ready(sk); | 2312 | l2cap_chan_ready(sk); |
2324 | goto unlock; | 2313 | goto unlock; |
2325 | } | 2314 | } |
2326 | 2315 | ||
2327 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) { | 2316 | if (!(chan->conf_state & L2CAP_CONF_REQ_SENT)) { |
2328 | u8 buf[64]; | 2317 | u8 buf[64]; |
2329 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | 2318 | chan->conf_state |= L2CAP_CONF_REQ_SENT; |
2330 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 2319 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
2331 | l2cap_build_conf_req(chan, buf), buf); | 2320 | l2cap_build_conf_req(chan, buf), buf); |
2332 | chan->num_conf_req++; | 2321 | chan->num_conf_req++; |
@@ -2360,7 +2349,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2360 | 2349 | ||
2361 | switch (result) { | 2350 | switch (result) { |
2362 | case L2CAP_CONF_SUCCESS: | 2351 | case L2CAP_CONF_SUCCESS: |
2363 | l2cap_conf_rfc_get(sk, rsp->data, len); | 2352 | l2cap_conf_rfc_get(chan, rsp->data, len); |
2364 | break; | 2353 | break; |
2365 | 2354 | ||
2366 | case L2CAP_CONF_UNACCEPT: | 2355 | case L2CAP_CONF_UNACCEPT: |
@@ -2374,8 +2363,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2374 | 2363 | ||
2375 | /* throw out any old stored conf requests */ | 2364 | /* throw out any old stored conf requests */ |
2376 | result = L2CAP_CONF_SUCCESS; | 2365 | result = L2CAP_CONF_SUCCESS; |
2377 | len = l2cap_parse_conf_rsp(sk, rsp->data, | 2366 | len = l2cap_parse_conf_rsp(chan, rsp->data, len, |
2378 | len, req, &result); | 2367 | req, &result); |
2379 | if (len < 0) { | 2368 | if (len < 0) { |
2380 | l2cap_send_disconn_req(conn, chan, ECONNRESET); | 2369 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
2381 | goto done; | 2370 | goto done; |
@@ -2399,16 +2388,16 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2399 | if (flags & 0x01) | 2388 | if (flags & 0x01) |
2400 | goto done; | 2389 | goto done; |
2401 | 2390 | ||
2402 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; | 2391 | chan->conf_state |= L2CAP_CONF_INPUT_DONE; |
2403 | 2392 | ||
2404 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { | 2393 | if (chan->conf_state & L2CAP_CONF_OUTPUT_DONE) { |
2405 | set_default_fcs(l2cap_pi(sk)); | 2394 | set_default_fcs(chan); |
2406 | 2395 | ||
2407 | sk->sk_state = BT_CONNECTED; | 2396 | sk->sk_state = BT_CONNECTED; |
2408 | chan->next_tx_seq = 0; | 2397 | chan->next_tx_seq = 0; |
2409 | chan->expected_tx_seq = 0; | 2398 | chan->expected_tx_seq = 0; |
2410 | skb_queue_head_init(&chan->tx_q); | 2399 | skb_queue_head_init(&chan->tx_q); |
2411 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) | 2400 | if (chan->mode == L2CAP_MODE_ERTM) |
2412 | l2cap_ertm_init(chan); | 2401 | l2cap_ertm_init(chan); |
2413 | 2402 | ||
2414 | l2cap_chan_ready(sk); | 2403 | l2cap_chan_ready(sk); |
@@ -2438,8 +2427,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2438 | 2427 | ||
2439 | sk = chan->sk; | 2428 | sk = chan->sk; |
2440 | 2429 | ||
2441 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 2430 | rsp.dcid = cpu_to_le16(chan->scid); |
2442 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 2431 | rsp.scid = cpu_to_le16(chan->dcid); |
2443 | l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp); | 2432 | l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp); |
2444 | 2433 | ||
2445 | sk->sk_shutdown = SHUTDOWN_MASK; | 2434 | sk->sk_shutdown = SHUTDOWN_MASK; |
@@ -2774,12 +2763,12 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
2774 | kfree_skb(skb); | 2763 | kfree_skb(skb); |
2775 | } | 2764 | } |
2776 | 2765 | ||
2777 | static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb) | 2766 | static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) |
2778 | { | 2767 | { |
2779 | u16 our_fcs, rcv_fcs; | 2768 | u16 our_fcs, rcv_fcs; |
2780 | int hdr_size = L2CAP_HDR_SIZE + 2; | 2769 | int hdr_size = L2CAP_HDR_SIZE + 2; |
2781 | 2770 | ||
2782 | if (pi->fcs == L2CAP_FCS_CRC16) { | 2771 | if (chan->fcs == L2CAP_FCS_CRC16) { |
2783 | skb_trim(skb, skb->len - 2); | 2772 | skb_trim(skb, skb->len - 2); |
2784 | rcv_fcs = get_unaligned_le16(skb->data + skb->len); | 2773 | rcv_fcs = get_unaligned_le16(skb->data + skb->len); |
2785 | our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); | 2774 | our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); |
@@ -2860,7 +2849,6 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, | |||
2860 | 2849 | ||
2861 | static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | 2850 | static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) |
2862 | { | 2851 | { |
2863 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | ||
2864 | struct sk_buff *_skb; | 2852 | struct sk_buff *_skb; |
2865 | int err; | 2853 | int err; |
2866 | 2854 | ||
@@ -2881,7 +2869,7 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk | |||
2881 | 2869 | ||
2882 | chan->sdu_len = get_unaligned_le16(skb->data); | 2870 | chan->sdu_len = get_unaligned_le16(skb->data); |
2883 | 2871 | ||
2884 | if (chan->sdu_len > pi->imtu) | 2872 | if (chan->sdu_len > chan->imtu) |
2885 | goto disconnect; | 2873 | goto disconnect; |
2886 | 2874 | ||
2887 | chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC); | 2875 | chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC); |
@@ -2924,7 +2912,7 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk | |||
2924 | if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) { | 2912 | if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) { |
2925 | chan->partial_sdu_len += skb->len; | 2913 | chan->partial_sdu_len += skb->len; |
2926 | 2914 | ||
2927 | if (chan->partial_sdu_len > pi->imtu) | 2915 | if (chan->partial_sdu_len > chan->imtu) |
2928 | goto drop; | 2916 | goto drop; |
2929 | 2917 | ||
2930 | if (chan->partial_sdu_len != chan->sdu_len) | 2918 | if (chan->partial_sdu_len != chan->sdu_len) |
@@ -2961,7 +2949,7 @@ drop: | |||
2961 | chan->sdu = NULL; | 2949 | chan->sdu = NULL; |
2962 | 2950 | ||
2963 | disconnect: | 2951 | disconnect: |
2964 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); | 2952 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
2965 | kfree_skb(skb); | 2953 | kfree_skb(skb); |
2966 | return 0; | 2954 | return 0; |
2967 | } | 2955 | } |
@@ -3022,7 +3010,7 @@ static void l2cap_busy_work(struct work_struct *work) | |||
3022 | 3010 | ||
3023 | if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { | 3011 | if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { |
3024 | err = -EBUSY; | 3012 | err = -EBUSY; |
3025 | l2cap_send_disconn_req(l2cap_pi(sk)->conn, chan, EBUSY); | 3013 | l2cap_send_disconn_req(chan->conn, chan, EBUSY); |
3026 | break; | 3014 | break; |
3027 | } | 3015 | } |
3028 | 3016 | ||
@@ -3092,7 +3080,6 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c | |||
3092 | 3080 | ||
3093 | static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | 3081 | static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) |
3094 | { | 3082 | { |
3095 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | ||
3096 | struct sk_buff *_skb; | 3083 | struct sk_buff *_skb; |
3097 | int err = -EINVAL; | 3084 | int err = -EINVAL; |
3098 | 3085 | ||
@@ -3123,7 +3110,7 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf | |||
3123 | chan->sdu_len = get_unaligned_le16(skb->data); | 3110 | chan->sdu_len = get_unaligned_le16(skb->data); |
3124 | skb_pull(skb, 2); | 3111 | skb_pull(skb, 2); |
3125 | 3112 | ||
3126 | if (chan->sdu_len > pi->imtu) { | 3113 | if (chan->sdu_len > chan->imtu) { |
3127 | err = -EMSGSIZE; | 3114 | err = -EMSGSIZE; |
3128 | break; | 3115 | break; |
3129 | } | 3116 | } |
@@ -3164,7 +3151,7 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf | |||
3164 | chan->conn_state &= ~L2CAP_CONN_SAR_SDU; | 3151 | chan->conn_state &= ~L2CAP_CONN_SAR_SDU; |
3165 | chan->partial_sdu_len += skb->len; | 3152 | chan->partial_sdu_len += skb->len; |
3166 | 3153 | ||
3167 | if (chan->partial_sdu_len > pi->imtu) | 3154 | if (chan->partial_sdu_len > chan->imtu) |
3168 | goto drop; | 3155 | goto drop; |
3169 | 3156 | ||
3170 | if (chan->partial_sdu_len == chan->sdu_len) { | 3157 | if (chan->partial_sdu_len == chan->sdu_len) { |
@@ -3241,12 +3228,11 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) | |||
3241 | 3228 | ||
3242 | static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) | 3229 | static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) |
3243 | { | 3230 | { |
3244 | struct l2cap_pinfo *pi = l2cap_pi(chan->sk); | ||
3245 | u8 tx_seq = __get_txseq(rx_control); | 3231 | u8 tx_seq = __get_txseq(rx_control); |
3246 | u8 req_seq = __get_reqseq(rx_control); | 3232 | u8 req_seq = __get_reqseq(rx_control); |
3247 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; | 3233 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; |
3248 | int tx_seq_offset, expected_tx_seq_offset; | 3234 | int tx_seq_offset, expected_tx_seq_offset; |
3249 | int num_to_ack = (pi->tx_win/6) + 1; | 3235 | int num_to_ack = (chan->tx_win/6) + 1; |
3250 | int err = 0; | 3236 | int err = 0; |
3251 | 3237 | ||
3252 | BT_DBG("chan %p len %d tx_seq %d rx_control 0x%4.4x", chan, skb->len, | 3238 | BT_DBG("chan %p len %d tx_seq %d rx_control 0x%4.4x", chan, skb->len, |
@@ -3271,8 +3257,8 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3271 | tx_seq_offset += 64; | 3257 | tx_seq_offset += 64; |
3272 | 3258 | ||
3273 | /* invalid tx_seq */ | 3259 | /* invalid tx_seq */ |
3274 | if (tx_seq_offset >= pi->tx_win) { | 3260 | if (tx_seq_offset >= chan->tx_win) { |
3275 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); | 3261 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3276 | goto drop; | 3262 | goto drop; |
3277 | } | 3263 | } |
3278 | 3264 | ||
@@ -3539,7 +3525,6 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont | |||
3539 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | 3525 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) |
3540 | { | 3526 | { |
3541 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 3527 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
3542 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
3543 | u16 control; | 3528 | u16 control; |
3544 | u8 req_seq; | 3529 | u8 req_seq; |
3545 | int len, next_tx_seq_offset, req_seq_offset; | 3530 | int len, next_tx_seq_offset, req_seq_offset; |
@@ -3553,17 +3538,17 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | |||
3553 | * Receiver will miss it and start proper recovery | 3538 | * Receiver will miss it and start proper recovery |
3554 | * procedures and ask retransmission. | 3539 | * procedures and ask retransmission. |
3555 | */ | 3540 | */ |
3556 | if (l2cap_check_fcs(pi, skb)) | 3541 | if (l2cap_check_fcs(chan, skb)) |
3557 | goto drop; | 3542 | goto drop; |
3558 | 3543 | ||
3559 | if (__is_sar_start(control) && __is_iframe(control)) | 3544 | if (__is_sar_start(control) && __is_iframe(control)) |
3560 | len -= 2; | 3545 | len -= 2; |
3561 | 3546 | ||
3562 | if (pi->fcs == L2CAP_FCS_CRC16) | 3547 | if (chan->fcs == L2CAP_FCS_CRC16) |
3563 | len -= 2; | 3548 | len -= 2; |
3564 | 3549 | ||
3565 | if (len > pi->mps) { | 3550 | if (len > chan->mps) { |
3566 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); | 3551 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3567 | goto drop; | 3552 | goto drop; |
3568 | } | 3553 | } |
3569 | 3554 | ||
@@ -3579,13 +3564,13 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | |||
3579 | 3564 | ||
3580 | /* check for invalid req-seq */ | 3565 | /* check for invalid req-seq */ |
3581 | if (req_seq_offset > next_tx_seq_offset) { | 3566 | if (req_seq_offset > next_tx_seq_offset) { |
3582 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); | 3567 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3583 | goto drop; | 3568 | goto drop; |
3584 | } | 3569 | } |
3585 | 3570 | ||
3586 | if (__is_iframe(control)) { | 3571 | if (__is_iframe(control)) { |
3587 | if (len < 0) { | 3572 | if (len < 0) { |
3588 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); | 3573 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3589 | goto drop; | 3574 | goto drop; |
3590 | } | 3575 | } |
3591 | 3576 | ||
@@ -3593,7 +3578,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | |||
3593 | } else { | 3578 | } else { |
3594 | if (len != 0) { | 3579 | if (len != 0) { |
3595 | BT_ERR("%d", len); | 3580 | BT_ERR("%d", len); |
3596 | l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); | 3581 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3597 | goto drop; | 3582 | goto drop; |
3598 | } | 3583 | } |
3599 | 3584 | ||
@@ -3630,14 +3615,14 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3630 | if (sk->sk_state != BT_CONNECTED) | 3615 | if (sk->sk_state != BT_CONNECTED) |
3631 | goto drop; | 3616 | goto drop; |
3632 | 3617 | ||
3633 | switch (pi->mode) { | 3618 | switch (chan->mode) { |
3634 | case L2CAP_MODE_BASIC: | 3619 | case L2CAP_MODE_BASIC: |
3635 | /* If socket recv buffers overflows we drop data here | 3620 | /* If socket recv buffers overflows we drop data here |
3636 | * which is *bad* because L2CAP has to be reliable. | 3621 | * which is *bad* because L2CAP has to be reliable. |
3637 | * But we don't have any other choice. L2CAP doesn't | 3622 | * But we don't have any other choice. L2CAP doesn't |
3638 | * provide flow control mechanism. */ | 3623 | * provide flow control mechanism. */ |
3639 | 3624 | ||
3640 | if (pi->imtu < skb->len) | 3625 | if (chan->imtu < skb->len) |
3641 | goto drop; | 3626 | goto drop; |
3642 | 3627 | ||
3643 | if (!sock_queue_rcv_skb(sk, skb)) | 3628 | if (!sock_queue_rcv_skb(sk, skb)) |
@@ -3659,16 +3644,16 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3659 | skb_pull(skb, 2); | 3644 | skb_pull(skb, 2); |
3660 | len = skb->len; | 3645 | len = skb->len; |
3661 | 3646 | ||
3662 | if (l2cap_check_fcs(pi, skb)) | 3647 | if (l2cap_check_fcs(chan, skb)) |
3663 | goto drop; | 3648 | goto drop; |
3664 | 3649 | ||
3665 | if (__is_sar_start(control)) | 3650 | if (__is_sar_start(control)) |
3666 | len -= 2; | 3651 | len -= 2; |
3667 | 3652 | ||
3668 | if (pi->fcs == L2CAP_FCS_CRC16) | 3653 | if (chan->fcs == L2CAP_FCS_CRC16) |
3669 | len -= 2; | 3654 | len -= 2; |
3670 | 3655 | ||
3671 | if (len > pi->mps || len < 0 || __is_sframe(control)) | 3656 | if (len > chan->mps || len < 0 || __is_sframe(control)) |
3672 | goto drop; | 3657 | goto drop; |
3673 | 3658 | ||
3674 | tx_seq = __get_txseq(control); | 3659 | tx_seq = __get_txseq(control); |
@@ -3683,7 +3668,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3683 | goto done; | 3668 | goto done; |
3684 | 3669 | ||
3685 | default: | 3670 | default: |
3686 | BT_DBG("chan %p: bad mode 0x%2.2x", chan, pi->mode); | 3671 | BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode); |
3687 | break; | 3672 | break; |
3688 | } | 3673 | } |
3689 | 3674 | ||
@@ -3712,7 +3697,7 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str | |||
3712 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) | 3697 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) |
3713 | goto drop; | 3698 | goto drop; |
3714 | 3699 | ||
3715 | if (l2cap_pi(sk)->imtu < skb->len) | 3700 | if (l2cap_pi(sk)->chan->imtu < skb->len) |
3716 | goto drop; | 3701 | goto drop; |
3717 | 3702 | ||
3718 | if (!sock_queue_rcv_skb(sk, skb)) | 3703 | if (!sock_queue_rcv_skb(sk, skb)) |
@@ -3742,7 +3727,7 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct | |||
3742 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) | 3727 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) |
3743 | goto drop; | 3728 | goto drop; |
3744 | 3729 | ||
3745 | if (l2cap_pi(sk)->imtu < skb->len) | 3730 | if (l2cap_pi(sk)->chan->imtu < skb->len) |
3746 | goto drop; | 3731 | goto drop; |
3747 | 3732 | ||
3748 | if (!sock_queue_rcv_skb(sk, skb)) | 3733 | if (!sock_queue_rcv_skb(sk, skb)) |
@@ -3812,17 +3797,19 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
3812 | /* Find listening sockets and check their link_mode */ | 3797 | /* Find listening sockets and check their link_mode */ |
3813 | read_lock(&l2cap_sk_list.lock); | 3798 | read_lock(&l2cap_sk_list.lock); |
3814 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 3799 | sk_for_each(sk, node, &l2cap_sk_list.head) { |
3800 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
3801 | |||
3815 | if (sk->sk_state != BT_LISTEN) | 3802 | if (sk->sk_state != BT_LISTEN) |
3816 | continue; | 3803 | continue; |
3817 | 3804 | ||
3818 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { | 3805 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { |
3819 | lm1 |= HCI_LM_ACCEPT; | 3806 | lm1 |= HCI_LM_ACCEPT; |
3820 | if (l2cap_pi(sk)->role_switch) | 3807 | if (chan->role_switch) |
3821 | lm1 |= HCI_LM_MASTER; | 3808 | lm1 |= HCI_LM_MASTER; |
3822 | exact++; | 3809 | exact++; |
3823 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { | 3810 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { |
3824 | lm2 |= HCI_LM_ACCEPT; | 3811 | lm2 |= HCI_LM_ACCEPT; |
3825 | if (l2cap_pi(sk)->role_switch) | 3812 | if (chan->role_switch) |
3826 | lm2 |= HCI_LM_MASTER; | 3813 | lm2 |= HCI_LM_MASTER; |
3827 | } | 3814 | } |
3828 | } | 3815 | } |
@@ -3874,19 +3861,21 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) | |||
3874 | return 0; | 3861 | return 0; |
3875 | } | 3862 | } |
3876 | 3863 | ||
3877 | static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt) | 3864 | static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) |
3878 | { | 3865 | { |
3866 | struct sock *sk = chan->sk; | ||
3867 | |||
3879 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM) | 3868 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM) |
3880 | return; | 3869 | return; |
3881 | 3870 | ||
3882 | if (encrypt == 0x00) { | 3871 | if (encrypt == 0x00) { |
3883 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) { | 3872 | if (chan->sec_level == BT_SECURITY_MEDIUM) { |
3884 | l2cap_sock_clear_timer(sk); | 3873 | l2cap_sock_clear_timer(sk); |
3885 | l2cap_sock_set_timer(sk, HZ * 5); | 3874 | l2cap_sock_set_timer(sk, HZ * 5); |
3886 | } else if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) | 3875 | } else if (chan->sec_level == BT_SECURITY_HIGH) |
3887 | __l2cap_sock_close(sk, ECONNREFUSED); | 3876 | __l2cap_sock_close(sk, ECONNREFUSED); |
3888 | } else { | 3877 | } else { |
3889 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_MEDIUM) | 3878 | if (chan->sec_level == BT_SECURITY_MEDIUM) |
3890 | l2cap_sock_clear_timer(sk); | 3879 | l2cap_sock_clear_timer(sk); |
3891 | } | 3880 | } |
3892 | } | 3881 | } |
@@ -3908,14 +3897,14 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
3908 | 3897 | ||
3909 | bh_lock_sock(sk); | 3898 | bh_lock_sock(sk); |
3910 | 3899 | ||
3911 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) { | 3900 | if (chan->conf_state & L2CAP_CONF_CONNECT_PEND) { |
3912 | bh_unlock_sock(sk); | 3901 | bh_unlock_sock(sk); |
3913 | continue; | 3902 | continue; |
3914 | } | 3903 | } |
3915 | 3904 | ||
3916 | if (!status && (sk->sk_state == BT_CONNECTED || | 3905 | if (!status && (sk->sk_state == BT_CONNECTED || |
3917 | sk->sk_state == BT_CONFIG)) { | 3906 | sk->sk_state == BT_CONFIG)) { |
3918 | l2cap_check_encryption(sk, encrypt); | 3907 | l2cap_check_encryption(chan, encrypt); |
3919 | bh_unlock_sock(sk); | 3908 | bh_unlock_sock(sk); |
3920 | continue; | 3909 | continue; |
3921 | } | 3910 | } |
@@ -3923,11 +3912,11 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
3923 | if (sk->sk_state == BT_CONNECT) { | 3912 | if (sk->sk_state == BT_CONNECT) { |
3924 | if (!status) { | 3913 | if (!status) { |
3925 | struct l2cap_conn_req req; | 3914 | struct l2cap_conn_req req; |
3926 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 3915 | req.scid = cpu_to_le16(chan->scid); |
3927 | req.psm = l2cap_pi(sk)->psm; | 3916 | req.psm = chan->psm; |
3928 | 3917 | ||
3929 | chan->ident = l2cap_get_ident(conn); | 3918 | chan->ident = l2cap_get_ident(conn); |
3930 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; | 3919 | chan->conf_state |= L2CAP_CONF_CONNECT_PEND; |
3931 | 3920 | ||
3932 | l2cap_send_cmd(conn, chan->ident, | 3921 | l2cap_send_cmd(conn, chan->ident, |
3933 | L2CAP_CONN_REQ, sizeof(req), &req); | 3922 | L2CAP_CONN_REQ, sizeof(req), &req); |
@@ -3948,8 +3937,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
3948 | result = L2CAP_CR_SEC_BLOCK; | 3937 | result = L2CAP_CR_SEC_BLOCK; |
3949 | } | 3938 | } |
3950 | 3939 | ||
3951 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 3940 | rsp.scid = cpu_to_le16(chan->dcid); |
3952 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 3941 | rsp.dcid = cpu_to_le16(chan->scid); |
3953 | rsp.result = cpu_to_le16(result); | 3942 | rsp.result = cpu_to_le16(result); |
3954 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | 3943 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); |
3955 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | 3944 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
@@ -4021,10 +4010,10 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
4021 | if (chan && chan->sk) { | 4010 | if (chan && chan->sk) { |
4022 | struct sock *sk = chan->sk; | 4011 | struct sock *sk = chan->sk; |
4023 | 4012 | ||
4024 | if (l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) { | 4013 | if (chan->imtu < len - L2CAP_HDR_SIZE) { |
4025 | BT_ERR("Frame exceeding recv MTU (len %d, " | 4014 | BT_ERR("Frame exceeding recv MTU (len %d, " |
4026 | "MTU %d)", len, | 4015 | "MTU %d)", len, |
4027 | l2cap_pi(sk)->imtu); | 4016 | chan->imtu); |
4028 | bh_unlock_sock(sk); | 4017 | bh_unlock_sock(sk); |
4029 | l2cap_conn_unreliable(conn, ECOMM); | 4018 | l2cap_conn_unreliable(conn, ECOMM); |
4030 | goto drop; | 4019 | goto drop; |
@@ -4084,14 +4073,15 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p) | |||
4084 | 4073 | ||
4085 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 4074 | sk_for_each(sk, node, &l2cap_sk_list.head) { |
4086 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 4075 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
4076 | struct l2cap_chan *chan = pi->chan; | ||
4087 | 4077 | ||
4088 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", | 4078 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", |
4089 | batostr(&bt_sk(sk)->src), | 4079 | batostr(&bt_sk(sk)->src), |
4090 | batostr(&bt_sk(sk)->dst), | 4080 | batostr(&bt_sk(sk)->dst), |
4091 | sk->sk_state, __le16_to_cpu(pi->psm), | 4081 | sk->sk_state, __le16_to_cpu(chan->psm), |
4092 | pi->scid, pi->dcid, | 4082 | chan->scid, chan->dcid, |
4093 | pi->imtu, pi->omtu, pi->sec_level, | 4083 | chan->imtu, chan->omtu, chan->sec_level, |
4094 | pi->mode); | 4084 | chan->mode); |
4095 | } | 4085 | } |
4096 | 4086 | ||
4097 | read_unlock_bh(&l2cap_sk_list.lock); | 4087 | read_unlock_bh(&l2cap_sk_list.lock); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 47394a178bd5..7c4a9ae9b3ce 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <net/bluetooth/hci_core.h> | 30 | #include <net/bluetooth/hci_core.h> |
31 | #include <net/bluetooth/l2cap.h> | 31 | #include <net/bluetooth/l2cap.h> |
32 | 32 | ||
33 | static const struct proto_ops l2cap_sock_ops; | ||
34 | |||
33 | /* ---- L2CAP timers ---- */ | 35 | /* ---- L2CAP timers ---- */ |
34 | static void l2cap_sock_timeout(unsigned long arg) | 36 | static void l2cap_sock_timeout(unsigned long arg) |
35 | { | 37 | { |
@@ -51,7 +53,7 @@ static void l2cap_sock_timeout(unsigned long arg) | |||
51 | if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG) | 53 | if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG) |
52 | reason = ECONNREFUSED; | 54 | reason = ECONNREFUSED; |
53 | else if (sk->sk_state == BT_CONNECT && | 55 | else if (sk->sk_state == BT_CONNECT && |
54 | l2cap_pi(sk)->sec_level != BT_SECURITY_SDP) | 56 | l2cap_pi(sk)->chan->sec_level != BT_SECURITY_SDP) |
55 | reason = ECONNREFUSED; | 57 | reason = ECONNREFUSED; |
56 | else | 58 | else |
57 | reason = ETIMEDOUT; | 59 | reason = ETIMEDOUT; |
@@ -80,9 +82,13 @@ static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) | |||
80 | { | 82 | { |
81 | struct sock *sk; | 83 | struct sock *sk; |
82 | struct hlist_node *node; | 84 | struct hlist_node *node; |
83 | sk_for_each(sk, node, &l2cap_sk_list.head) | 85 | sk_for_each(sk, node, &l2cap_sk_list.head) { |
84 | if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src)) | 86 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
87 | |||
88 | if (chan->sport == psm && !bacmp(&bt_sk(sk)->src, src)) | ||
85 | goto found; | 89 | goto found; |
90 | } | ||
91 | |||
86 | sk = NULL; | 92 | sk = NULL; |
87 | found: | 93 | found: |
88 | return sk; | 94 | return sk; |
@@ -91,6 +97,7 @@ found: | |||
91 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | 97 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) |
92 | { | 98 | { |
93 | struct sock *sk = sock->sk; | 99 | struct sock *sk = sock->sk; |
100 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
94 | struct sockaddr_l2 la; | 101 | struct sockaddr_l2 la; |
95 | int len, err = 0; | 102 | int len, err = 0; |
96 | 103 | ||
@@ -136,17 +143,17 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
136 | } else { | 143 | } else { |
137 | /* Save source address */ | 144 | /* Save source address */ |
138 | bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); | 145 | bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); |
139 | l2cap_pi(sk)->psm = la.l2_psm; | 146 | chan->psm = la.l2_psm; |
140 | l2cap_pi(sk)->sport = la.l2_psm; | 147 | chan->sport = la.l2_psm; |
141 | sk->sk_state = BT_BOUND; | 148 | sk->sk_state = BT_BOUND; |
142 | 149 | ||
143 | if (__le16_to_cpu(la.l2_psm) == 0x0001 || | 150 | if (__le16_to_cpu(la.l2_psm) == 0x0001 || |
144 | __le16_to_cpu(la.l2_psm) == 0x0003) | 151 | __le16_to_cpu(la.l2_psm) == 0x0003) |
145 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | 152 | chan->sec_level = BT_SECURITY_SDP; |
146 | } | 153 | } |
147 | 154 | ||
148 | if (la.l2_cid) | 155 | if (la.l2_cid) |
149 | l2cap_pi(sk)->scid = la.l2_cid; | 156 | chan->scid = la.l2_cid; |
150 | 157 | ||
151 | write_unlock_bh(&l2cap_sk_list.lock); | 158 | write_unlock_bh(&l2cap_sk_list.lock); |
152 | 159 | ||
@@ -158,6 +165,7 @@ done: | |||
158 | static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) | 165 | static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) |
159 | { | 166 | { |
160 | struct sock *sk = sock->sk; | 167 | struct sock *sk = sock->sk; |
168 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
161 | struct sockaddr_l2 la; | 169 | struct sockaddr_l2 la; |
162 | int len, err = 0; | 170 | int len, err = 0; |
163 | 171 | ||
@@ -182,7 +190,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
182 | goto done; | 190 | goto done; |
183 | } | 191 | } |
184 | 192 | ||
185 | switch (l2cap_pi(sk)->mode) { | 193 | switch (chan->mode) { |
186 | case L2CAP_MODE_BASIC: | 194 | case L2CAP_MODE_BASIC: |
187 | break; | 195 | break; |
188 | case L2CAP_MODE_ERTM: | 196 | case L2CAP_MODE_ERTM: |
@@ -226,10 +234,10 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
226 | 234 | ||
227 | /* Set destination address and psm */ | 235 | /* Set destination address and psm */ |
228 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); | 236 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); |
229 | l2cap_pi(sk)->psm = la.l2_psm; | 237 | chan->psm = la.l2_psm; |
230 | l2cap_pi(sk)->dcid = la.l2_cid; | 238 | chan->dcid = la.l2_cid; |
231 | 239 | ||
232 | err = l2cap_do_connect(sk); | 240 | err = l2cap_chan_connect(l2cap_pi(sk)->chan); |
233 | if (err) | 241 | if (err) |
234 | goto done; | 242 | goto done; |
235 | 243 | ||
@@ -244,6 +252,7 @@ done: | |||
244 | static int l2cap_sock_listen(struct socket *sock, int backlog) | 252 | static int l2cap_sock_listen(struct socket *sock, int backlog) |
245 | { | 253 | { |
246 | struct sock *sk = sock->sk; | 254 | struct sock *sk = sock->sk; |
255 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
247 | int err = 0; | 256 | int err = 0; |
248 | 257 | ||
249 | BT_DBG("sk %p backlog %d", sk, backlog); | 258 | BT_DBG("sk %p backlog %d", sk, backlog); |
@@ -256,7 +265,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) | |||
256 | goto done; | 265 | goto done; |
257 | } | 266 | } |
258 | 267 | ||
259 | switch (l2cap_pi(sk)->mode) { | 268 | switch (chan->mode) { |
260 | case L2CAP_MODE_BASIC: | 269 | case L2CAP_MODE_BASIC: |
261 | break; | 270 | break; |
262 | case L2CAP_MODE_ERTM: | 271 | case L2CAP_MODE_ERTM: |
@@ -269,7 +278,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) | |||
269 | goto done; | 278 | goto done; |
270 | } | 279 | } |
271 | 280 | ||
272 | if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->scid) { | 281 | if (!chan->psm && !chan->scid) { |
273 | bdaddr_t *src = &bt_sk(sk)->src; | 282 | bdaddr_t *src = &bt_sk(sk)->src; |
274 | u16 psm; | 283 | u16 psm; |
275 | 284 | ||
@@ -279,8 +288,8 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) | |||
279 | 288 | ||
280 | for (psm = 0x1001; psm < 0x1100; psm += 2) | 289 | for (psm = 0x1001; psm < 0x1100; psm += 2) |
281 | if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) { | 290 | if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) { |
282 | l2cap_pi(sk)->psm = cpu_to_le16(psm); | 291 | chan->psm = cpu_to_le16(psm); |
283 | l2cap_pi(sk)->sport = cpu_to_le16(psm); | 292 | chan->sport = cpu_to_le16(psm); |
284 | err = 0; | 293 | err = 0; |
285 | break; | 294 | break; |
286 | } | 295 | } |
@@ -360,6 +369,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l | |||
360 | { | 369 | { |
361 | struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; | 370 | struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; |
362 | struct sock *sk = sock->sk; | 371 | struct sock *sk = sock->sk; |
372 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
363 | 373 | ||
364 | BT_DBG("sock %p, sk %p", sock, sk); | 374 | BT_DBG("sock %p, sk %p", sock, sk); |
365 | 375 | ||
@@ -367,13 +377,13 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l | |||
367 | *len = sizeof(struct sockaddr_l2); | 377 | *len = sizeof(struct sockaddr_l2); |
368 | 378 | ||
369 | if (peer) { | 379 | if (peer) { |
370 | la->l2_psm = l2cap_pi(sk)->psm; | 380 | la->l2_psm = chan->psm; |
371 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); | 381 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); |
372 | la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid); | 382 | la->l2_cid = cpu_to_le16(chan->dcid); |
373 | } else { | 383 | } else { |
374 | la->l2_psm = l2cap_pi(sk)->sport; | 384 | la->l2_psm = chan->sport; |
375 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); | 385 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); |
376 | la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid); | 386 | la->l2_cid = cpu_to_le16(chan->scid); |
377 | } | 387 | } |
378 | 388 | ||
379 | return 0; | 389 | return 0; |
@@ -382,6 +392,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l | |||
382 | static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) | 392 | static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) |
383 | { | 393 | { |
384 | struct sock *sk = sock->sk; | 394 | struct sock *sk = sock->sk; |
395 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
385 | struct l2cap_options opts; | 396 | struct l2cap_options opts; |
386 | struct l2cap_conninfo cinfo; | 397 | struct l2cap_conninfo cinfo; |
387 | int len, err = 0; | 398 | int len, err = 0; |
@@ -397,13 +408,13 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
397 | switch (optname) { | 408 | switch (optname) { |
398 | case L2CAP_OPTIONS: | 409 | case L2CAP_OPTIONS: |
399 | memset(&opts, 0, sizeof(opts)); | 410 | memset(&opts, 0, sizeof(opts)); |
400 | opts.imtu = l2cap_pi(sk)->imtu; | 411 | opts.imtu = chan->imtu; |
401 | opts.omtu = l2cap_pi(sk)->omtu; | 412 | opts.omtu = chan->omtu; |
402 | opts.flush_to = l2cap_pi(sk)->flush_to; | 413 | opts.flush_to = chan->flush_to; |
403 | opts.mode = l2cap_pi(sk)->mode; | 414 | opts.mode = chan->mode; |
404 | opts.fcs = l2cap_pi(sk)->fcs; | 415 | opts.fcs = chan->fcs; |
405 | opts.max_tx = l2cap_pi(sk)->max_tx; | 416 | opts.max_tx = chan->max_tx; |
406 | opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; | 417 | opts.txwin_size = (__u16)chan->tx_win; |
407 | 418 | ||
408 | len = min_t(unsigned int, len, sizeof(opts)); | 419 | len = min_t(unsigned int, len, sizeof(opts)); |
409 | if (copy_to_user(optval, (char *) &opts, len)) | 420 | if (copy_to_user(optval, (char *) &opts, len)) |
@@ -412,7 +423,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
412 | break; | 423 | break; |
413 | 424 | ||
414 | case L2CAP_LM: | 425 | case L2CAP_LM: |
415 | switch (l2cap_pi(sk)->sec_level) { | 426 | switch (chan->sec_level) { |
416 | case BT_SECURITY_LOW: | 427 | case BT_SECURITY_LOW: |
417 | opt = L2CAP_LM_AUTH; | 428 | opt = L2CAP_LM_AUTH; |
418 | break; | 429 | break; |
@@ -428,10 +439,10 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
428 | break; | 439 | break; |
429 | } | 440 | } |
430 | 441 | ||
431 | if (l2cap_pi(sk)->role_switch) | 442 | if (chan->role_switch) |
432 | opt |= L2CAP_LM_MASTER; | 443 | opt |= L2CAP_LM_MASTER; |
433 | 444 | ||
434 | if (l2cap_pi(sk)->force_reliable) | 445 | if (chan->force_reliable) |
435 | opt |= L2CAP_LM_RELIABLE; | 446 | opt |= L2CAP_LM_RELIABLE; |
436 | 447 | ||
437 | if (put_user(opt, (u32 __user *) optval)) | 448 | if (put_user(opt, (u32 __user *) optval)) |
@@ -446,8 +457,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
446 | break; | 457 | break; |
447 | } | 458 | } |
448 | 459 | ||
449 | cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle; | 460 | cinfo.hci_handle = chan->conn->hcon->handle; |
450 | memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3); | 461 | memcpy(cinfo.dev_class, chan->conn->hcon->dev_class, 3); |
451 | 462 | ||
452 | len = min_t(unsigned int, len, sizeof(cinfo)); | 463 | len = min_t(unsigned int, len, sizeof(cinfo)); |
453 | if (copy_to_user(optval, (char *) &cinfo, len)) | 464 | if (copy_to_user(optval, (char *) &cinfo, len)) |
@@ -467,6 +478,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
467 | static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) | 478 | static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) |
468 | { | 479 | { |
469 | struct sock *sk = sock->sk; | 480 | struct sock *sk = sock->sk; |
481 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
470 | struct bt_security sec; | 482 | struct bt_security sec; |
471 | int len, err = 0; | 483 | int len, err = 0; |
472 | 484 | ||
@@ -491,7 +503,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
491 | break; | 503 | break; |
492 | } | 504 | } |
493 | 505 | ||
494 | sec.level = l2cap_pi(sk)->sec_level; | 506 | sec.level = chan->sec_level; |
495 | 507 | ||
496 | len = min_t(unsigned int, len, sizeof(sec)); | 508 | len = min_t(unsigned int, len, sizeof(sec)); |
497 | if (copy_to_user(optval, (char *) &sec, len)) | 509 | if (copy_to_user(optval, (char *) &sec, len)) |
@@ -511,7 +523,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
511 | break; | 523 | break; |
512 | 524 | ||
513 | case BT_FLUSHABLE: | 525 | case BT_FLUSHABLE: |
514 | if (put_user(l2cap_pi(sk)->flushable, (u32 __user *) optval)) | 526 | if (put_user(chan->flushable, (u32 __user *) optval)) |
515 | err = -EFAULT; | 527 | err = -EFAULT; |
516 | 528 | ||
517 | break; | 529 | break; |
@@ -528,6 +540,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
528 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) | 540 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) |
529 | { | 541 | { |
530 | struct sock *sk = sock->sk; | 542 | struct sock *sk = sock->sk; |
543 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
531 | struct l2cap_options opts; | 544 | struct l2cap_options opts; |
532 | int len, err = 0; | 545 | int len, err = 0; |
533 | u32 opt; | 546 | u32 opt; |
@@ -543,13 +556,13 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
543 | break; | 556 | break; |
544 | } | 557 | } |
545 | 558 | ||
546 | opts.imtu = l2cap_pi(sk)->imtu; | 559 | opts.imtu = chan->imtu; |
547 | opts.omtu = l2cap_pi(sk)->omtu; | 560 | opts.omtu = chan->omtu; |
548 | opts.flush_to = l2cap_pi(sk)->flush_to; | 561 | opts.flush_to = chan->flush_to; |
549 | opts.mode = l2cap_pi(sk)->mode; | 562 | opts.mode = chan->mode; |
550 | opts.fcs = l2cap_pi(sk)->fcs; | 563 | opts.fcs = chan->fcs; |
551 | opts.max_tx = l2cap_pi(sk)->max_tx; | 564 | opts.max_tx = chan->max_tx; |
552 | opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; | 565 | opts.txwin_size = (__u16)chan->tx_win; |
553 | 566 | ||
554 | len = min_t(unsigned int, sizeof(opts), optlen); | 567 | len = min_t(unsigned int, sizeof(opts), optlen); |
555 | if (copy_from_user((char *) &opts, optval, len)) { | 568 | if (copy_from_user((char *) &opts, optval, len)) { |
@@ -562,10 +575,10 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
562 | break; | 575 | break; |
563 | } | 576 | } |
564 | 577 | ||
565 | l2cap_pi(sk)->mode = opts.mode; | 578 | chan->mode = opts.mode; |
566 | switch (l2cap_pi(sk)->mode) { | 579 | switch (chan->mode) { |
567 | case L2CAP_MODE_BASIC: | 580 | case L2CAP_MODE_BASIC: |
568 | l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE; | 581 | chan->conf_state &= ~L2CAP_CONF_STATE2_DEVICE; |
569 | break; | 582 | break; |
570 | case L2CAP_MODE_ERTM: | 583 | case L2CAP_MODE_ERTM: |
571 | case L2CAP_MODE_STREAMING: | 584 | case L2CAP_MODE_STREAMING: |
@@ -577,11 +590,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
577 | break; | 590 | break; |
578 | } | 591 | } |
579 | 592 | ||
580 | l2cap_pi(sk)->imtu = opts.imtu; | 593 | chan->imtu = opts.imtu; |
581 | l2cap_pi(sk)->omtu = opts.omtu; | 594 | chan->omtu = opts.omtu; |
582 | l2cap_pi(sk)->fcs = opts.fcs; | 595 | chan->fcs = opts.fcs; |
583 | l2cap_pi(sk)->max_tx = opts.max_tx; | 596 | chan->max_tx = opts.max_tx; |
584 | l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size; | 597 | chan->tx_win = (__u8)opts.txwin_size; |
585 | break; | 598 | break; |
586 | 599 | ||
587 | case L2CAP_LM: | 600 | case L2CAP_LM: |
@@ -591,14 +604,14 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
591 | } | 604 | } |
592 | 605 | ||
593 | if (opt & L2CAP_LM_AUTH) | 606 | if (opt & L2CAP_LM_AUTH) |
594 | l2cap_pi(sk)->sec_level = BT_SECURITY_LOW; | 607 | chan->sec_level = BT_SECURITY_LOW; |
595 | if (opt & L2CAP_LM_ENCRYPT) | 608 | if (opt & L2CAP_LM_ENCRYPT) |
596 | l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM; | 609 | chan->sec_level = BT_SECURITY_MEDIUM; |
597 | if (opt & L2CAP_LM_SECURE) | 610 | if (opt & L2CAP_LM_SECURE) |
598 | l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH; | 611 | chan->sec_level = BT_SECURITY_HIGH; |
599 | 612 | ||
600 | l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER); | 613 | chan->role_switch = (opt & L2CAP_LM_MASTER); |
601 | l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE); | 614 | chan->force_reliable = (opt & L2CAP_LM_RELIABLE); |
602 | break; | 615 | break; |
603 | 616 | ||
604 | default: | 617 | default: |
@@ -613,6 +626,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
613 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) | 626 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) |
614 | { | 627 | { |
615 | struct sock *sk = sock->sk; | 628 | struct sock *sk = sock->sk; |
629 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
616 | struct bt_security sec; | 630 | struct bt_security sec; |
617 | int len, err = 0; | 631 | int len, err = 0; |
618 | u32 opt; | 632 | u32 opt; |
@@ -649,7 +663,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
649 | break; | 663 | break; |
650 | } | 664 | } |
651 | 665 | ||
652 | l2cap_pi(sk)->sec_level = sec.level; | 666 | chan->sec_level = sec.level; |
653 | break; | 667 | break; |
654 | 668 | ||
655 | case BT_DEFER_SETUP: | 669 | case BT_DEFER_SETUP: |
@@ -678,7 +692,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
678 | } | 692 | } |
679 | 693 | ||
680 | if (opt == BT_FLUSHABLE_OFF) { | 694 | if (opt == BT_FLUSHABLE_OFF) { |
681 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 695 | struct l2cap_conn *conn = chan->conn; |
682 | /* proceed further only when we have l2cap_conn and | 696 | /* proceed further only when we have l2cap_conn and |
683 | No Flush support in the LM */ | 697 | No Flush support in the LM */ |
684 | if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) { | 698 | if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) { |
@@ -687,7 +701,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
687 | } | 701 | } |
688 | } | 702 | } |
689 | 703 | ||
690 | l2cap_pi(sk)->flushable = opt; | 704 | chan->flushable = opt; |
691 | break; | 705 | break; |
692 | 706 | ||
693 | default: | 707 | default: |
@@ -702,7 +716,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
702 | static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) | 716 | static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) |
703 | { | 717 | { |
704 | struct sock *sk = sock->sk; | 718 | struct sock *sk = sock->sk; |
705 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 719 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
706 | struct sk_buff *skb; | 720 | struct sk_buff *skb; |
707 | u16 control; | 721 | u16 control; |
708 | int err; | 722 | int err; |
@@ -725,76 +739,77 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
725 | 739 | ||
726 | /* Connectionless channel */ | 740 | /* Connectionless channel */ |
727 | if (sk->sk_type == SOCK_DGRAM) { | 741 | if (sk->sk_type == SOCK_DGRAM) { |
728 | skb = l2cap_create_connless_pdu(sk, msg, len); | 742 | skb = l2cap_create_connless_pdu(chan, msg, len); |
729 | if (IS_ERR(skb)) { | 743 | if (IS_ERR(skb)) { |
730 | err = PTR_ERR(skb); | 744 | err = PTR_ERR(skb); |
731 | } else { | 745 | } else { |
732 | l2cap_do_send(sk, skb); | 746 | l2cap_do_send(chan, skb); |
733 | err = len; | 747 | err = len; |
734 | } | 748 | } |
735 | goto done; | 749 | goto done; |
736 | } | 750 | } |
737 | 751 | ||
738 | switch (pi->mode) { | 752 | switch (chan->mode) { |
739 | case L2CAP_MODE_BASIC: | 753 | case L2CAP_MODE_BASIC: |
740 | /* Check outgoing MTU */ | 754 | /* Check outgoing MTU */ |
741 | if (len > pi->omtu) { | 755 | if (len > chan->omtu) { |
742 | err = -EMSGSIZE; | 756 | err = -EMSGSIZE; |
743 | goto done; | 757 | goto done; |
744 | } | 758 | } |
745 | 759 | ||
746 | /* Create a basic PDU */ | 760 | /* Create a basic PDU */ |
747 | skb = l2cap_create_basic_pdu(sk, msg, len); | 761 | skb = l2cap_create_basic_pdu(chan, msg, len); |
748 | if (IS_ERR(skb)) { | 762 | if (IS_ERR(skb)) { |
749 | err = PTR_ERR(skb); | 763 | err = PTR_ERR(skb); |
750 | goto done; | 764 | goto done; |
751 | } | 765 | } |
752 | 766 | ||
753 | l2cap_do_send(sk, skb); | 767 | l2cap_do_send(chan, skb); |
754 | err = len; | 768 | err = len; |
755 | break; | 769 | break; |
756 | 770 | ||
757 | case L2CAP_MODE_ERTM: | 771 | case L2CAP_MODE_ERTM: |
758 | case L2CAP_MODE_STREAMING: | 772 | case L2CAP_MODE_STREAMING: |
759 | /* Entire SDU fits into one PDU */ | 773 | /* Entire SDU fits into one PDU */ |
760 | if (len <= pi->chan->remote_mps) { | 774 | if (len <= chan->remote_mps) { |
761 | control = L2CAP_SDU_UNSEGMENTED; | 775 | control = L2CAP_SDU_UNSEGMENTED; |
762 | skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0); | 776 | skb = l2cap_create_iframe_pdu(chan, msg, len, control, |
777 | 0); | ||
763 | if (IS_ERR(skb)) { | 778 | if (IS_ERR(skb)) { |
764 | err = PTR_ERR(skb); | 779 | err = PTR_ERR(skb); |
765 | goto done; | 780 | goto done; |
766 | } | 781 | } |
767 | __skb_queue_tail(&pi->chan->tx_q, skb); | 782 | __skb_queue_tail(&chan->tx_q, skb); |
768 | 783 | ||
769 | if (pi->chan->tx_send_head == NULL) | 784 | if (chan->tx_send_head == NULL) |
770 | pi->chan->tx_send_head = skb; | 785 | chan->tx_send_head = skb; |
771 | 786 | ||
772 | } else { | 787 | } else { |
773 | /* Segment SDU into multiples PDUs */ | 788 | /* Segment SDU into multiples PDUs */ |
774 | err = l2cap_sar_segment_sdu(pi->chan, msg, len); | 789 | err = l2cap_sar_segment_sdu(chan, msg, len); |
775 | if (err < 0) | 790 | if (err < 0) |
776 | goto done; | 791 | goto done; |
777 | } | 792 | } |
778 | 793 | ||
779 | if (pi->mode == L2CAP_MODE_STREAMING) { | 794 | if (chan->mode == L2CAP_MODE_STREAMING) { |
780 | l2cap_streaming_send(pi->chan); | 795 | l2cap_streaming_send(chan); |
781 | err = len; | 796 | err = len; |
782 | break; | 797 | break; |
783 | } | 798 | } |
784 | 799 | ||
785 | if ((pi->chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && | 800 | if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
786 | (pi->chan->conn_state & L2CAP_CONN_WAIT_F)) { | 801 | (chan->conn_state & L2CAP_CONN_WAIT_F)) { |
787 | err = len; | 802 | err = len; |
788 | break; | 803 | break; |
789 | } | 804 | } |
790 | err = l2cap_ertm_send(pi->chan); | 805 | err = l2cap_ertm_send(chan); |
791 | 806 | ||
792 | if (err >= 0) | 807 | if (err >= 0) |
793 | err = len; | 808 | err = len; |
794 | break; | 809 | break; |
795 | 810 | ||
796 | default: | 811 | default: |
797 | BT_DBG("bad state %1.1x", pi->mode); | 812 | BT_DBG("bad state %1.1x", chan->mode); |
798 | err = -EBADFD; | 813 | err = -EBADFD; |
799 | } | 814 | } |
800 | 815 | ||
@@ -810,7 +825,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
810 | lock_sock(sk); | 825 | lock_sock(sk); |
811 | 826 | ||
812 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { | 827 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { |
813 | __l2cap_connect_rsp_defer(sk); | 828 | sk->sk_state = BT_CONFIG; |
829 | |||
830 | __l2cap_connect_rsp_defer(l2cap_pi(sk)->chan); | ||
814 | release_sock(sk); | 831 | release_sock(sk); |
815 | return 0; | 832 | return 0; |
816 | } | 833 | } |
@@ -834,6 +851,8 @@ void l2cap_sock_kill(struct sock *sk) | |||
834 | BT_DBG("sk %p state %d", sk, sk->sk_state); | 851 | BT_DBG("sk %p state %d", sk, sk->sk_state); |
835 | 852 | ||
836 | /* Kill poor orphan */ | 853 | /* Kill poor orphan */ |
854 | |||
855 | l2cap_chan_free(l2cap_pi(sk)->chan); | ||
837 | bt_sock_unlink(&l2cap_sk_list, sk); | 856 | bt_sock_unlink(&l2cap_sk_list, sk); |
838 | sock_set_flag(sk, SOCK_DEAD); | 857 | sock_set_flag(sk, SOCK_DEAD); |
839 | sock_put(sk); | 858 | sock_put(sk); |
@@ -865,8 +884,8 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) | |||
865 | 884 | ||
866 | void __l2cap_sock_close(struct sock *sk, int reason) | 885 | void __l2cap_sock_close(struct sock *sk, int reason) |
867 | { | 886 | { |
868 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
869 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 887 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
888 | struct l2cap_conn *conn = chan->conn; | ||
870 | 889 | ||
871 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); | 890 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); |
872 | 891 | ||
@@ -898,8 +917,8 @@ void __l2cap_sock_close(struct sock *sk, int reason) | |||
898 | else | 917 | else |
899 | result = L2CAP_CR_BAD_PSM; | 918 | result = L2CAP_CR_BAD_PSM; |
900 | 919 | ||
901 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 920 | rsp.scid = cpu_to_le16(chan->dcid); |
902 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 921 | rsp.dcid = cpu_to_le16(chan->scid); |
903 | rsp.result = cpu_to_le16(result); | 922 | rsp.result = cpu_to_le16(result); |
904 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | 923 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); |
905 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | 924 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
@@ -923,6 +942,7 @@ void __l2cap_sock_close(struct sock *sk, int reason) | |||
923 | static int l2cap_sock_shutdown(struct socket *sock, int how) | 942 | static int l2cap_sock_shutdown(struct socket *sock, int how) |
924 | { | 943 | { |
925 | struct sock *sk = sock->sk; | 944 | struct sock *sk = sock->sk; |
945 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
926 | int err = 0; | 946 | int err = 0; |
927 | 947 | ||
928 | BT_DBG("sock %p, sk %p", sock, sk); | 948 | BT_DBG("sock %p, sk %p", sock, sk); |
@@ -932,7 +952,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) | |||
932 | 952 | ||
933 | lock_sock(sk); | 953 | lock_sock(sk); |
934 | if (!sk->sk_shutdown) { | 954 | if (!sk->sk_shutdown) { |
935 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) | 955 | if (chan->mode == L2CAP_MODE_ERTM) |
936 | err = __l2cap_wait_ack(sk); | 956 | err = __l2cap_wait_ack(sk); |
937 | 957 | ||
938 | sk->sk_shutdown = SHUTDOWN_MASK; | 958 | sk->sk_shutdown = SHUTDOWN_MASK; |
@@ -979,44 +999,47 @@ static void l2cap_sock_destruct(struct sock *sk) | |||
979 | void l2cap_sock_init(struct sock *sk, struct sock *parent) | 999 | void l2cap_sock_init(struct sock *sk, struct sock *parent) |
980 | { | 1000 | { |
981 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1001 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
1002 | struct l2cap_chan *chan = pi->chan; | ||
982 | 1003 | ||
983 | BT_DBG("sk %p", sk); | 1004 | BT_DBG("sk %p", sk); |
984 | 1005 | ||
985 | if (parent) { | 1006 | if (parent) { |
1007 | struct l2cap_chan *pchan = l2cap_pi(parent)->chan; | ||
1008 | |||
986 | sk->sk_type = parent->sk_type; | 1009 | sk->sk_type = parent->sk_type; |
987 | bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup; | 1010 | bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup; |
988 | 1011 | ||
989 | pi->imtu = l2cap_pi(parent)->imtu; | 1012 | chan->imtu = pchan->imtu; |
990 | pi->omtu = l2cap_pi(parent)->omtu; | 1013 | chan->omtu = pchan->omtu; |
991 | pi->conf_state = l2cap_pi(parent)->conf_state; | 1014 | chan->conf_state = pchan->conf_state; |
992 | pi->mode = l2cap_pi(parent)->mode; | 1015 | chan->mode = pchan->mode; |
993 | pi->fcs = l2cap_pi(parent)->fcs; | 1016 | chan->fcs = pchan->fcs; |
994 | pi->max_tx = l2cap_pi(parent)->max_tx; | 1017 | chan->max_tx = pchan->max_tx; |
995 | pi->tx_win = l2cap_pi(parent)->tx_win; | 1018 | chan->tx_win = pchan->tx_win; |
996 | pi->sec_level = l2cap_pi(parent)->sec_level; | 1019 | chan->sec_level = pchan->sec_level; |
997 | pi->role_switch = l2cap_pi(parent)->role_switch; | 1020 | chan->role_switch = pchan->role_switch; |
998 | pi->force_reliable = l2cap_pi(parent)->force_reliable; | 1021 | chan->force_reliable = pchan->force_reliable; |
999 | pi->flushable = l2cap_pi(parent)->flushable; | 1022 | chan->flushable = pchan->flushable; |
1000 | } else { | 1023 | } else { |
1001 | pi->imtu = L2CAP_DEFAULT_MTU; | 1024 | chan->imtu = L2CAP_DEFAULT_MTU; |
1002 | pi->omtu = 0; | 1025 | chan->omtu = 0; |
1003 | if (!disable_ertm && sk->sk_type == SOCK_STREAM) { | 1026 | if (!disable_ertm && sk->sk_type == SOCK_STREAM) { |
1004 | pi->mode = L2CAP_MODE_ERTM; | 1027 | chan->mode = L2CAP_MODE_ERTM; |
1005 | pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; | 1028 | chan->conf_state |= L2CAP_CONF_STATE2_DEVICE; |
1006 | } else { | 1029 | } else { |
1007 | pi->mode = L2CAP_MODE_BASIC; | 1030 | chan->mode = L2CAP_MODE_BASIC; |
1008 | } | 1031 | } |
1009 | pi->max_tx = L2CAP_DEFAULT_MAX_TX; | 1032 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; |
1010 | pi->fcs = L2CAP_FCS_CRC16; | 1033 | chan->fcs = L2CAP_FCS_CRC16; |
1011 | pi->tx_win = L2CAP_DEFAULT_TX_WINDOW; | 1034 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; |
1012 | pi->sec_level = BT_SECURITY_LOW; | 1035 | chan->sec_level = BT_SECURITY_LOW; |
1013 | pi->role_switch = 0; | 1036 | chan->role_switch = 0; |
1014 | pi->force_reliable = 0; | 1037 | chan->force_reliable = 0; |
1015 | pi->flushable = BT_FLUSHABLE_OFF; | 1038 | chan->flushable = BT_FLUSHABLE_OFF; |
1016 | } | 1039 | } |
1017 | 1040 | ||
1018 | /* Default config options */ | 1041 | /* Default config options */ |
1019 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; | 1042 | chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; |
1020 | } | 1043 | } |
1021 | 1044 | ||
1022 | static struct proto l2cap_proto = { | 1045 | static struct proto l2cap_proto = { |
@@ -1054,6 +1077,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, | |||
1054 | int kern) | 1077 | int kern) |
1055 | { | 1078 | { |
1056 | struct sock *sk; | 1079 | struct sock *sk; |
1080 | struct l2cap_chan *chan; | ||
1057 | 1081 | ||
1058 | BT_DBG("sock %p", sock); | 1082 | BT_DBG("sock %p", sock); |
1059 | 1083 | ||
@@ -1072,11 +1096,19 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, | |||
1072 | if (!sk) | 1096 | if (!sk) |
1073 | return -ENOMEM; | 1097 | return -ENOMEM; |
1074 | 1098 | ||
1099 | chan = l2cap_chan_alloc(sk); | ||
1100 | if (!chan) { | ||
1101 | l2cap_sock_kill(sk); | ||
1102 | return -ENOMEM; | ||
1103 | } | ||
1104 | |||
1105 | l2cap_pi(sk)->chan = chan; | ||
1106 | |||
1075 | l2cap_sock_init(sk, NULL); | 1107 | l2cap_sock_init(sk, NULL); |
1076 | return 0; | 1108 | return 0; |
1077 | } | 1109 | } |
1078 | 1110 | ||
1079 | const struct proto_ops l2cap_sock_ops = { | 1111 | static const struct proto_ops l2cap_sock_ops = { |
1080 | .family = PF_BLUETOOTH, | 1112 | .family = PF_BLUETOOTH, |
1081 | .owner = THIS_MODULE, | 1113 | .owner = THIS_MODULE, |
1082 | .release = l2cap_sock_release, | 1114 | .release = l2cap_sock_release, |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index c304688252b8..2481d257ed98 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -945,7 +945,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
945 | for (i = 0; i < key_count; i++) { | 945 | for (i = 0; i < key_count; i++) { |
946 | struct mgmt_key_info *key = &cp->keys[i]; | 946 | struct mgmt_key_info *key = &cp->keys[i]; |
947 | 947 | ||
948 | hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type, | 948 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, |
949 | key->pin_len); | 949 | key->pin_len); |
950 | } | 950 | } |
951 | 951 | ||
@@ -1569,6 +1569,75 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, | |||
1569 | return err; | 1569 | return err; |
1570 | } | 1570 | } |
1571 | 1571 | ||
1572 | static int start_discovery(struct sock *sk, u16 index) | ||
1573 | { | ||
1574 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
1575 | struct hci_cp_inquiry cp; | ||
1576 | struct pending_cmd *cmd; | ||
1577 | struct hci_dev *hdev; | ||
1578 | int err; | ||
1579 | |||
1580 | BT_DBG("hci%u", index); | ||
1581 | |||
1582 | hdev = hci_dev_get(index); | ||
1583 | if (!hdev) | ||
1584 | return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, ENODEV); | ||
1585 | |||
1586 | hci_dev_lock_bh(hdev); | ||
1587 | |||
1588 | cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0); | ||
1589 | if (!cmd) { | ||
1590 | err = -ENOMEM; | ||
1591 | goto failed; | ||
1592 | } | ||
1593 | |||
1594 | memset(&cp, 0, sizeof(cp)); | ||
1595 | memcpy(&cp.lap, lap, 3); | ||
1596 | cp.length = 0x08; | ||
1597 | cp.num_rsp = 0x00; | ||
1598 | |||
1599 | err = hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
1600 | if (err < 0) | ||
1601 | mgmt_pending_remove(cmd); | ||
1602 | |||
1603 | failed: | ||
1604 | hci_dev_unlock_bh(hdev); | ||
1605 | hci_dev_put(hdev); | ||
1606 | |||
1607 | return err; | ||
1608 | } | ||
1609 | |||
1610 | static int stop_discovery(struct sock *sk, u16 index) | ||
1611 | { | ||
1612 | struct hci_dev *hdev; | ||
1613 | struct pending_cmd *cmd; | ||
1614 | int err; | ||
1615 | |||
1616 | BT_DBG("hci%u", index); | ||
1617 | |||
1618 | hdev = hci_dev_get(index); | ||
1619 | if (!hdev) | ||
1620 | return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, ENODEV); | ||
1621 | |||
1622 | hci_dev_lock_bh(hdev); | ||
1623 | |||
1624 | cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, index, NULL, 0); | ||
1625 | if (!cmd) { | ||
1626 | err = -ENOMEM; | ||
1627 | goto failed; | ||
1628 | } | ||
1629 | |||
1630 | err = hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); | ||
1631 | if (err < 0) | ||
1632 | mgmt_pending_remove(cmd); | ||
1633 | |||
1634 | failed: | ||
1635 | hci_dev_unlock_bh(hdev); | ||
1636 | hci_dev_put(hdev); | ||
1637 | |||
1638 | return err; | ||
1639 | } | ||
1640 | |||
1572 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | 1641 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) |
1573 | { | 1642 | { |
1574 | unsigned char *buf; | 1643 | unsigned char *buf; |
@@ -1677,7 +1746,12 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
1677 | err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr), | 1746 | err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr), |
1678 | len); | 1747 | len); |
1679 | break; | 1748 | break; |
1680 | 1749 | case MGMT_OP_START_DISCOVERY: | |
1750 | err = start_discovery(sk, index); | ||
1751 | break; | ||
1752 | case MGMT_OP_STOP_DISCOVERY: | ||
1753 | err = stop_discovery(sk, index); | ||
1754 | break; | ||
1681 | default: | 1755 | default: |
1682 | BT_DBG("Unknown op %u", opcode); | 1756 | BT_DBG("Unknown op %u", opcode); |
1683 | err = cmd_status(sk, index, opcode, 0x01); | 1757 | err = cmd_status(sk, index, opcode, 0x01); |
@@ -1784,17 +1858,17 @@ int mgmt_connectable(u16 index, u8 connectable) | |||
1784 | return ret; | 1858 | return ret; |
1785 | } | 1859 | } |
1786 | 1860 | ||
1787 | int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type) | 1861 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) |
1788 | { | 1862 | { |
1789 | struct mgmt_ev_new_key ev; | 1863 | struct mgmt_ev_new_key ev; |
1790 | 1864 | ||
1791 | memset(&ev, 0, sizeof(ev)); | 1865 | memset(&ev, 0, sizeof(ev)); |
1792 | 1866 | ||
1867 | ev.store_hint = persistent; | ||
1793 | bacpy(&ev.key.bdaddr, &key->bdaddr); | 1868 | bacpy(&ev.key.bdaddr, &key->bdaddr); |
1794 | ev.key.type = key->type; | 1869 | ev.key.type = key->type; |
1795 | memcpy(ev.key.val, key->val, 16); | 1870 | memcpy(ev.key.val, key->val, 16); |
1796 | ev.key.pin_len = key->pin_len; | 1871 | ev.key.pin_len = key->pin_len; |
1797 | ev.old_key_type = old_key_type; | ||
1798 | 1872 | ||
1799 | return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); | 1873 | return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); |
1800 | } | 1874 | } |
@@ -1868,11 +1942,12 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status) | |||
1868 | return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); | 1942 | return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); |
1869 | } | 1943 | } |
1870 | 1944 | ||
1871 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr) | 1945 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure) |
1872 | { | 1946 | { |
1873 | struct mgmt_ev_pin_code_request ev; | 1947 | struct mgmt_ev_pin_code_request ev; |
1874 | 1948 | ||
1875 | bacpy(&ev.bdaddr, bdaddr); | 1949 | bacpy(&ev.bdaddr, bdaddr); |
1950 | ev.secure = secure; | ||
1876 | 1951 | ||
1877 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev), | 1952 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev), |
1878 | NULL); | 1953 | NULL); |
@@ -1920,13 +1995,15 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
1920 | return err; | 1995 | return err; |
1921 | } | 1996 | } |
1922 | 1997 | ||
1923 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value) | 1998 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value, |
1999 | u8 confirm_hint) | ||
1924 | { | 2000 | { |
1925 | struct mgmt_ev_user_confirm_request ev; | 2001 | struct mgmt_ev_user_confirm_request ev; |
1926 | 2002 | ||
1927 | BT_DBG("hci%u", index); | 2003 | BT_DBG("hci%u", index); |
1928 | 2004 | ||
1929 | bacpy(&ev.bdaddr, bdaddr); | 2005 | bacpy(&ev.bdaddr, bdaddr); |
2006 | ev.confirm_hint = confirm_hint; | ||
1930 | put_unaligned_le32(value, &ev.value); | 2007 | put_unaligned_le32(value, &ev.value); |
1931 | 2008 | ||
1932 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev), | 2009 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev), |
@@ -2075,3 +2152,9 @@ int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) | |||
2075 | 2152 | ||
2076 | return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL); | 2153 | return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL); |
2077 | } | 2154 | } |
2155 | |||
2156 | int mgmt_discovering(u16 index, u8 discovering) | ||
2157 | { | ||
2158 | return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering, | ||
2159 | sizeof(discovering), NULL); | ||
2160 | } | ||
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index c9973932456f..121a5c13b989 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -232,6 +232,8 @@ static int rfcomm_l2sock_create(struct socket **sock) | |||
232 | static inline int rfcomm_check_security(struct rfcomm_dlc *d) | 232 | static inline int rfcomm_check_security(struct rfcomm_dlc *d) |
233 | { | 233 | { |
234 | struct sock *sk = d->session->sock->sk; | 234 | struct sock *sk = d->session->sock->sk; |
235 | struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; | ||
236 | |||
235 | __u8 auth_type; | 237 | __u8 auth_type; |
236 | 238 | ||
237 | switch (d->sec_level) { | 239 | switch (d->sec_level) { |
@@ -246,8 +248,7 @@ static inline int rfcomm_check_security(struct rfcomm_dlc *d) | |||
246 | break; | 248 | break; |
247 | } | 249 | } |
248 | 250 | ||
249 | return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level, | 251 | return hci_conn_security(conn->hcon, d->sec_level, auth_type); |
250 | auth_type); | ||
251 | } | 252 | } |
252 | 253 | ||
253 | static void rfcomm_session_timeout(unsigned long arg) | 254 | static void rfcomm_session_timeout(unsigned long arg) |
@@ -710,10 +711,10 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, | |||
710 | /* Set L2CAP options */ | 711 | /* Set L2CAP options */ |
711 | sk = sock->sk; | 712 | sk = sock->sk; |
712 | lock_sock(sk); | 713 | lock_sock(sk); |
713 | l2cap_pi(sk)->imtu = l2cap_mtu; | 714 | l2cap_pi(sk)->chan->imtu = l2cap_mtu; |
714 | l2cap_pi(sk)->sec_level = sec_level; | 715 | l2cap_pi(sk)->chan->sec_level = sec_level; |
715 | if (l2cap_ertm) | 716 | if (l2cap_ertm) |
716 | l2cap_pi(sk)->mode = L2CAP_MODE_ERTM; | 717 | l2cap_pi(sk)->chan->mode = L2CAP_MODE_ERTM; |
717 | release_sock(sk); | 718 | release_sock(sk); |
718 | 719 | ||
719 | s = rfcomm_session_add(sock, BT_BOUND); | 720 | s = rfcomm_session_add(sock, BT_BOUND); |
@@ -1241,6 +1242,7 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci) | |||
1241 | void rfcomm_dlc_accept(struct rfcomm_dlc *d) | 1242 | void rfcomm_dlc_accept(struct rfcomm_dlc *d) |
1242 | { | 1243 | { |
1243 | struct sock *sk = d->session->sock->sk; | 1244 | struct sock *sk = d->session->sock->sk; |
1245 | struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; | ||
1244 | 1246 | ||
1245 | BT_DBG("dlc %p", d); | 1247 | BT_DBG("dlc %p", d); |
1246 | 1248 | ||
@@ -1254,7 +1256,7 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d) | |||
1254 | rfcomm_dlc_unlock(d); | 1256 | rfcomm_dlc_unlock(d); |
1255 | 1257 | ||
1256 | if (d->role_switch) | 1258 | if (d->role_switch) |
1257 | hci_conn_switch_role(l2cap_pi(sk)->conn->hcon, 0x00); | 1259 | hci_conn_switch_role(conn->hcon, 0x00); |
1258 | 1260 | ||
1259 | rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig); | 1261 | rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig); |
1260 | } | 1262 | } |
@@ -1890,7 +1892,8 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s) | |||
1890 | 1892 | ||
1891 | /* We should adjust MTU on incoming sessions. | 1893 | /* We should adjust MTU on incoming sessions. |
1892 | * L2CAP MTU minus UIH header and FCS. */ | 1894 | * L2CAP MTU minus UIH header and FCS. */ |
1893 | s->mtu = min(l2cap_pi(nsock->sk)->omtu, l2cap_pi(nsock->sk)->imtu) - 5; | 1895 | s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu, |
1896 | l2cap_pi(nsock->sk)->chan->imtu) - 5; | ||
1894 | 1897 | ||
1895 | rfcomm_schedule(); | 1898 | rfcomm_schedule(); |
1896 | } else | 1899 | } else |
@@ -1909,7 +1912,7 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s) | |||
1909 | 1912 | ||
1910 | /* We can adjust MTU on outgoing sessions. | 1913 | /* We can adjust MTU on outgoing sessions. |
1911 | * L2CAP MTU minus UIH header and FCS. */ | 1914 | * L2CAP MTU minus UIH header and FCS. */ |
1912 | s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) - 5; | 1915 | s->mtu = min(l2cap_pi(sk)->chan->omtu, l2cap_pi(sk)->chan->imtu) - 5; |
1913 | 1916 | ||
1914 | rfcomm_send_sabm(s, 0); | 1917 | rfcomm_send_sabm(s, 0); |
1915 | break; | 1918 | break; |
@@ -1992,7 +1995,7 @@ static int rfcomm_add_listener(bdaddr_t *ba) | |||
1992 | /* Set L2CAP options */ | 1995 | /* Set L2CAP options */ |
1993 | sk = sock->sk; | 1996 | sk = sock->sk; |
1994 | lock_sock(sk); | 1997 | lock_sock(sk); |
1995 | l2cap_pi(sk)->imtu = l2cap_mtu; | 1998 | l2cap_pi(sk)->chan->imtu = l2cap_mtu; |
1996 | release_sock(sk); | 1999 | release_sock(sk); |
1997 | 2000 | ||
1998 | /* Start listening on the socket */ | 2001 | /* Start listening on the socket */ |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 66cc1f0c3df8..386cfaffd4b7 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -743,6 +743,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u | |||
743 | struct sock *sk = sock->sk; | 743 | struct sock *sk = sock->sk; |
744 | struct sock *l2cap_sk; | 744 | struct sock *l2cap_sk; |
745 | struct rfcomm_conninfo cinfo; | 745 | struct rfcomm_conninfo cinfo; |
746 | struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; | ||
746 | int len, err = 0; | 747 | int len, err = 0; |
747 | u32 opt; | 748 | u32 opt; |
748 | 749 | ||
@@ -787,8 +788,8 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u | |||
787 | 788 | ||
788 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; | 789 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; |
789 | 790 | ||
790 | cinfo.hci_handle = l2cap_pi(l2cap_sk)->conn->hcon->handle; | 791 | cinfo.hci_handle = conn->hcon->handle; |
791 | memcpy(cinfo.dev_class, l2cap_pi(l2cap_sk)->conn->hcon->dev_class, 3); | 792 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); |
792 | 793 | ||
793 | len = min_t(unsigned int, len, sizeof(cinfo)); | 794 | len = min_t(unsigned int, len, sizeof(cinfo)); |
794 | if (copy_to_user(optval, (char *) &cinfo, len)) | 795 | if (copy_to_user(optval, (char *) &cinfo, len)) |
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index 4bd6ef0be380..b9b595c08112 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c | |||
@@ -54,13 +54,12 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
54 | u8 *cdata, u8 *mic) | 54 | u8 *cdata, u8 *mic) |
55 | { | 55 | { |
56 | int i, j, last_len, num_blocks; | 56 | int i, j, last_len, num_blocks; |
57 | u8 *pos, *cpos, *b, *s_0, *e, *b_0, *aad; | 57 | u8 *pos, *cpos, *b, *s_0, *e, *b_0; |
58 | 58 | ||
59 | b = scratch; | 59 | b = scratch; |
60 | s_0 = scratch + AES_BLOCK_LEN; | 60 | s_0 = scratch + AES_BLOCK_LEN; |
61 | e = scratch + 2 * AES_BLOCK_LEN; | 61 | e = scratch + 2 * AES_BLOCK_LEN; |
62 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 62 | b_0 = scratch + 3 * AES_BLOCK_LEN; |
63 | aad = scratch + 4 * AES_BLOCK_LEN; | ||
64 | 63 | ||
65 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); | 64 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); |
66 | last_len = data_len % AES_BLOCK_LEN; | 65 | last_len = data_len % AES_BLOCK_LEN; |
@@ -94,13 +93,12 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
94 | u8 *cdata, size_t data_len, u8 *mic, u8 *data) | 93 | u8 *cdata, size_t data_len, u8 *mic, u8 *data) |
95 | { | 94 | { |
96 | int i, j, last_len, num_blocks; | 95 | int i, j, last_len, num_blocks; |
97 | u8 *pos, *cpos, *b, *s_0, *a, *b_0, *aad; | 96 | u8 *pos, *cpos, *b, *s_0, *a, *b_0; |
98 | 97 | ||
99 | b = scratch; | 98 | b = scratch; |
100 | s_0 = scratch + AES_BLOCK_LEN; | 99 | s_0 = scratch + AES_BLOCK_LEN; |
101 | a = scratch + 2 * AES_BLOCK_LEN; | 100 | a = scratch + 2 * AES_BLOCK_LEN; |
102 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 101 | b_0 = scratch + 3 * AES_BLOCK_LEN; |
103 | aad = scratch + 4 * AES_BLOCK_LEN; | ||
104 | 102 | ||
105 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); | 103 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); |
106 | last_len = data_len % AES_BLOCK_LEN; | 104 | last_len = data_len % AES_BLOCK_LEN; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a9ddaf63ee14..12d52cec9515 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1633,16 +1633,13 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | |||
1633 | { | 1633 | { |
1634 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1634 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1635 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1635 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1636 | int i; | 1636 | int i, ret; |
1637 | |||
1638 | /* | ||
1639 | * This _could_ be supported by providing a hook for | ||
1640 | * drivers for this function, but at this point it | ||
1641 | * doesn't seem worth bothering. | ||
1642 | */ | ||
1643 | if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) | ||
1644 | return -EOPNOTSUPP; | ||
1645 | 1637 | ||
1638 | if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) { | ||
1639 | ret = drv_set_bitrate_mask(local, sdata, mask); | ||
1640 | if (ret) | ||
1641 | return ret; | ||
1642 | } | ||
1646 | 1643 | ||
1647 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | 1644 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) |
1648 | sdata->rc_rateidx_mask[i] = mask->control[i].legacy; | 1645 | sdata->rc_rateidx_mask[i] = mask->control[i].legacy; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 00a0685f2403..2ddb56e5b51f 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -565,4 +565,22 @@ static inline bool drv_tx_frames_pending(struct ieee80211_local *local) | |||
565 | 565 | ||
566 | return ret; | 566 | return ret; |
567 | } | 567 | } |
568 | |||
569 | static inline int drv_set_bitrate_mask(struct ieee80211_local *local, | ||
570 | struct ieee80211_sub_if_data *sdata, | ||
571 | const struct cfg80211_bitrate_mask *mask) | ||
572 | { | ||
573 | int ret = -EOPNOTSUPP; | ||
574 | |||
575 | might_sleep(); | ||
576 | |||
577 | trace_drv_set_bitrate_mask(local, sdata, mask); | ||
578 | if (local->ops->set_bitrate_mask) | ||
579 | ret = local->ops->set_bitrate_mask(&local->hw, | ||
580 | &sdata->vif, mask); | ||
581 | trace_drv_return_int(local, ret); | ||
582 | |||
583 | return ret; | ||
584 | } | ||
585 | |||
568 | #endif /* __MAC80211_DRIVER_OPS */ | 586 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index c8c934d48b7a..191e834ec46b 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -989,6 +989,33 @@ DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait, | |||
989 | TP_ARGS(local) | 989 | TP_ARGS(local) |
990 | ); | 990 | ); |
991 | 991 | ||
992 | TRACE_EVENT(drv_set_bitrate_mask, | ||
993 | TP_PROTO(struct ieee80211_local *local, | ||
994 | struct ieee80211_sub_if_data *sdata, | ||
995 | const struct cfg80211_bitrate_mask *mask), | ||
996 | |||
997 | TP_ARGS(local, sdata, mask), | ||
998 | |||
999 | TP_STRUCT__entry( | ||
1000 | LOCAL_ENTRY | ||
1001 | VIF_ENTRY | ||
1002 | __field(u32, legacy_2g) | ||
1003 | __field(u32, legacy_5g) | ||
1004 | ), | ||
1005 | |||
1006 | TP_fast_assign( | ||
1007 | LOCAL_ASSIGN; | ||
1008 | VIF_ASSIGN; | ||
1009 | __entry->legacy_2g = mask->control[IEEE80211_BAND_2GHZ].legacy; | ||
1010 | __entry->legacy_5g = mask->control[IEEE80211_BAND_5GHZ].legacy; | ||
1011 | ), | ||
1012 | |||
1013 | TP_printk( | ||
1014 | LOCAL_PR_FMT VIF_PR_FMT " 2G Mask:0x%x 5G Mask:0x%x", | ||
1015 | LOCAL_PR_ARG, VIF_PR_ARG, __entry->legacy_2g, __entry->legacy_5g | ||
1016 | ) | ||
1017 | ); | ||
1018 | |||
992 | /* | 1019 | /* |
993 | * Tracing for API calls that drivers call. | 1020 | * Tracing for API calls that drivers call. |
994 | */ | 1021 | */ |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 14883966374e..b81860c94698 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -40,7 +40,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
40 | struct ieee80211_mgmt *mgmt, | 40 | struct ieee80211_mgmt *mgmt, |
41 | size_t len) | 41 | size_t len) |
42 | { | 42 | { |
43 | u16 auth_alg, auth_transaction, status_code; | 43 | u16 auth_alg, auth_transaction; |
44 | 44 | ||
45 | lockdep_assert_held(&sdata->u.ibss.mtx); | 45 | lockdep_assert_held(&sdata->u.ibss.mtx); |
46 | 46 | ||
@@ -49,7 +49,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
49 | 49 | ||
50 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 50 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
51 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | 51 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); |
52 | status_code = le16_to_cpu(mgmt->u.auth.status_code); | ||
53 | 52 | ||
54 | /* | 53 | /* |
55 | * IEEE 802.11 standard does not require authentication in IBSS | 54 | * IEEE 802.11 standard does not require authentication in IBSS |
@@ -527,8 +526,6 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
527 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | 526 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) |
528 | { | 527 | { |
529 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 528 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
530 | struct ieee80211_local *local = sdata->local; | ||
531 | struct ieee80211_supported_band *sband; | ||
532 | u8 bssid[ETH_ALEN]; | 529 | u8 bssid[ETH_ALEN]; |
533 | u16 capability; | 530 | u16 capability; |
534 | int i; | 531 | int i; |
@@ -551,8 +548,6 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
551 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", | 548 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", |
552 | sdata->name, bssid); | 549 | sdata->name, bssid); |
553 | 550 | ||
554 | sband = local->hw.wiphy->bands[ifibss->channel->band]; | ||
555 | |||
556 | capability = WLAN_CAPABILITY_IBSS; | 551 | capability = WLAN_CAPABILITY_IBSS; |
557 | 552 | ||
558 | if (ifibss->privacy) | 553 | if (ifibss->privacy) |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a77849970914..027c0467d7a3 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -766,6 +766,9 @@ struct ieee80211_local { | |||
766 | 766 | ||
767 | int tx_headroom; /* required headroom for hardware/radiotap */ | 767 | int tx_headroom; /* required headroom for hardware/radiotap */ |
768 | 768 | ||
769 | /* count for keys needing tailroom space allocation */ | ||
770 | int crypto_tx_tailroom_needed_cnt; | ||
771 | |||
769 | /* Tasklet and skb queue to process calls from IRQ mode. All frames | 772 | /* Tasklet and skb queue to process calls from IRQ mode. All frames |
770 | * added to skb_queue will be processed, but frames in | 773 | * added to skb_queue will be processed, but frames in |
771 | * skb_queue_unreliable may be dropped if the total length of these | 774 | * skb_queue_unreliable may be dropped if the total length of these |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index af3c56482c80..b510721e3b3d 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -101,6 +101,11 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
101 | 101 | ||
102 | if (!ret) { | 102 | if (!ret) { |
103 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; | 103 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
104 | |||
105 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | ||
106 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | ||
107 | key->local->crypto_tx_tailroom_needed_cnt--; | ||
108 | |||
104 | return 0; | 109 | return 0; |
105 | } | 110 | } |
106 | 111 | ||
@@ -156,6 +161,10 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
156 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); | 161 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); |
157 | 162 | ||
158 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 163 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
164 | |||
165 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | ||
166 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | ||
167 | key->local->crypto_tx_tailroom_needed_cnt++; | ||
159 | } | 168 | } |
160 | 169 | ||
161 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) | 170 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) |
@@ -388,8 +397,10 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) | |||
388 | ieee80211_aes_key_free(key->u.ccmp.tfm); | 397 | ieee80211_aes_key_free(key->u.ccmp.tfm); |
389 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) | 398 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) |
390 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); | 399 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); |
391 | if (key->local) | 400 | if (key->local) { |
392 | ieee80211_debugfs_key_remove(key); | 401 | ieee80211_debugfs_key_remove(key); |
402 | key->local->crypto_tx_tailroom_needed_cnt--; | ||
403 | } | ||
393 | 404 | ||
394 | kfree(key); | 405 | kfree(key); |
395 | } | 406 | } |
@@ -451,6 +462,8 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
451 | 462 | ||
452 | ieee80211_debugfs_key_add(key); | 463 | ieee80211_debugfs_key_add(key); |
453 | 464 | ||
465 | key->local->crypto_tx_tailroom_needed_cnt++; | ||
466 | |||
454 | ret = ieee80211_key_enable_hw_accel(key); | 467 | ret = ieee80211_key_enable_hw_accel(key); |
455 | 468 | ||
456 | mutex_unlock(&sdata->local->key_mtx); | 469 | mutex_unlock(&sdata->local->key_mtx); |
@@ -492,8 +505,12 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) | |||
492 | 505 | ||
493 | mutex_lock(&sdata->local->key_mtx); | 506 | mutex_lock(&sdata->local->key_mtx); |
494 | 507 | ||
495 | list_for_each_entry(key, &sdata->key_list, list) | 508 | sdata->local->crypto_tx_tailroom_needed_cnt = 0; |
509 | |||
510 | list_for_each_entry(key, &sdata->key_list, list) { | ||
511 | sdata->local->crypto_tx_tailroom_needed_cnt++; | ||
496 | ieee80211_key_enable_hw_accel(key); | 512 | ieee80211_key_enable_hw_accel(key); |
513 | } | ||
497 | 514 | ||
498 | mutex_unlock(&sdata->local->key_mtx); | 515 | mutex_unlock(&sdata->local->key_mtx); |
499 | } | 516 | } |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0ab2a8df312d..61877662e8f8 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -33,12 +33,6 @@ | |||
33 | #include "cfg.h" | 33 | #include "cfg.h" |
34 | #include "debugfs.h" | 34 | #include "debugfs.h" |
35 | 35 | ||
36 | |||
37 | static bool ieee80211_disable_40mhz_24ghz; | ||
38 | module_param(ieee80211_disable_40mhz_24ghz, bool, 0644); | ||
39 | MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, | ||
40 | "Disable 40MHz support in the 2.4GHz band"); | ||
41 | |||
42 | static struct lock_class_key ieee80211_rx_skb_queue_class; | 36 | static struct lock_class_key ieee80211_rx_skb_queue_class; |
43 | 37 | ||
44 | void ieee80211_configure_filter(struct ieee80211_local *local) | 38 | void ieee80211_configure_filter(struct ieee80211_local *local) |
@@ -728,18 +722,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
728 | } | 722 | } |
729 | channels += sband->n_channels; | 723 | channels += sband->n_channels; |
730 | 724 | ||
731 | /* | ||
732 | * Since ieee80211_disable_40mhz_24ghz is global, we can | ||
733 | * modify the sband's ht data even if the driver uses a | ||
734 | * global structure for that. | ||
735 | */ | ||
736 | if (ieee80211_disable_40mhz_24ghz && | ||
737 | band == IEEE80211_BAND_2GHZ && | ||
738 | sband->ht_cap.ht_supported) { | ||
739 | sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
740 | sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
741 | } | ||
742 | |||
743 | if (max_bitrates < sband->n_bitrates) | 725 | if (max_bitrates < sband->n_bitrates) |
744 | max_bitrates = sband->n_bitrates; | 726 | max_bitrates = sband->n_bitrates; |
745 | supp_ht = supp_ht || sband->ht_cap.ht_supported; | 727 | supp_ht = supp_ht || sband->ht_cap.ht_supported; |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 11207979e2e2..c1299e249541 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -613,12 +613,9 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
613 | struct sk_buff *skb) | 613 | struct sk_buff *skb) |
614 | { | 614 | { |
615 | struct ieee80211_rx_status *rx_status; | 615 | struct ieee80211_rx_status *rx_status; |
616 | struct ieee80211_if_mesh *ifmsh; | ||
617 | struct ieee80211_mgmt *mgmt; | 616 | struct ieee80211_mgmt *mgmt; |
618 | u16 stype; | 617 | u16 stype; |
619 | 618 | ||
620 | ifmsh = &sdata->u.mesh; | ||
621 | |||
622 | rx_status = IEEE80211_SKB_RXCB(skb); | 619 | rx_status = IEEE80211_SKB_RXCB(skb); |
623 | mgmt = (struct ieee80211_mgmt *) skb->data; | 620 | mgmt = (struct ieee80211_mgmt *) skb->data; |
624 | stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; | 621 | stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 5bf64d7112b3..e57f2e728cfe 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -633,7 +633,6 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, | |||
633 | struct mesh_path *mpath; | 633 | struct mesh_path *mpath; |
634 | u8 ttl; | 634 | u8 ttl; |
635 | u8 *ta, *target_addr; | 635 | u8 *ta, *target_addr; |
636 | u8 target_flags; | ||
637 | u32 target_sn; | 636 | u32 target_sn; |
638 | u16 target_rcode; | 637 | u16 target_rcode; |
639 | 638 | ||
@@ -644,7 +643,6 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, | |||
644 | return; | 643 | return; |
645 | } | 644 | } |
646 | ttl--; | 645 | ttl--; |
647 | target_flags = PERR_IE_TARGET_FLAGS(perr_elem); | ||
648 | target_addr = PERR_IE_TARGET_ADDR(perr_elem); | 646 | target_addr = PERR_IE_TARGET_ADDR(perr_elem); |
649 | target_sn = PERR_IE_TARGET_SN(perr_elem); | 647 | target_sn = PERR_IE_TARGET_SN(perr_elem); |
650 | target_rcode = PERR_IE_TARGET_RCODE(perr_elem); | 648 | target_rcode = PERR_IE_TARGET_RCODE(perr_elem); |
@@ -675,12 +673,10 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
675 | { | 673 | { |
676 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 674 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
677 | struct mesh_path *mpath; | 675 | struct mesh_path *mpath; |
678 | u8 *ta; | ||
679 | u8 ttl, flags, hopcount; | 676 | u8 ttl, flags, hopcount; |
680 | u8 *orig_addr; | 677 | u8 *orig_addr; |
681 | u32 orig_sn, metric; | 678 | u32 orig_sn, metric; |
682 | 679 | ||
683 | ta = mgmt->sa; | ||
684 | ttl = rann->rann_ttl; | 680 | ttl = rann->rann_ttl; |
685 | if (ttl <= 1) { | 681 | if (ttl <= 1) { |
686 | ifmsh->mshstats.dropped_frames_ttl++; | 682 | ifmsh->mshstats.dropped_frames_ttl++; |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index e37355193ed1..042461710880 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -14,12 +14,23 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
14 | 14 | ||
15 | ieee80211_scan_cancel(local); | 15 | ieee80211_scan_cancel(local); |
16 | 16 | ||
17 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { | ||
18 | mutex_lock(&local->sta_mtx); | ||
19 | list_for_each_entry(sta, &local->sta_list, list) { | ||
20 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | ||
21 | ieee80211_sta_tear_down_BA_sessions(sta, true); | ||
22 | } | ||
23 | mutex_unlock(&local->sta_mtx); | ||
24 | } | ||
25 | |||
17 | ieee80211_stop_queues_by_reason(hw, | 26 | ieee80211_stop_queues_by_reason(hw, |
18 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 27 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
19 | 28 | ||
20 | /* flush out all packets */ | 29 | /* flush out all packets */ |
21 | synchronize_net(); | 30 | synchronize_net(); |
22 | 31 | ||
32 | drv_flush(local, false); | ||
33 | |||
23 | local->quiescing = true; | 34 | local->quiescing = true; |
24 | /* make quiescing visible to timers everywhere */ | 35 | /* make quiescing visible to timers everywhere */ |
25 | mb(); | 36 | mb(); |
@@ -43,11 +54,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
43 | /* tear down aggregation sessions and remove STAs */ | 54 | /* tear down aggregation sessions and remove STAs */ |
44 | mutex_lock(&local->sta_mtx); | 55 | mutex_lock(&local->sta_mtx); |
45 | list_for_each_entry(sta, &local->sta_list, list) { | 56 | list_for_each_entry(sta, &local->sta_list, list) { |
46 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { | ||
47 | set_sta_flags(sta, WLAN_STA_BLOCK_BA); | ||
48 | ieee80211_sta_tear_down_BA_sessions(sta, true); | ||
49 | } | ||
50 | |||
51 | if (sta->uploaded) { | 57 | if (sta->uploaded) { |
52 | sdata = sta->sdata; | 58 | sdata = sta->sdata; |
53 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 59 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index a864890e4d03..13a6697651ad 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -652,7 +652,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
652 | set_release_timer: | 652 | set_release_timer: |
653 | 653 | ||
654 | mod_timer(&tid_agg_rx->reorder_timer, | 654 | mod_timer(&tid_agg_rx->reorder_timer, |
655 | tid_agg_rx->reorder_time[j] + | 655 | tid_agg_rx->reorder_time[j] + 1 + |
656 | HT_RX_REORDER_BUF_TIMEOUT); | 656 | HT_RX_REORDER_BUF_TIMEOUT); |
657 | } else { | 657 | } else { |
658 | del_timer(&tid_agg_rx->reorder_timer); | 658 | del_timer(&tid_agg_rx->reorder_timer); |
@@ -2368,47 +2368,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
2368 | return RX_QUEUED; | 2368 | return RX_QUEUED; |
2369 | } | 2369 | } |
2370 | 2370 | ||
2371 | static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr, | ||
2372 | struct ieee80211_rx_data *rx) | ||
2373 | { | ||
2374 | int keyidx; | ||
2375 | unsigned int hdrlen; | ||
2376 | |||
2377 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
2378 | if (rx->skb->len >= hdrlen + 4) | ||
2379 | keyidx = rx->skb->data[hdrlen + 3] >> 6; | ||
2380 | else | ||
2381 | keyidx = -1; | ||
2382 | |||
2383 | if (!rx->sta) { | ||
2384 | /* | ||
2385 | * Some hardware seem to generate incorrect Michael MIC | ||
2386 | * reports; ignore them to avoid triggering countermeasures. | ||
2387 | */ | ||
2388 | return; | ||
2389 | } | ||
2390 | |||
2391 | if (!ieee80211_has_protected(hdr->frame_control)) | ||
2392 | return; | ||
2393 | |||
2394 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) { | ||
2395 | /* | ||
2396 | * APs with pairwise keys should never receive Michael MIC | ||
2397 | * errors for non-zero keyidx because these are reserved for | ||
2398 | * group keys and only the AP is sending real multicast | ||
2399 | * frames in the BSS. | ||
2400 | */ | ||
2401 | return; | ||
2402 | } | ||
2403 | |||
2404 | if (!ieee80211_is_data(hdr->frame_control) && | ||
2405 | !ieee80211_is_auth(hdr->frame_control)) | ||
2406 | return; | ||
2407 | |||
2408 | mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL, | ||
2409 | GFP_ATOMIC); | ||
2410 | } | ||
2411 | |||
2412 | /* TODO: use IEEE80211_RX_FRAGMENTED */ | 2371 | /* TODO: use IEEE80211_RX_FRAGMENTED */ |
2413 | static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | 2372 | static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, |
2414 | struct ieee80211_rate *rate) | 2373 | struct ieee80211_rate *rate) |
@@ -2752,12 +2711,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | |||
2752 | if (!prepares) | 2711 | if (!prepares) |
2753 | return false; | 2712 | return false; |
2754 | 2713 | ||
2755 | if (status->flag & RX_FLAG_MMIC_ERROR) { | ||
2756 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) | ||
2757 | ieee80211_rx_michael_mic_report(hdr, rx); | ||
2758 | return false; | ||
2759 | } | ||
2760 | |||
2761 | if (!consume) { | 2714 | if (!consume) { |
2762 | skb = skb_copy(skb, GFP_ATOMIC); | 2715 | skb = skb_copy(skb, GFP_ATOMIC); |
2763 | if (!skb) { | 2716 | if (!skb) { |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a03d8a312875..d9e6e81ff6b2 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -587,7 +587,6 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
587 | { | 587 | { |
588 | unsigned long flags; | 588 | unsigned long flags; |
589 | struct sk_buff *skb; | 589 | struct sk_buff *skb; |
590 | struct ieee80211_sub_if_data *sdata; | ||
591 | 590 | ||
592 | if (skb_queue_empty(&sta->ps_tx_buf)) | 591 | if (skb_queue_empty(&sta->ps_tx_buf)) |
593 | return false; | 592 | return false; |
@@ -604,7 +603,6 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
604 | if (!skb) | 603 | if (!skb) |
605 | break; | 604 | break; |
606 | 605 | ||
607 | sdata = sta->sdata; | ||
608 | local->total_ps_buffered--; | 606 | local->total_ps_buffered--; |
609 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 607 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
610 | printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n", | 608 | printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n", |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 3ed3c835fbbf..1658efaa2e8e 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -446,3 +446,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
446 | dev_kfree_skb(skb); | 446 | dev_kfree_skb(skb); |
447 | } | 447 | } |
448 | EXPORT_SYMBOL(ieee80211_tx_status); | 448 | EXPORT_SYMBOL(ieee80211_tx_status); |
449 | |||
450 | void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets) | ||
451 | { | ||
452 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | ||
453 | cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr, | ||
454 | num_packets, GFP_ATOMIC); | ||
455 | } | ||
456 | EXPORT_SYMBOL(ieee80211_report_low_ack); | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 17b10be31f55..e3e3aa173af0 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1036,14 +1036,11 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1036 | struct ieee80211_radiotap_iterator iterator; | 1036 | struct ieee80211_radiotap_iterator iterator; |
1037 | struct ieee80211_radiotap_header *rthdr = | 1037 | struct ieee80211_radiotap_header *rthdr = |
1038 | (struct ieee80211_radiotap_header *) skb->data; | 1038 | (struct ieee80211_radiotap_header *) skb->data; |
1039 | struct ieee80211_supported_band *sband; | ||
1040 | bool hw_frag; | 1039 | bool hw_frag; |
1041 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1040 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1042 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, | 1041 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, |
1043 | NULL); | 1042 | NULL); |
1044 | 1043 | ||
1045 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | ||
1046 | |||
1047 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1044 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
1048 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 1045 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
1049 | 1046 | ||
@@ -1442,11 +1439,8 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | |||
1442 | struct ieee80211_tx_data tx; | 1439 | struct ieee80211_tx_data tx; |
1443 | ieee80211_tx_result res_prepare; | 1440 | ieee80211_tx_result res_prepare; |
1444 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1441 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1445 | u16 queue; | ||
1446 | bool result = true; | 1442 | bool result = true; |
1447 | 1443 | ||
1448 | queue = skb_get_queue_mapping(skb); | ||
1449 | |||
1450 | if (unlikely(skb->len < 10)) { | 1444 | if (unlikely(skb->len < 10)) { |
1451 | dev_kfree_skb(skb); | 1445 | dev_kfree_skb(skb); |
1452 | return true; | 1446 | return true; |
@@ -1482,12 +1476,7 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, | |||
1482 | { | 1476 | { |
1483 | int tail_need = 0; | 1477 | int tail_need = 0; |
1484 | 1478 | ||
1485 | /* | 1479 | if (may_encrypt && local->crypto_tx_tailroom_needed_cnt) { |
1486 | * This could be optimised, devices that do full hardware | ||
1487 | * crypto (including TKIP MMIC) need no tailroom... But we | ||
1488 | * have no drivers for such devices currently. | ||
1489 | */ | ||
1490 | if (may_encrypt) { | ||
1491 | tail_need = IEEE80211_ENCRYPT_TAILROOM; | 1480 | tail_need = IEEE80211_ENCRYPT_TAILROOM; |
1492 | tail_need -= skb_tailroom(skb); | 1481 | tail_need -= skb_tailroom(skb); |
1493 | tail_need = max_t(int, tail_need, 0); | 1482 | tail_need = max_t(int, tail_need, 0); |
@@ -2485,7 +2474,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2485 | { | 2474 | { |
2486 | struct ieee80211_local *local = hw_to_local(hw); | 2475 | struct ieee80211_local *local = hw_to_local(hw); |
2487 | struct sk_buff *skb = NULL; | 2476 | struct sk_buff *skb = NULL; |
2488 | struct sta_info *sta; | ||
2489 | struct ieee80211_tx_data tx; | 2477 | struct ieee80211_tx_data tx; |
2490 | struct ieee80211_sub_if_data *sdata; | 2478 | struct ieee80211_sub_if_data *sdata; |
2491 | struct ieee80211_if_ap *bss = NULL; | 2479 | struct ieee80211_if_ap *bss = NULL; |
@@ -2527,7 +2515,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2527 | 2515 | ||
2528 | info = IEEE80211_SKB_CB(skb); | 2516 | info = IEEE80211_SKB_CB(skb); |
2529 | 2517 | ||
2530 | sta = tx.sta; | ||
2531 | tx.flags |= IEEE80211_TX_PS_BUFFERED; | 2518 | tx.flags |= IEEE80211_TX_PS_BUFFERED; |
2532 | tx.channel = local->hw.conf.channel; | 2519 | tx.channel = local->hw.conf.channel; |
2533 | info->band = tx.channel->band; | 2520 | info->band = tx.channel->band; |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index e73c8cae036b..a94b312dbfac 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -198,9 +198,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
198 | struct sk_buff *skb; | 198 | struct sk_buff *skb; |
199 | struct ieee80211_mgmt *mgmt; | 199 | struct ieee80211_mgmt *mgmt; |
200 | u8 *pos, qos_info; | 200 | u8 *pos, qos_info; |
201 | const u8 *ies; | ||
202 | size_t offset = 0, noffset; | 201 | size_t offset = 0, noffset; |
203 | int i, len, count, rates_len, supp_rates_len; | 202 | int i, count, rates_len, supp_rates_len; |
204 | u16 capab; | 203 | u16 capab; |
205 | struct ieee80211_supported_band *sband; | 204 | struct ieee80211_supported_band *sband; |
206 | u32 rates = 0; | 205 | u32 rates = 0; |
@@ -285,7 +284,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
285 | } | 284 | } |
286 | 285 | ||
287 | /* SSID */ | 286 | /* SSID */ |
288 | ies = pos = skb_put(skb, 2 + wk->assoc.ssid_len); | 287 | pos = skb_put(skb, 2 + wk->assoc.ssid_len); |
289 | *pos++ = WLAN_EID_SSID; | 288 | *pos++ = WLAN_EID_SSID; |
290 | *pos++ = wk->assoc.ssid_len; | 289 | *pos++ = wk->assoc.ssid_len; |
291 | memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len); | 290 | memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len); |
@@ -295,7 +294,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
295 | if (supp_rates_len > 8) | 294 | if (supp_rates_len > 8) |
296 | supp_rates_len = 8; | 295 | supp_rates_len = 8; |
297 | 296 | ||
298 | len = sband->n_bitrates; | ||
299 | pos = skb_put(skb, supp_rates_len + 2); | 297 | pos = skb_put(skb, supp_rates_len + 2); |
300 | *pos++ = WLAN_EID_SUPP_RATES; | 298 | *pos++ = WLAN_EID_SUPP_RATES; |
301 | *pos++ = supp_rates_len; | 299 | *pos++ = supp_rates_len; |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index f1765de2f4bf..9dc3b5f26e80 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -87,42 +87,76 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
87 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 87 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
88 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 88 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
89 | 89 | ||
90 | /* No way to verify the MIC if the hardware stripped it */ | 90 | /* |
91 | if (status->flag & RX_FLAG_MMIC_STRIPPED) | 91 | * it makes no sense to check for MIC errors on anything other |
92 | * than data frames. | ||
93 | */ | ||
94 | if (!ieee80211_is_data_present(hdr->frame_control)) | ||
95 | return RX_CONTINUE; | ||
96 | |||
97 | /* | ||
98 | * No way to verify the MIC if the hardware stripped it or | ||
99 | * the IV with the key index. In this case we have solely rely | ||
100 | * on the driver to set RX_FLAG_MMIC_ERROR in the event of a | ||
101 | * MIC failure report. | ||
102 | */ | ||
103 | if (status->flag & (RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED)) { | ||
104 | if (status->flag & RX_FLAG_MMIC_ERROR) | ||
105 | goto mic_fail; | ||
106 | |||
107 | if (!(status->flag & RX_FLAG_IV_STRIPPED)) | ||
108 | goto update_iv; | ||
109 | |||
92 | return RX_CONTINUE; | 110 | return RX_CONTINUE; |
111 | } | ||
93 | 112 | ||
113 | /* | ||
114 | * Some hardware seems to generate Michael MIC failure reports; even | ||
115 | * though, the frame was not encrypted with TKIP and therefore has no | ||
116 | * MIC. Ignore the flag them to avoid triggering countermeasures. | ||
117 | */ | ||
94 | if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || | 118 | if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || |
95 | !ieee80211_has_protected(hdr->frame_control) || | 119 | !(status->flag & RX_FLAG_DECRYPTED)) |
96 | !ieee80211_is_data_present(hdr->frame_control)) | ||
97 | return RX_CONTINUE; | 120 | return RX_CONTINUE; |
98 | 121 | ||
122 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && rx->key->conf.keyidx) { | ||
123 | /* | ||
124 | * APs with pairwise keys should never receive Michael MIC | ||
125 | * errors for non-zero keyidx because these are reserved for | ||
126 | * group keys and only the AP is sending real multicast | ||
127 | * frames in the BSS. ( | ||
128 | */ | ||
129 | return RX_DROP_UNUSABLE; | ||
130 | } | ||
131 | |||
132 | if (status->flag & RX_FLAG_MMIC_ERROR) | ||
133 | goto mic_fail; | ||
134 | |||
99 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 135 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
100 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) | 136 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) |
101 | return RX_DROP_UNUSABLE; | 137 | return RX_DROP_UNUSABLE; |
102 | 138 | ||
103 | data = skb->data + hdrlen; | 139 | data = skb->data + hdrlen; |
104 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; | 140 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; |
105 | |||
106 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; | 141 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; |
107 | michael_mic(key, hdr, data, data_len, mic); | 142 | michael_mic(key, hdr, data, data_len, mic); |
108 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) { | 143 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) |
109 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | 144 | goto mic_fail; |
110 | return RX_DROP_UNUSABLE; | ||
111 | |||
112 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | ||
113 | (void *) skb->data, NULL, | ||
114 | GFP_ATOMIC); | ||
115 | return RX_DROP_UNUSABLE; | ||
116 | } | ||
117 | 145 | ||
118 | /* remove Michael MIC from payload */ | 146 | /* remove Michael MIC from payload */ |
119 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); | 147 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); |
120 | 148 | ||
149 | update_iv: | ||
121 | /* update IV in key information to be able to detect replays */ | 150 | /* update IV in key information to be able to detect replays */ |
122 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; | 151 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; |
123 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; | 152 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; |
124 | 153 | ||
125 | return RX_CONTINUE; | 154 | return RX_CONTINUE; |
155 | |||
156 | mic_fail: | ||
157 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | ||
158 | (void *) skb->data, NULL, GFP_ATOMIC); | ||
159 | return RX_DROP_UNUSABLE; | ||
126 | } | 160 | } |
127 | 161 | ||
128 | 162 | ||
diff --git a/net/wireless/core.c b/net/wireless/core.c index fe01de29bfe8..bbf1fa11107a 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -46,6 +46,11 @@ static struct dentry *ieee80211_debugfs_dir; | |||
46 | /* for the cleanup, scan and event works */ | 46 | /* for the cleanup, scan and event works */ |
47 | struct workqueue_struct *cfg80211_wq; | 47 | struct workqueue_struct *cfg80211_wq; |
48 | 48 | ||
49 | static bool cfg80211_disable_40mhz_24ghz; | ||
50 | module_param(cfg80211_disable_40mhz_24ghz, bool, 0644); | ||
51 | MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz, | ||
52 | "Disable 40MHz support in the 2.4GHz band"); | ||
53 | |||
49 | /* requires cfg80211_mutex to be held! */ | 54 | /* requires cfg80211_mutex to be held! */ |
50 | struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) | 55 | struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) |
51 | { | 56 | { |
@@ -451,6 +456,18 @@ int wiphy_register(struct wiphy *wiphy) | |||
451 | return -EINVAL; | 456 | return -EINVAL; |
452 | 457 | ||
453 | /* | 458 | /* |
459 | * Since cfg80211_disable_40mhz_24ghz is global, we can | ||
460 | * modify the sband's ht data even if the driver uses a | ||
461 | * global structure for that. | ||
462 | */ | ||
463 | if (cfg80211_disable_40mhz_24ghz && | ||
464 | band == IEEE80211_BAND_2GHZ && | ||
465 | sband->ht_cap.ht_supported) { | ||
466 | sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
467 | sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
468 | } | ||
469 | |||
470 | /* | ||
454 | * Since we use a u32 for rate bitmaps in | 471 | * Since we use a u32 for rate bitmaps in |
455 | * ieee80211_get_response_rate, we cannot | 472 | * ieee80211_get_response_rate, we cannot |
456 | * have more than 32 legacy rates. | 473 | * have more than 32 legacy rates. |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 58d69959ab28..1613080a96b9 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -1455,7 +1455,8 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
1455 | * We only time out user hints, given that they should be the only | 1455 | * We only time out user hints, given that they should be the only |
1456 | * source of bogus requests. | 1456 | * source of bogus requests. |
1457 | */ | 1457 | */ |
1458 | if (reg_request->initiator == NL80211_REGDOM_SET_BY_USER) | 1458 | if (r != -EALREADY && |
1459 | reg_request->initiator == NL80211_REGDOM_SET_BY_USER) | ||
1459 | schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); | 1460 | schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); |
1460 | } | 1461 | } |
1461 | 1462 | ||