> Date: Sun, 9 Feb 2014 14:23:18 +0100
> From: Fabian Raetz <fabian.ra...@gmail.com>
> > 
> > Hmm, my cleanup was based on the version you send out on December
> > 31st.  Can you send me the latest version of your diff?
> > 
> 
> On Tue, Jan 07, 2014 at 12:08:02PM +0100, Martin Pieuchot wrote:
> > On 03/01/14(Fri) 14:24, Fabian Raetz wrote:
> > > Hi tech@,
> > > 
> > > here is an updated patch.
> > > 
> > > it seems like Intel Centrino Wireless-N 2030 and
> > > Intel Centrino Wireless-N 2230 have the same pciids...
> > > 
> > > this makes patch apply again with newest pcidevs changes.
> > 
> > Please also make sure to use tab and not space when appropriate ;)  You
> > can check style(9) if in doubt !
> > 
> ups :)
> attached is a diff
> - which follows style(9) (hopefully) and
> - fixes a firmware error by handling IWN_FW_TLV_ENH_SENS and
>   IWN_FW_TLV_PHY_CALIB in iwn_read_firmware_tlv().
> 
> @mike, only style changes since the last patch i send you.

Thanks.  I incorporated the changes in my cleaned up version.

The change does affect other hardware types now, but I've tested this
on a couple of systems:

iwn0 at pci3 dev 0 function 0 "Intel WiFi Link 5300" rev 0x00: msi, MIMO 3T3R, 
MoW

iwn0 at pci3 dev 0 function 0 "Intel Centrino Ultimate-N 6300" rev 0x35: msi, 
MIMO 3T3R, MoW

iwn0 at pci2 dev 0 function 0 "Intel Centrino Advanced-N 6205" rev 0x34: msi, 
MIMO 2T2R, MoW

So if this one works for you and Benoit, I'll go ahead and commit this.


Index: if_iwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
retrieving revision 1.127
diff -u -p -r1.127 if_iwn.c
--- if_iwn.c    6 Dec 2013 21:03:04 -0000       1.127
+++ if_iwn.c    9 Feb 2014 20:25:41 -0000
@@ -94,6 +94,8 @@ static const struct pci_matchid iwn_devi
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_130_2 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6235_1 },
        { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_6235_2 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_2030_1 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_2030_2 },
 };
 
 int            iwn_match(struct device *, void *, void *);
@@ -243,7 +245,8 @@ int         iwn5000_query_calibration(struct iw
 int            iwn5000_send_calibration(struct iwn_softc *);
 int            iwn5000_send_wimax_coex(struct iwn_softc *);
 int            iwn5000_crystal_calib(struct iwn_softc *);
-int            iwn5000_temp_offset_calib(struct iwn_softc *);
+int            iwn6000_temp_offset_calib(struct iwn_softc *);
+int            iwn2000_temp_offset_calib(struct iwn_softc *);
 int            iwn4965_post_alive(struct iwn_softc *);
 int            iwn5000_post_alive(struct iwn_softc *);
 int            iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
@@ -651,6 +654,11 @@ iwn5000_attach(struct iwn_softc *sc, pci
                } else
                        sc->fwname = "iwn-6005";
                break;
+       case IWN_HW_REV_TYPE_2030:
+               sc->limits = &iwn2000_sensitivity_limits;
+               sc->fwname = "iwn-2030";
+               sc->sc_flags |= IWN_FLAG_ADV_BT_COEX;
+               break;
        default:
                printf(": adapter type %d not supported\n", sc->hw_type);
                return ENOTSUP;
@@ -1529,6 +1537,14 @@ iwn5000_read_eeprom(struct iwn_softc *sc
            hdr.version, hdr.pa_type, letoh16(hdr.volt)));
        sc->calib_ver = hdr.version;
 
+       if (sc->hw_type == IWN_HW_REV_TYPE_2030) {
+               sc->eeprom_voltage = letoh16(hdr.volt);
+               iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
+               sc->eeprom_temp = letoh16(val);
+               iwn_read_prom_data(sc, base + IWN2000_EEPROM_RAWTEMP, &val, 2);
+               sc->eeprom_rawtemp = letoh16(val);
+       }
+
        if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
                /* Compute temperature offset. */
                iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
@@ -2095,7 +2111,8 @@ iwn5000_rx_calib_results(struct iwn_soft
 
        switch (calib->code) {
        case IWN5000_PHY_CALIB_DC:
-               if (sc->hw_type == IWN_HW_REV_TYPE_5150)
+               if (sc->hw_type == IWN_HW_REV_TYPE_5150 ||
+                   sc->hw_type == IWN_HW_REV_TYPE_2030)
                        idx = 0;
                break;
        case IWN5000_PHY_CALIB_LO:
@@ -3822,7 +3839,7 @@ iwn5000_init_gains(struct iwn_softc *sc)
        struct iwn_phy_calib cmd;
 
        memset(&cmd, 0, sizeof cmd);
-       cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
+       cmd.code = sc->reset_noise_gain;
        cmd.ngroups = 1;
        cmd.isvalid = 1;
        DPRINTF(("setting initial differential gains\n"));
@@ -3872,7 +3889,7 @@ iwn5000_set_gains(struct iwn_softc *sc)
        div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30;
 
        memset(&cmd, 0, sizeof cmd);
-       cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
+       cmd.code = sc->noise_gain;
        cmd.ngroups = 1;
        cmd.isvalid = 1;
        /* Get first available RX antenna as referential. */
@@ -4160,29 +4177,55 @@ iwn_send_advanced_btcoex(struct iwn_soft
                0xcc00ff28, 0x0000aaaa, 0xcc00aaaa, 0x0000aaaa,
                0xc0004000, 0x00004000, 0xf0005000, 0xf0005000,
        };
-       struct iwn6000_btcoex_config btconfig;
        struct iwn_btcoex_priotable btprio;
        struct iwn_btcoex_prot btprot;
        int error, i;
 
-       memset(&btconfig, 0, sizeof btconfig);
-       btconfig.flags = IWN_BT_FLAG_COEX6000_CHAN_INHIBITION |
-           (IWN_BT_FLAG_COEX6000_MODE_3W << IWN_BT_FLAG_COEX6000_MODE_SHIFT) |
-           IWN_BT_FLAG_SYNC_2_BT_DISABLE;
-       btconfig.max_kill = 5;
-       btconfig.bt3_t7_timer = 1;
-       btconfig.kill_ack = htole32(0xffff0000);
-       btconfig.kill_cts = htole32(0xffff0000);
-       btconfig.sample_time = 2;
-       btconfig.bt3_t2_timer = 0xc;
-       for (i = 0; i < 12; i++)
-               btconfig.lookup_table[i] = htole32(btcoex_3wire[i]);
-       btconfig.valid = htole16(0xff);
-       btconfig.prio_boost = 0xf0;
-       DPRINTF(("configuring advanced bluetooth coexistence\n"));
-       error = iwn_cmd(sc, IWN_CMD_BT_COEX, &btconfig, sizeof(btconfig), 1);
-       if (error != 0)
-               return (error);
+       if (sc->hw_type == IWN_HW_REV_TYPE_2030) {
+               struct iwn2000_btcoex_config btconfig;
+
+               memset(&btconfig, 0, sizeof btconfig);
+               btconfig.flags = IWN_BT_COEX6000_CHAN_INHIBITION |
+                   (IWN_BT_COEX6000_MODE_3W << IWN_BT_COEX6000_MODE_SHIFT) |
+                   IWN_BT_SYNC_2_BT_DISABLE;
+               btconfig.max_kill = 5;
+               btconfig.bt3_t7_timer = 1;
+               btconfig.kill_ack = htole32(0xffff0000);
+               btconfig.kill_cts = htole32(0xffff0000);
+               btconfig.sample_time = 2;
+               btconfig.bt3_t2_timer = 0xc;
+               for (i = 0; i < 12; i++)
+                       btconfig.lookup_table[i] = htole32(btcoex_3wire[i]);
+               btconfig.valid = htole16(0xff);
+               btconfig.prio_boost = htole32(0xf0);
+               DPRINTF(("configuring advanced bluetooth coexistence\n"));
+               error = iwn_cmd(sc, IWN_CMD_BT_COEX, &btconfig,
+                   sizeof(btconfig), 1);
+               if (error != 0)
+                       return (error);
+       } else {
+               struct iwn6000_btcoex_config btconfig;
+
+               memset(&btconfig, 0, sizeof btconfig);
+               btconfig.flags = IWN_BT_COEX6000_CHAN_INHIBITION |
+                   (IWN_BT_COEX6000_MODE_3W << IWN_BT_COEX6000_MODE_SHIFT) |
+                   IWN_BT_SYNC_2_BT_DISABLE;
+               btconfig.max_kill = 5;
+               btconfig.bt3_t7_timer = 1;
+               btconfig.kill_ack = htole32(0xffff0000);
+               btconfig.kill_cts = htole32(0xffff0000);
+               btconfig.sample_time = 2;
+               btconfig.bt3_t2_timer = 0xc;
+               for (i = 0; i < 12; i++)
+                       btconfig.lookup_table[i] = htole32(btcoex_3wire[i]);
+               btconfig.valid = htole16(0xff);
+               btconfig.prio_boost = 0xf0;
+               DPRINTF(("configuring advanced bluetooth coexistence\n"));
+               error = iwn_cmd(sc, IWN_CMD_BT_COEX, &btconfig,
+                   sizeof(btconfig), 1);
+               if (error != 0)
+                       return (error);
+       }
 
        memset(&btprio, 0, sizeof btprio);
        btprio.calib_init1 = 0x6;
@@ -4233,9 +4276,16 @@ iwn_config(struct iwn_softc *sc)
        uint16_t rxchain;
        int error;
 
+       /* Set radio temperature sensor offset. */
        if (sc->hw_type == IWN_HW_REV_TYPE_6005) {
-               /* Set radio temperature sensor offset. */
-               error = iwn5000_temp_offset_calib(sc);
+               error = iwn6000_temp_offset_calib(sc);
+               if (error != 0) {
+                       printf("%s: could not set temperature offset\n",
+                           sc->sc_dev.dv_xname);
+                       return error;
+               }
+       } else if (sc->hw_type == IWN_HW_REV_TYPE_2030) {
+               error = iwn2000_temp_offset_calib(sc);
                if (error != 0) {
                        printf("%s: could not set temperature offset\n",
                            sc->sc_dev.dv_xname);
@@ -4989,12 +5039,12 @@ iwn5000_crystal_calib(struct iwn_softc *
 }
 
 int
-iwn5000_temp_offset_calib(struct iwn_softc *sc)
+iwn6000_temp_offset_calib(struct iwn_softc *sc)
 {
-       struct iwn5000_phy_calib_temp_offset cmd;
+       struct iwn6000_phy_calib_temp_offset cmd;
 
        memset(&cmd, 0, sizeof cmd);
-       cmd.code = IWN5000_PHY_CALIB_TEMP_OFFSET;
+       cmd.code = IWN6000_PHY_CALIB_TEMP_OFFSET;
        cmd.ngroups = 1;
        cmd.isvalid = 1;
        if (sc->eeprom_temp != 0)
@@ -5005,6 +5055,29 @@ iwn5000_temp_offset_calib(struct iwn_sof
        return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
 }
 
+int
+iwn2000_temp_offset_calib(struct iwn_softc *sc)
+{
+       struct iwn2000_phy_calib_temp_offset cmd;
+
+       memset(&cmd, 0, sizeof cmd);
+       cmd.code = IWN2000_PHY_CALIB_TEMP_OFFSET;
+       cmd.ngroups = 1;
+       cmd.isvalid = 1;
+       if (sc->eeprom_rawtemp != 0) {
+               cmd.offset_low = htole16(sc->eeprom_rawtemp);
+               cmd.offset_high = htole16(sc->eeprom_temp);
+       } else {
+               cmd.offset_low = htole16(IWN_DEFAULT_TEMP_OFFSET);
+               cmd.offset_high = htole16(IWN_DEFAULT_TEMP_OFFSET);
+       }
+       cmd.burnt_voltage_ref = htole16(sc->eeprom_voltage);
+       DPRINTF(("setting radio sensor offset to %d:%d, voltage to %d\n",
+           letoh16(cmd.offset_low), letoh16(cmd.offset_high),
+           letoh16(cmd.burnt_voltage_ref)));
+       return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
+}
+
 /*
  * This function is called after the runtime firmware notifies us of its
  * readiness (called in a process context).
@@ -5458,6 +5531,27 @@ iwn_read_firmware_tlv(struct iwn_softc *
                        fw->boot.text = ptr;
                        fw->boot.textsz = len;
                        break;
+               case IWN_FW_TLV_ENH_SENS:
+                       if (len !=  0) {
+                               printf("%s: TLV type %d has invalid size %u\n",
+                                   sc->sc_dev.dv_xname, letoh16(tlv->type),
+                                   len);
+                               goto next;
+                       }
+                       sc->sc_flags |= IWN_FLAG_ENH_SENS;
+                       break;
+               case IWN_FW_TLV_PHY_CALIB:
+                       if (len != sizeof(uint32_t)) {
+                               printf("%s: TLV type %d has invalid size %u\n",
+                                   sc->sc_dev.dv_xname, letoh16(tlv->type),
+                                   len);
+                               goto next;
+                       }
+                       if (letoh32(*ptr) <= IWN5000_PHY_CALIB_MAX) {
+                               sc->reset_noise_gain = letoh32(*ptr);
+                               sc->noise_gain = letoh32(*ptr) + 1;
+                       }
+                       break;
                default:
                        DPRINTF(("TLV type %d not handled\n",
                            letoh16(tlv->type)));
@@ -5475,6 +5569,14 @@ iwn_read_firmware(struct iwn_softc *sc)
        struct iwn_fw_info *fw = &sc->fw;
        int error;
 
+       /*
+        * Some PHY calibration commands are firmware-dependent; these
+        * are the default values that will be overridden if
+        * necessary.
+        */
+       sc->reset_noise_gain = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
+       sc->noise_gain = IWN5000_PHY_CALIB_NOISE_GAIN;
+
        memset(fw, 0, sizeof (*fw));
 
        /* Read firmware image from filesystem. */
@@ -5681,6 +5783,8 @@ iwn5000_nic_config(struct iwn_softc *sc)
        }
        if (sc->hw_type == IWN_HW_REV_TYPE_6005)
                IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_6050_1X2);
+       if (sc->hw_type == IWN_HW_REV_TYPE_2030)
+               IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_IQ_INVERT);
        return 0;
 }
 
Index: if_iwnreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwnreg.h,v
retrieving revision 1.45
diff -u -p -r1.45 if_iwnreg.h
--- if_iwnreg.h 26 Nov 2013 20:33:17 -0000      1.45
+++ if_iwnreg.h 9 Feb 2014 20:25:41 -0000
@@ -205,6 +205,7 @@
 #define IWN_HW_REV_TYPE_6000   7
 #define IWN_HW_REV_TYPE_6050   8
 #define IWN_HW_REV_TYPE_6005   11
+#define IWN_HW_REV_TYPE_2030   12
 
 /* Possible flags for register IWN_GIO_CHICKEN. */
 #define IWN_GIO_CHICKEN_L1A_NO_L0S_RX  (1 << 23)
@@ -219,6 +220,7 @@
 #define IWN_GP_DRIVER_RADIO_2X2_IPA    (2 << 0)
 #define IWN_GP_DRIVER_CALIB_VER6       (1 << 2)
 #define IWN_GP_DRIVER_6050_1X2         (1 << 3)
+#define IWN_GP_DRIVER_RADIO_IQ_INVERT  (1 << 7)
 
 /* Possible flags for register IWN_UCODE_GP1_CLR. */
 #define IWN_UCODE_GP1_RFKILL           (1 << 1)
@@ -852,15 +854,15 @@ struct iwn_bluetooth {
 
 struct iwn6000_btcoex_config {
        uint8_t         flags;
-#define        IWN_BT_FLAG_COEX6000_CHAN_INHIBITION    1
-#define        IWN_BT_FLAG_COEX6000_MODE_MASK          ((1 << 3) | (1 << 4) | 
(1 << 5))
-#define        IWN_BT_FLAG_COEX6000_MODE_SHIFT         3
-#define        IWN_BT_FLAG_COEX6000_MODE_DISABLED      0
-#define        IWN_BT_FLAG_COEX6000_MODE_LEGACY_2W     1
-#define        IWN_BT_FLAG_COEX6000_MODE_3W            2
-#define        IWN_BT_FLAG_COEX6000_MODE_4W            3
-#define        IWN_BT_FLAG_UCODE_DEFAULT               (1<<6)
-#define        IWN_BT_FLAG_SYNC_2_BT_DISABLE           (1<<7)
+#define        IWN_BT_COEX6000_CHAN_INHIBITION 1
+#define        IWN_BT_COEX6000_MODE_MASK       ((1 << 3) | (1 << 4) | (1 << 5))
+#define        IWN_BT_COEX6000_MODE_SHIFT      3
+#define        IWN_BT_COEX6000_MODE_DISABLED   0
+#define        IWN_BT_COEX6000_MODE_LEGACY_2W  1
+#define        IWN_BT_COEX6000_MODE_3W         2
+#define        IWN_BT_COEX6000_MODE_4W         3
+#define        IWN_BT_UCODE_DEFAULT            (1<<6)
+#define        IWN_BT_SYNC_2_BT_DISABLE        (1<<7)
 
        uint8_t         lead_time;
        uint8_t         max_kill;
@@ -878,6 +880,25 @@ struct iwn6000_btcoex_config {
        uint16_t        rx_prio_boost;
 } __packed;
 
+struct iwn2000_btcoex_config {
+       uint8_t         flags;          /* same as in iwn6000_btcoex_config */
+       uint8_t         lead_time;
+       uint8_t         max_kill;
+       uint8_t         bt3_t7_timer;
+       uint32_t        kill_ack;
+       uint32_t        kill_cts;
+       uint8_t         sample_time;
+       uint8_t         bt3_t2_timer;
+       uint16_t        bt4_reaction;
+       uint32_t        lookup_table[12];
+       uint16_t        bt4_decision;
+       uint16_t        valid;
+       uint32_t        prio_boost;
+       uint8_t         reserved;
+       uint8_t         tx_prio_boost;
+       uint16_t        rx_prio_boost;
+} __packed;
+
 /* Structure for command IWN_CMD_BT_COEX_PRIOTABLE */
 struct iwn_btcoex_priotable {
        uint8_t         calib_init1;
@@ -967,11 +988,14 @@ struct iwn_phy_calib {
 #define IWN5000_PHY_CALIB_CRYSTAL              15
 #define IWN5000_PHY_CALIB_BASE_BAND            16
 #define IWN5000_PHY_CALIB_TX_IQ_PERIODIC       17
-#define IWN5000_PHY_CALIB_TEMP_OFFSET          18
-
 #define IWN5000_PHY_CALIB_RESET_NOISE_GAIN     18
 #define IWN5000_PHY_CALIB_NOISE_GAIN           19
 
+#define IWN6000_PHY_CALIB_TEMP_OFFSET          18
+#define IWN2000_PHY_CALIB_TEMP_OFFSET          18
+
+#define IWN5000_PHY_CALIB_MAX                  253
+
        uint8_t group;
        uint8_t ngroups;
        uint8_t isvalid;
@@ -987,7 +1011,7 @@ struct iwn5000_phy_calib_crystal {
        uint8_t reserved[2];
 } __packed;
 
-struct iwn5000_phy_calib_temp_offset {
+struct iwn6000_phy_calib_temp_offset {
        uint8_t         code;
        uint8_t         group;
        uint8_t         ngroups;
@@ -998,6 +1022,17 @@ struct iwn5000_phy_calib_temp_offset {
        uint16_t        reserved;
 } __packed;
 
+struct iwn2000_phy_calib_temp_offset {
+       uint8_t         code;
+       uint8_t         group;
+       uint8_t         ngroups;
+       uint8_t         isvalid;
+       int16_t         offset_high;
+       int16_t         offset_low;
+       int16_t         burnt_voltage_ref;
+       int16_t         reserved;
+} __packed;
+
 struct iwn_phy_calib_gain {
        uint8_t code;
        uint8_t group;
@@ -1366,6 +1401,8 @@ struct iwn_fw_tlv {
 #define IWN_FW_TLV_INIT_DATA           4
 #define IWN_FW_TLV_BOOT_TEXT           5
 #define IWN_FW_TLV_PBREQ_MAXLEN                6
+#define IWN_FW_TLV_ENH_SENS            14
+#define IWN_FW_TLV_PHY_CALIB           15
 
        uint16_t        alt;
        uint32_t        len;
@@ -1411,6 +1448,7 @@ struct iwn_fw_tlv {
 #define IWN5000_EEPROM_CRYSTAL 0x128
 #define IWN5000_EEPROM_TEMP    0x12a
 #define IWN5000_EEPROM_VOLT    0x12b
+#define IWN2000_EEPROM_RAWTEMP 0x12b
 
 /* Possible flags for IWN_EEPROM_SKU_CAP. */
 #define IWN_EEPROM_SKU_CAP_11N (1 << 6)
@@ -1708,6 +1746,18 @@ static const struct iwn_sensitivity_limi
 };
 
 static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = {
+       105, 110,
+       192, 232,
+        80, 145,
+       128, 232,
+       125, 175,
+       160, 310,
+        97,
+        97,
+       100
+};
+
+static const struct iwn_sensitivity_limits iwn2000_sensitivity_limits = {
        105, 110,
        192, 232,
         80, 145,
Index: if_iwnvar.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwnvar.h,v
retrieving revision 1.26
diff -u -p -r1.26 if_iwnvar.h
--- if_iwnvar.h 30 Nov 2013 19:41:21 -0000      1.26
+++ if_iwnvar.h 9 Feb 2014 20:25:41 -0000
@@ -275,10 +275,14 @@ struct iwn_softc {
        uint32_t                eeprom_crystal;
        int16_t                 eeprom_temp;
        int16_t                 eeprom_voltage;
+       int16_t                 eeprom_rawtemp;
        int8_t                  maxpwr2GHz;
        int8_t                  maxpwr5GHz;
        int8_t                  maxpwr[IEEE80211_CHAN_MAX];
        int8_t                  enh_maxpwr[35];
+
+       uint8_t                 reset_noise_gain;
+       uint8_t                 noise_gain;
 
        int32_t                 temp_off;
        uint32_t                int_mask;

Reply via email to