aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/phy_n.c
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2010-01-15 08:48:21 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-15 17:05:36 -0500
commit90b9738d85395d46ffdc961e1a0c80a17e8f4d32 (patch)
treeb95c1028dad4aecae1266aa79e66b166b505751e /drivers/net/wireless/b43/phy_n.c
parentdfb4aa5dd0a9b61a6eaa64e9209b2f8839c0a256 (diff)
b43: N-PHY: RSSI calibration for rev < 3
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/phy_n.c')
-rw-r--r--drivers/net/wireless/b43/phy_n.c157
1 files changed, 155 insertions, 2 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index a0e84c428e79..126c0afa5da2 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -685,7 +685,160 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
685/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ 685/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
686static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) 686static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
687{ 687{
688 /* TODO */ 688 int i, j;
689 u8 state[4];
690 u8 code, val;
691 u16 class, override;
692 u8 regs_save_radio[2];
693 u16 regs_save_phy[2];
694 s8 offset[4];
695
696 u16 clip_state[2];
697 u16 clip_off[2] = { 0xFFFF, 0xFFFF };
698 s32 results_min[4] = { };
699 u8 vcm_final[4] = { };
700 s32 results[4][4] = { };
701 s32 miniq[4][2] = { };
702
703 if (type == 2) {
704 code = 0;
705 val = 6;
706 } else if (type < 2) {
707 code = 25;
708 val = 4;
709 } else {
710 B43_WARN_ON(1);
711 return;
712 }
713
714 class = b43_nphy_classifier(dev, 0, 0);
715 b43_nphy_classifier(dev, 7, 4);
716 b43_nphy_read_clip_detection(dev, clip_state);
717 b43_nphy_write_clip_detection(dev, clip_off);
718
719 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
720 override = 0x140;
721 else
722 override = 0x110;
723
724 regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
725 regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX);
726 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
727 b43_radio_write16(dev, B2055_C1_PD_RXTX, val);
728
729 regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
730 regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX);
731 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
732 b43_radio_write16(dev, B2055_C2_PD_RXTX, val);
733
734 state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07;
735 state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07;
736 b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8);
737 b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8);
738 state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07;
739 state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07;
740
741 b43_nphy_rssi_select(dev, 5, type);
742 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type);
743 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type);
744
745 for (i = 0; i < 4; i++) {
746 u8 tmp[4];
747 for (j = 0; j < 4; j++)
748 tmp[j] = i;
749 if (type != 1)
750 b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
751 b43_nphy_poll_rssi(dev, type, results[i], 8);
752 if (type < 2)
753 for (j = 0; j < 2; j++)
754 miniq[i][j] = min(results[i][2 * j],
755 results[i][2 * j + 1]);
756 }
757
758 for (i = 0; i < 4; i++) {
759 s32 mind = 40;
760 u8 minvcm = 0;
761 s32 minpoll = 249;
762 s32 curr;
763 for (j = 0; j < 4; j++) {
764 if (type == 2)
765 curr = abs(results[j][i]);
766 else
767 curr = abs(miniq[j][i / 2] - code * 8);
768
769 if (curr < mind) {
770 mind = curr;
771 minvcm = j;
772 }
773
774 if (results[j][i] < minpoll)
775 minpoll = results[j][i];
776 }
777 results_min[i] = minpoll;
778 vcm_final[i] = minvcm;
779 }
780
781 if (type != 1)
782 b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
783
784 for (i = 0; i < 4; i++) {
785 offset[i] = (code * 8) - results[vcm_final[i]][i];
786
787 if (offset[i] < 0)
788 offset[i] = -((abs(offset[i]) + 4) / 8);
789 else
790 offset[i] = (offset[i] + 4) / 8;
791
792 if (results_min[i] == 248)
793 offset[i] = code - 32;
794
795 if (i % 2 == 0)
796 b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0,
797 type);
798 else
799 b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1,
800 type);
801 }
802
803 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
804 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]);
805
806 switch (state[2]) {
807 case 1:
808 b43_nphy_rssi_select(dev, 1, 2);
809 break;
810 case 4:
811 b43_nphy_rssi_select(dev, 1, 0);
812 break;
813 case 2:
814 b43_nphy_rssi_select(dev, 1, 1);
815 break;
816 default:
817 b43_nphy_rssi_select(dev, 1, 1);
818 break;
819 }
820
821 switch (state[3]) {
822 case 1:
823 b43_nphy_rssi_select(dev, 2, 2);
824 break;
825 case 4:
826 b43_nphy_rssi_select(dev, 2, 0);
827 break;
828 default:
829 b43_nphy_rssi_select(dev, 2, 1);
830 break;
831 }
832
833 b43_nphy_rssi_select(dev, 0, type);
834
835 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
836 b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
837 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
838 b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
839
840 b43_nphy_classifier(dev, 7, class);
841 b43_nphy_write_clip_detection(dev, clip_state);
689} 842}
690 843
691/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ 844/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
@@ -867,7 +1020,7 @@ int b43_phy_initn(struct b43_wldev *dev)
867 if (nphy->antsel_type == 2) 1020 if (nphy->antsel_type == 2)
868 ;/*TODO NPHY Superswitch Init with argument 1*/ 1021 ;/*TODO NPHY Superswitch Init with argument 1*/
869 if (nphy->perical != 2) { 1022 if (nphy->perical != 2) {
870 /* b43_nphy_rssi_cal(dev); */ 1023 b43_nphy_rssi_cal(dev);
871 if (phy->rev >= 3) { 1024 if (phy->rev >= 3) {
872 nphy->cal_orig_pwr_idx[0] = 1025 nphy->cal_orig_pwr_idx[0] =
873 nphy->txpwrindex[0].index_internal; 1026 nphy->txpwrindex[0].index_internal;