summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2011-12-17 13:57:25 +0100
committerJohn W. Linville <linville@tuxdriver.com>2011-12-19 14:40:49 -0500
commit5ecab603c75efafaa2604725efe0afc3da4bd55b (patch)
treeaef8288287bf3cf1ca8a203cff9feae57396ee51 /drivers/net/wireless/b43
parent647120956e4e9a2151c42f4d3eead20c7f7be869 (diff)
downloadlinux-3.10-5ecab603c75efafaa2604725efe0afc3da4bd55b.tar.gz
linux-3.10-5ecab603c75efafaa2604725efe0afc3da4bd55b.tar.bz2
linux-3.10-5ecab603c75efafaa2604725efe0afc3da4bd55b.zip
b43: N-PHY: reorder functions: move RSSI calibration
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Acked-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/phy_n.c600
1 files changed, 300 insertions, 300 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 620d278c59c..f027909a4b3 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -1193,6 +1193,306 @@ static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
b43_nphy_rev2_rssi_select(dev, code, type);
}
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
+static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf)
+{
+ int i;
+ for (i = 0; i < 2; i++) {
+ if (type == 2) {
+ if (i == 0) {
+ b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM,
+ 0xFC, buf[0]);
+ b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
+ 0xFC, buf[1]);
+ } else {
+ b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM,
+ 0xFC, buf[2 * i]);
+ b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
+ 0xFC, buf[2 * i + 1]);
+ }
+ } else {
+ if (i == 0)
+ b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
+ 0xF3, buf[0] << 2);
+ else
+ b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
+ 0xF3, buf[2 * i + 1] << 2);
+ }
+ }
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
+static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
+ u8 nsamp)
+{
+ int i;
+ int out;
+ u16 save_regs_phy[9];
+ u16 s[2];
+
+ if (dev->phy.rev >= 3) {
+ save_regs_phy[0] = b43_phy_read(dev,
+ B43_NPHY_RFCTL_LUT_TRSW_UP1);
+ save_regs_phy[1] = b43_phy_read(dev,
+ B43_NPHY_RFCTL_LUT_TRSW_UP2);
+ save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
+ save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
+ save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
+ save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
+ save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
+ save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
+ save_regs_phy[8] = 0;
+ } else {
+ save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
+ save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
+ save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
+ save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD);
+ save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
+ save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
+ save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
+ save_regs_phy[7] = 0;
+ save_regs_phy[8] = 0;
+ }
+
+ b43_nphy_rssi_select(dev, 5, type);
+
+ if (dev->phy.rev < 2) {
+ save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL);
+ b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5);
+ }
+
+ for (i = 0; i < 4; i++)
+ buf[i] = 0;
+
+ for (i = 0; i < nsamp; i++) {
+ if (dev->phy.rev < 2) {
+ s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT);
+ s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT);
+ } else {
+ s[0] = b43_phy_read(dev, B43_NPHY_RSSI1);
+ s[1] = b43_phy_read(dev, B43_NPHY_RSSI2);
+ }
+
+ buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2;
+ buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2;
+ buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2;
+ buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2;
+ }
+ out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 |
+ (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF);
+
+ if (dev->phy.rev < 2)
+ b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
+
+ if (dev->phy.rev >= 3) {
+ b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
+ save_regs_phy[0]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
+ save_regs_phy[1]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
+ b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
+ b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
+ } else {
+ b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
+ b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]);
+ }
+
+ return out;
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
+static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
+{
+ int i, j;
+ u8 state[4];
+ u8 code, val;
+ u16 class, override;
+ u8 regs_save_radio[2];
+ u16 regs_save_phy[2];
+
+ s8 offset[4];
+ u8 core;
+ u8 rail;
+
+ u16 clip_state[2];
+ u16 clip_off[2] = { 0xFFFF, 0xFFFF };
+ s32 results_min[4] = { };
+ u8 vcm_final[4] = { };
+ s32 results[4][4] = { };
+ s32 miniq[4][2] = { };
+
+ if (type == 2) {
+ code = 0;
+ val = 6;
+ } else if (type < 2) {
+ code = 25;
+ val = 4;
+ } else {
+ B43_WARN_ON(1);
+ return;
+ }
+
+ class = b43_nphy_classifier(dev, 0, 0);
+ b43_nphy_classifier(dev, 7, 4);
+ b43_nphy_read_clip_detection(dev, clip_state);
+ b43_nphy_write_clip_detection(dev, clip_off);
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+ override = 0x140;
+ else
+ override = 0x110;
+
+ regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
+ regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX);
+ b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
+ b43_radio_write16(dev, B2055_C1_PD_RXTX, val);
+
+ regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
+ regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX);
+ b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
+ b43_radio_write16(dev, B2055_C2_PD_RXTX, val);
+
+ state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07;
+ state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07;
+ b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8);
+ b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8);
+ state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07;
+ state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07;
+
+ b43_nphy_rssi_select(dev, 5, type);
+ b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type);
+ b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type);
+
+ for (i = 0; i < 4; i++) {
+ u8 tmp[4];
+ for (j = 0; j < 4; j++)
+ tmp[j] = i;
+ if (type != 1)
+ b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
+ b43_nphy_poll_rssi(dev, type, results[i], 8);
+ if (type < 2)
+ for (j = 0; j < 2; j++)
+ miniq[i][j] = min(results[i][2 * j],
+ results[i][2 * j + 1]);
+ }
+
+ for (i = 0; i < 4; i++) {
+ s32 mind = 40;
+ u8 minvcm = 0;
+ s32 minpoll = 249;
+ s32 curr;
+ for (j = 0; j < 4; j++) {
+ if (type == 2)
+ curr = abs(results[j][i]);
+ else
+ curr = abs(miniq[j][i / 2] - code * 8);
+
+ if (curr < mind) {
+ mind = curr;
+ minvcm = j;
+ }
+
+ if (results[j][i] < minpoll)
+ minpoll = results[j][i];
+ }
+ results_min[i] = minpoll;
+ vcm_final[i] = minvcm;
+ }
+
+ if (type != 1)
+ b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
+
+ for (i = 0; i < 4; i++) {
+ offset[i] = (code * 8) - results[vcm_final[i]][i];
+
+ if (offset[i] < 0)
+ offset[i] = -((abs(offset[i]) + 4) / 8);
+ else
+ offset[i] = (offset[i] + 4) / 8;
+
+ if (results_min[i] == 248)
+ offset[i] = code - 32;
+
+ core = (i / 2) ? 2 : 1;
+ rail = (i % 2) ? 1 : 0;
+
+ b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail,
+ type);
+ }
+
+ b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
+ b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]);
+
+ switch (state[2]) {
+ case 1:
+ b43_nphy_rssi_select(dev, 1, 2);
+ break;
+ case 4:
+ b43_nphy_rssi_select(dev, 1, 0);
+ break;
+ case 2:
+ b43_nphy_rssi_select(dev, 1, 1);
+ break;
+ default:
+ b43_nphy_rssi_select(dev, 1, 1);
+ break;
+ }
+
+ switch (state[3]) {
+ case 1:
+ b43_nphy_rssi_select(dev, 2, 2);
+ break;
+ case 4:
+ b43_nphy_rssi_select(dev, 2, 0);
+ break;
+ default:
+ b43_nphy_rssi_select(dev, 2, 1);
+ break;
+ }
+
+ b43_nphy_rssi_select(dev, 0, type);
+
+ b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
+ b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
+ b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
+ b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
+
+ b43_nphy_classifier(dev, 7, class);
+ b43_nphy_write_clip_detection(dev, clip_state);
+ /* Specs don't say about reset here, but it makes wl and b43 dumps
+ identical, it really seems wl performs this */
+ b43_nphy_reset_cca(dev);
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
+static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
+{
+ /* TODO */
+}
+
+/*
+ * RSSI Calibration
+ * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
+ */
+static void b43_nphy_rssi_cal(struct b43_wldev *dev)
+{
+ if (dev->phy.rev >= 3) {
+ b43_nphy_rev3_rssi_cal(dev);
+ } else {
+ b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z);
+ b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X);
+ b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y);
+ }
+}
+
/**************************************************
* Workarounds
**************************************************/
@@ -2539,306 +2839,6 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
-static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf)
-{
- int i;
- for (i = 0; i < 2; i++) {
- if (type == 2) {
- if (i == 0) {
- b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM,
- 0xFC, buf[0]);
- b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
- 0xFC, buf[1]);
- } else {
- b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM,
- 0xFC, buf[2 * i]);
- b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
- 0xFC, buf[2 * i + 1]);
- }
- } else {
- if (i == 0)
- b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
- 0xF3, buf[0] << 2);
- else
- b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
- 0xF3, buf[2 * i + 1] << 2);
- }
- }
-}
-
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
-static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
- u8 nsamp)
-{
- int i;
- int out;
- u16 save_regs_phy[9];
- u16 s[2];
-
- if (dev->phy.rev >= 3) {
- save_regs_phy[0] = b43_phy_read(dev,
- B43_NPHY_RFCTL_LUT_TRSW_UP1);
- save_regs_phy[1] = b43_phy_read(dev,
- B43_NPHY_RFCTL_LUT_TRSW_UP2);
- save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
- save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
- save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
- save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
- save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
- save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
- save_regs_phy[8] = 0;
- } else {
- save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
- save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
- save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
- save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD);
- save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
- save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
- save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
- save_regs_phy[7] = 0;
- save_regs_phy[8] = 0;
- }
-
- b43_nphy_rssi_select(dev, 5, type);
-
- if (dev->phy.rev < 2) {
- save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL);
- b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5);
- }
-
- for (i = 0; i < 4; i++)
- buf[i] = 0;
-
- for (i = 0; i < nsamp; i++) {
- if (dev->phy.rev < 2) {
- s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT);
- s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT);
- } else {
- s[0] = b43_phy_read(dev, B43_NPHY_RSSI1);
- s[1] = b43_phy_read(dev, B43_NPHY_RSSI2);
- }
-
- buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2;
- buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2;
- buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2;
- buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2;
- }
- out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 |
- (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF);
-
- if (dev->phy.rev < 2)
- b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
-
- if (dev->phy.rev >= 3) {
- b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
- save_regs_phy[0]);
- b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
- save_regs_phy[1]);
- b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]);
- b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]);
- b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
- b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
- b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
- b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
- } else {
- b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
- b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
- b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
- b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]);
- b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]);
- b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]);
- b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]);
- }
-
- return out;
-}
-
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
-static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
-{
- int i, j;
- u8 state[4];
- u8 code, val;
- u16 class, override;
- u8 regs_save_radio[2];
- u16 regs_save_phy[2];
-
- s8 offset[4];
- u8 core;
- u8 rail;
-
- u16 clip_state[2];
- u16 clip_off[2] = { 0xFFFF, 0xFFFF };
- s32 results_min[4] = { };
- u8 vcm_final[4] = { };
- s32 results[4][4] = { };
- s32 miniq[4][2] = { };
-
- if (type == 2) {
- code = 0;
- val = 6;
- } else if (type < 2) {
- code = 25;
- val = 4;
- } else {
- B43_WARN_ON(1);
- return;
- }
-
- class = b43_nphy_classifier(dev, 0, 0);
- b43_nphy_classifier(dev, 7, 4);
- b43_nphy_read_clip_detection(dev, clip_state);
- b43_nphy_write_clip_detection(dev, clip_off);
-
- if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
- override = 0x140;
- else
- override = 0x110;
-
- regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
- regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX);
- b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
- b43_radio_write16(dev, B2055_C1_PD_RXTX, val);
-
- regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
- regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX);
- b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
- b43_radio_write16(dev, B2055_C2_PD_RXTX, val);
-
- state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07;
- state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07;
- b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8);
- b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8);
- state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07;
- state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07;
-
- b43_nphy_rssi_select(dev, 5, type);
- b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type);
- b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type);
-
- for (i = 0; i < 4; i++) {
- u8 tmp[4];
- for (j = 0; j < 4; j++)
- tmp[j] = i;
- if (type != 1)
- b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
- b43_nphy_poll_rssi(dev, type, results[i], 8);
- if (type < 2)
- for (j = 0; j < 2; j++)
- miniq[i][j] = min(results[i][2 * j],
- results[i][2 * j + 1]);
- }
-
- for (i = 0; i < 4; i++) {
- s32 mind = 40;
- u8 minvcm = 0;
- s32 minpoll = 249;
- s32 curr;
- for (j = 0; j < 4; j++) {
- if (type == 2)
- curr = abs(results[j][i]);
- else
- curr = abs(miniq[j][i / 2] - code * 8);
-
- if (curr < mind) {
- mind = curr;
- minvcm = j;
- }
-
- if (results[j][i] < minpoll)
- minpoll = results[j][i];
- }
- results_min[i] = minpoll;
- vcm_final[i] = minvcm;
- }
-
- if (type != 1)
- b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
-
- for (i = 0; i < 4; i++) {
- offset[i] = (code * 8) - results[vcm_final[i]][i];
-
- if (offset[i] < 0)
- offset[i] = -((abs(offset[i]) + 4) / 8);
- else
- offset[i] = (offset[i] + 4) / 8;
-
- if (results_min[i] == 248)
- offset[i] = code - 32;
-
- core = (i / 2) ? 2 : 1;
- rail = (i % 2) ? 1 : 0;
-
- b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail,
- type);
- }
-
- b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
- b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]);
-
- switch (state[2]) {
- case 1:
- b43_nphy_rssi_select(dev, 1, 2);
- break;
- case 4:
- b43_nphy_rssi_select(dev, 1, 0);
- break;
- case 2:
- b43_nphy_rssi_select(dev, 1, 1);
- break;
- default:
- b43_nphy_rssi_select(dev, 1, 1);
- break;
- }
-
- switch (state[3]) {
- case 1:
- b43_nphy_rssi_select(dev, 2, 2);
- break;
- case 4:
- b43_nphy_rssi_select(dev, 2, 0);
- break;
- default:
- b43_nphy_rssi_select(dev, 2, 1);
- break;
- }
-
- b43_nphy_rssi_select(dev, 0, type);
-
- b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
- b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
- b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
- b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
-
- b43_nphy_classifier(dev, 7, class);
- b43_nphy_write_clip_detection(dev, clip_state);
- /* Specs don't say about reset here, but it makes wl and b43 dumps
- identical, it really seems wl performs this */
- b43_nphy_reset_cca(dev);
-}
-
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
-static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
-{
- /* TODO */
-}
-
-/*
- * RSSI Calibration
- * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
- */
-static void b43_nphy_rssi_cal(struct b43_wldev *dev)
-{
- if (dev->phy.rev >= 3) {
- b43_nphy_rev3_rssi_cal(dev);
- } else {
- b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z);
- b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X);
- b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y);
- }
-}
-
/*
* Restore RSSI Calibration
* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal