b43: N-PHY: add rev7+ workarounds for radio revs 9 and 14
authorRafał Miłecki <zajec5@gmail.com>
Sat, 19 Jul 2014 10:52:45 +0000 (12:52 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 22 Jul 2014 17:53:18 +0000 (13:53 -0400)
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/b43/phy_n.c

index 376dcf9555796e36f315a54b2c1223722e8ff22c..1052540c97f88fd10003b7cf11a25ae9764e6e9d 100644 (file)
@@ -2722,9 +2722,9 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
 
        u16 lpf_ofdm_20mhz[2], lpf_ofdm_40mhz[2], lpf_11b[2];
        u16 bcap_val;
-       u16 bcap_val_11b[2], bcap_val_11n_20[2], bcap_val_11n_40[2];
+       s16 bcap_val_11b[2], bcap_val_11n_20[2], bcap_val_11n_40[2];
        u16 scap_val;
-       u16 scap_val_11b[2], scap_val_11n_20[2], scap_val_11n_40[2];
+       s16 scap_val_11b[2], scap_val_11n_20[2], scap_val_11n_40[2];
        bool rccal_ovrd = false;
 
        u16 bias, conv, filt;
@@ -2799,6 +2799,8 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
        scap_val = b43_radio_read(dev, R2057_RCCAL_SCAP_VAL);
 
        if (b43_nphy_ipa(dev)) {
+               bool ghz2 = b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ;
+
                switch (phy->radio_rev) {
                case 5:
                        /* Check radio version (to be 0) by PHY rev for now */
@@ -2838,6 +2840,58 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
                                }
                        }
 
+                       rccal_ovrd = true;
+                       break;
+               case 9:
+                       for (core = 0; core < 2; core++) {
+                               bcap_val_11b[core] = bcap_val;
+                               scap_val_11b[core] = scap_val;
+                               lpf_11b[core] = 1;
+
+                               if (ghz2) {
+                                       bcap_val_11n_20[core] = bcap_val + 13;
+                                       scap_val_11n_20[core] = scap_val + 15;
+                               } else {
+                                       bcap_val_11n_20[core] = bcap_val + 14;
+                                       scap_val_11n_20[core] = scap_val + 15;
+                               }
+                               lpf_ofdm_20mhz[core] = 4;
+
+                               if (ghz2) {
+                                       bcap_val_11n_40[core] = bcap_val - 7;
+                                       scap_val_11n_40[core] = scap_val - 5;
+                               } else {
+                                       bcap_val_11n_40[core] = bcap_val + 2;
+                                       scap_val_11n_40[core] = scap_val + 4;
+                               }
+                               lpf_ofdm_40mhz[core] = 4;
+                       }
+
+                       rccal_ovrd = true;
+                       break;
+               case 14:
+                       for (core = 0; core < 2; core++) {
+                               bcap_val_11b[core] = bcap_val;
+                               scap_val_11b[core] = scap_val;
+                               lpf_11b[core] = 1;
+                       }
+
+                       bcap_val_11n_20[0] = bcap_val + 20;
+                       scap_val_11n_20[0] = scap_val + 20;
+                       lpf_ofdm_20mhz[0] = 3;
+
+                       bcap_val_11n_20[1] = bcap_val + 16;
+                       scap_val_11n_20[1] = scap_val + 16;
+                       lpf_ofdm_20mhz[1] = 3;
+
+                       bcap_val_11n_40[0] = bcap_val + 20;
+                       scap_val_11n_40[0] = scap_val + 20;
+                       lpf_ofdm_40mhz[0] = 4;
+
+                       bcap_val_11n_40[1] = bcap_val + 10;
+                       scap_val_11n_40[1] = scap_val + 10;
+                       lpf_ofdm_40mhz[1] = 4;
+
                        rccal_ovrd = true;
                        break;
                }
@@ -2862,6 +2916,13 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
                u8 rx2tx_lut_extra = 1;
 
                for (core = 0; core < 2; core++) {
+                       bcap_val_11b[core] = clamp_val(bcap_val_11b[core], 0, 0x1f);
+                       scap_val_11b[core] = clamp_val(scap_val_11b[core], 0, 0x1f);
+                       bcap_val_11n_20[core] = clamp_val(bcap_val_11n_20[core], 0, 0x1f);
+                       scap_val_11n_20[core] = clamp_val(scap_val_11n_20[core], 0, 0x1f);
+                       bcap_val_11n_40[core] = clamp_val(bcap_val_11n_40[core], 0, 0x1f);
+                       scap_val_11n_40[core] = clamp_val(scap_val_11n_40[core], 0, 0x1f);
+
                        rx2tx_lut_20_11b[core] = (rx2tx_lut_extra << 13) |
                                                 (bcap_val_11b[core] << 8) |
                                                 (scap_val_11b[core] << 3) |
@@ -2982,6 +3043,20 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
                                        b43_radio_write(dev, 0xE8, 0x16);
                                }
                                break;
+                       case 14:
+                               for (core = 0; core < 2; core++) {
+                                       int o = core ? 0x85 : 0;
+
+                                       b43_radio_write(dev, o + R2057_IPA2G_CASCONV_CORE0, 0x13);
+                                       b43_radio_write(dev, o + R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, 0x21);
+                                       b43_radio_write(dev, o + R2057_IPA2G_BIAS_FILTER_CORE0, 0xff);
+                                       b43_radio_write(dev, o + R2057_PAD2G_IDACS_CORE0, 0x88);
+                                       b43_radio_write(dev, o + R2057_PAD2G_TUNE_PUS_CORE0, 0x23);
+                                       b43_radio_write(dev, o + R2057_IPA2G_IMAIN_CORE0, 0x16);
+                                       b43_radio_write(dev, o + R2057_PAD_BIAS_FILTER_BWS_CORE0, 0x3e);
+                                       b43_radio_write(dev, o + R2057_BACKUP1_CORE0, 0x10);
+                               }
+                               break;
                        }
                } else {
                        u16 freq = phy->chandef->chan->center_freq;