diff options
| author | Dan MacDonald <allcoms@gmail.com> | 2015-04-28 11:12:56 +0000 |
|---|---|---|
| committer | Adrien Destugues <pulkomandy@gmail.com> | 2015-04-28 20:49:46 +0200 |
| commit | 1894a24358be3f11916c06eddaaea1a2d68bc14a (patch) | |
| tree | f255238f7613b1d3a5c97c6fb470e56b001c94df | |
| parent | 5de22b9bf661cdf4c5864e3d5772b601771e7f44 (diff) | |
Add support for Intel Centrino Wireless-N 2230.hrev49127
Fixes #12006.
Signed-off-by: Adrien Destugues <pulkomandy@gmail.com>
5 files changed, 155 insertions, 30 deletions
diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/Jamfile b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/Jamfile index 6c26afb671..bee6f0662b 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/Jamfile @@ -25,12 +25,14 @@ KernelAddon iprowifi4965 : ; HAIKU_WIFI_FIRMWARE_PACKAGES on iprowifi4965 = - iwlwifi-1000-ucode-39.31.5.1 iwlwifi-4965-ucode-228.61.2.24 + iwlwifi-1000-ucode-39.31.5.1 + iwlwifi-2030-ucode-18.168.6.1 iwlwifi-4965-ucode-228.61.2.24 iwlwifi-5000-ucode-8.83.5.1 iwlwifi-5150-ucode-8.24.2.2 iwlwifi-6000-ucode-9.221.4.1 iwlwifi-6000g2a-ucode-18.168.6.1 iwlwifi-6000g2b-ucode-18.168.6.1 iwlwifi-6050-ucode-41.28.5.1 ; HAIKU_WIFI_FIRMWARE_ARCHIVES on iprowifi4965 = - iwlwifi-1000-ucode-39.31.5.1.tgz iwlwifi-4965-ucode-228.61.2.24.tgz + iwlwifi-1000-ucode-39.31.5.1.tgz + iwlwifi-2030-ucode-18.168.6.1.tgz iwlwifi-4965-ucode-228.61.2.24.tgz iwlwifi-5000-ucode-8.83.5.1.tgz iwlwifi-5150-ucode-8.24.2.2.tgz iwlwifi-6000-ucode-9.221.4.1.tgz iwlwifi-6000g2a-ucode-18.168.6.1.tgz iwlwifi-6000g2b-ucode-18.168.6.1.tgz iwlwifi-6050-ucode-41.28.5.1.tgz ; diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c index 8cd5a48064..255cc6eaa1 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c @@ -284,7 +284,8 @@ static int iwn5000_query_calibration(struct iwn_softc *); static int iwn5000_send_calibration(struct iwn_softc *); static int iwn5000_send_wimax_coex(struct iwn_softc *); static int iwn5000_crystal_calib(struct iwn_softc *); -static int iwn5000_temp_offset_calib(struct iwn_softc *); +static int iwn6000_temp_offset_calib(struct iwn_softc *); +static int iwn2000_temp_offset_calib(struct iwn_softc *); static int iwn4965_post_alive(struct iwn_softc *); static int iwn5000_post_alive(struct iwn_softc *); static int iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *, @@ -806,6 +807,11 @@ iwn5000_attach(struct iwn_softc *sc, uint16_t pid) } else sc->fwname = "iwn6000g2afw"; break; + case IWN_HW_REV_TYPE_2030: + sc->limits = &iwn2000_sensitivity_limits; + sc->fwname = "iwn2030fw"; + sc->sc_flags |= IWN_FLAG_ADV_BTCOEX; + break; default: device_printf(sc->sc_dev, "adapter type %d not supported\n", sc->hw_type); @@ -1774,6 +1780,14 @@ iwn5000_read_eeprom(struct iwn_softc *sc) hdr.version, hdr.pa_type, le16toh(hdr.volt)); sc->calib_ver = hdr.version; + if (sc->hw_type == IWN_HW_REV_TYPE_2030) { + sc->eeprom_voltage = htole16(hdr.volt); + iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2); + sc->eeprom_temp = htole16(val); + iwn_read_prom_data(sc, base + IWN2000_EEPROM_RAWTEMP, &val, 2); + sc->eeprom_rawtemp = htole16(val); + } + if (sc->hw_type == IWN_HW_REV_TYPE_5150) { /* Compute temperature offset. */ iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2); @@ -5002,28 +5016,55 @@ iwn_send_advanced_btcoex(struct iwn_softc *sc) 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 = 145; - 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(sc, IWN_DEBUG_RESET, - "%s: configuring advanced bluetooth coexistence\n", __func__); - 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 = 145; + 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(sc, IWN_DEBUG_RESET, + "%s: configuring advanced bluetooth coexistence\n", + __func__); + 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 = 145; + 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(sc, IWN_DEBUG_RESET, + "%s: configuring advanced bluetooth coexistence\n", + __func__); + 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; @@ -5074,9 +5115,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) { + device_printf(sc->sc_dev, + "%s: could not set temperature offset\n", __func__); + return error; + } + } else if (sc->hw_type == IWN_HW_REV_TYPE_2030) { + error = iwn2000_temp_offset_calib(sc); if (error != 0) { device_printf(sc->sc_dev, "%s: could not set temperature offset\n", __func__); @@ -5943,12 +5991,12 @@ iwn5000_crystal_calib(struct iwn_softc *sc) } static 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) @@ -5960,6 +6008,31 @@ iwn5000_temp_offset_calib(struct iwn_softc *sc) return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0); } +static 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(sc, IWN_DEBUG_CALIBRATE, + "setting radio sensor offset to %d:%d, voltage to %d\n", + htole16(cmd.offset_low), htole16(cmd.offset_high), + htole16(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). @@ -6663,6 +6736,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; } diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h index 9aa0d6606a..6791defc3d 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h @@ -206,6 +206,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) @@ -220,6 +221,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) @@ -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; + struct iwn_btcoex_priotable { uint8_t calib_init1; uint8_t calib_init2; @@ -965,11 +986,12 @@ 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 + uint8_t group; uint8_t ngroups; uint8_t isvalid; @@ -985,7 +1007,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; @@ -996,6 +1018,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; @@ -1414,6 +1447,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) @@ -1722,6 +1756,18 @@ static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = { 100 }; +static const struct iwn_sensitivity_limits iwn2000_sensitivity_limits = { + 105, 110, + 192, 232, + 80, 145, + 128, 232, + 125, 175, + 160, 310, + 97, + 97, + 100 +}; + /* Map TID to TX scheduler's FIFO. */ static const uint8_t iwn_tid2fifo[] = { 1, 0, 0, 1, 2, 2, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 3 diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h index 7647b09b0e..932aaafec7 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h @@ -295,6 +295,7 @@ 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]; diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/glue.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/glue.c index 198bece21c..cf23a6d04a 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/glue.c +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/glue.c @@ -24,8 +24,9 @@ NO_HAIKU_FBSD_MII_DRIVER(); NO_HAIKU_REENABLE_INTERRUPTS(); HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_WLAN); HAIKU_FIRMWARE_VERSION(44417); -HAIKU_FIRMWARE_NAME_MAP(8) = { +HAIKU_FIRMWARE_NAME_MAP(9) = { {"iwn1000fw", "iwlwifi-1000-5.ucode"}, + {"iwn2030fw", "iwlwifi-2030-6.ucode"}, {"iwn4965fw", "iwlwifi-4965-2.ucode"}, {"iwn5000fw", "iwlwifi-5000-5.ucode"}, {"iwn5150fw", "iwlwifi-5150-2.ucode"}, |
