On 02/09/14 21:32, Mark Kettenis wrote:
>> Date: Sun, 9 Feb 2014 14:23:18 +0100
>> From: Fabian Raetz <[email protected]>
>>>
>>> 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.
>
ok for me, works fine !
>
> 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;
>