if_iwm.c (267c626f0db9973967488b4b1f6aa3fe328ce47b) if_iwm.c (3bf2d5dd64862cae43545bfcc11323844091bf66)
1/* $OpenBSD: if_iwm.c,v 1.167 2017/04/04 00:40:52 claudio Exp $ */
2
3/*
4 * Copyright (c) 2014 genua mbh <info@genua.de>
5 * Copyright (c) 2014 Fixup Software Ltd.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above

--- 1637 unchanged lines hidden (view full) ---

1646 }
1647
1648 IWM_SETBITS(sc, IWM_FH_TX_CHICKEN_BITS_REG,
1649 IWM_FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
1650
1651 iwm_nic_unlock(sc);
1652
1653 /* Enable L1-Active */
1/* $OpenBSD: if_iwm.c,v 1.167 2017/04/04 00:40:52 claudio Exp $ */
2
3/*
4 * Copyright (c) 2014 genua mbh <info@genua.de>
5 * Copyright (c) 2014 Fixup Software Ltd.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above

--- 1637 unchanged lines hidden (view full) ---

1646 }
1647
1648 IWM_SETBITS(sc, IWM_FH_TX_CHICKEN_BITS_REG,
1649 IWM_FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
1650
1651 iwm_nic_unlock(sc);
1652
1653 /* Enable L1-Active */
1654 if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) {
1654 if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) {
1655 iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
1656 IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1657 }
1658
1659 return error;
1660}
1661
1662/*

--- 401 unchanged lines hidden (view full) ---

2064 device_printf(sc->sc_dev, "%s: mac address not found\n", __func__);
2065 memset(data->hw_addr, 0, sizeof(data->hw_addr));
2066}
2067
2068static int
2069iwm_get_sku(const struct iwm_softc *sc, const uint16_t *nvm_sw,
2070 const uint16_t *phy_sku)
2071{
1655 iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
1656 IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
1657 }
1658
1659 return error;
1660}
1661
1662/*

--- 401 unchanged lines hidden (view full) ---

2064 device_printf(sc->sc_dev, "%s: mac address not found\n", __func__);
2065 memset(data->hw_addr, 0, sizeof(data->hw_addr));
2066}
2067
2068static int
2069iwm_get_sku(const struct iwm_softc *sc, const uint16_t *nvm_sw,
2070 const uint16_t *phy_sku)
2071{
2072 if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000)
2072 if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000)
2073 return le16_to_cpup(nvm_sw + IWM_SKU);
2074
2075 return le32_to_cpup((const uint32_t *)(phy_sku + IWM_SKU_8000));
2076}
2077
2078static int
2079iwm_get_nvm_version(const struct iwm_softc *sc, const uint16_t *nvm_sw)
2080{
2073 return le16_to_cpup(nvm_sw + IWM_SKU);
2074
2075 return le32_to_cpup((const uint32_t *)(phy_sku + IWM_SKU_8000));
2076}
2077
2078static int
2079iwm_get_nvm_version(const struct iwm_softc *sc, const uint16_t *nvm_sw)
2080{
2081 if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000)
2081 if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000)
2082 return le16_to_cpup(nvm_sw + IWM_NVM_VERSION);
2083 else
2084 return le32_to_cpup((const uint32_t *)(nvm_sw +
2085 IWM_NVM_VERSION_8000));
2086}
2087
2088static int
2089iwm_get_radio_cfg(const struct iwm_softc *sc, const uint16_t *nvm_sw,
2090 const uint16_t *phy_sku)
2091{
2082 return le16_to_cpup(nvm_sw + IWM_NVM_VERSION);
2083 else
2084 return le32_to_cpup((const uint32_t *)(nvm_sw +
2085 IWM_NVM_VERSION_8000));
2086}
2087
2088static int
2089iwm_get_radio_cfg(const struct iwm_softc *sc, const uint16_t *nvm_sw,
2090 const uint16_t *phy_sku)
2091{
2092 if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000)
2092 if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000)
2093 return le16_to_cpup(nvm_sw + IWM_RADIO_CFG);
2094
2095 return le32_to_cpup((const uint32_t *)(phy_sku + IWM_RADIO_CFG_8000));
2096}
2097
2098static int
2099iwm_get_n_hw_addrs(const struct iwm_softc *sc, const uint16_t *nvm_sw)
2100{
2101 int n_hw_addr;
2102
2093 return le16_to_cpup(nvm_sw + IWM_RADIO_CFG);
2094
2095 return le32_to_cpup((const uint32_t *)(phy_sku + IWM_RADIO_CFG_8000));
2096}
2097
2098static int
2099iwm_get_n_hw_addrs(const struct iwm_softc *sc, const uint16_t *nvm_sw)
2100{
2101 int n_hw_addr;
2102
2103 if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000)
2103 if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000)
2104 return le16_to_cpup(nvm_sw + IWM_N_HW_ADDRS);
2105
2106 n_hw_addr = le32_to_cpup((const uint32_t *)(nvm_sw + IWM_N_HW_ADDRS_8000));
2107
2108 return n_hw_addr & IWM_N_HW_ADDR_MASK;
2109}
2110
2111static void
2112iwm_set_radio_cfg(const struct iwm_softc *sc, struct iwm_nvm_data *data,
2113 uint32_t radio_cfg)
2114{
2104 return le16_to_cpup(nvm_sw + IWM_N_HW_ADDRS);
2105
2106 n_hw_addr = le32_to_cpup((const uint32_t *)(nvm_sw + IWM_N_HW_ADDRS_8000));
2107
2108 return n_hw_addr & IWM_N_HW_ADDR_MASK;
2109}
2110
2111static void
2112iwm_set_radio_cfg(const struct iwm_softc *sc, struct iwm_nvm_data *data,
2113 uint32_t radio_cfg)
2114{
2115 if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) {
2115 if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) {
2116 data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg);
2117 data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK(radio_cfg);
2118 data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg);
2119 data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK(radio_cfg);
2120 return;
2121 }
2122
2123 /* set the radio configuration for family 8000 */

--- 9 unchanged lines hidden (view full) ---

2133iwm_set_hw_address(struct iwm_softc *sc, struct iwm_nvm_data *data,
2134 const uint16_t *nvm_hw, const uint16_t *mac_override)
2135{
2136#ifdef notyet /* for FAMILY 9000 */
2137 if (cfg->mac_addr_from_csr) {
2138 iwm_set_hw_address_from_csr(sc, data);
2139 } else
2140#endif
2116 data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg);
2117 data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK(radio_cfg);
2118 data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg);
2119 data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK(radio_cfg);
2120 return;
2121 }
2122
2123 /* set the radio configuration for family 8000 */

--- 9 unchanged lines hidden (view full) ---

2133iwm_set_hw_address(struct iwm_softc *sc, struct iwm_nvm_data *data,
2134 const uint16_t *nvm_hw, const uint16_t *mac_override)
2135{
2136#ifdef notyet /* for FAMILY 9000 */
2137 if (cfg->mac_addr_from_csr) {
2138 iwm_set_hw_address_from_csr(sc, data);
2139 } else
2140#endif
2141 if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) {
2141 if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) {
2142 const uint8_t *hw_addr = (const uint8_t *)(nvm_hw + IWM_HW_ADDR);
2143
2144 /* The byte order is little endian 16 bit, meaning 214365 */
2145 data->hw_addr[0] = hw_addr[1];
2146 data->hw_addr[1] = hw_addr[0];
2147 data->hw_addr[2] = hw_addr[3];
2148 data->hw_addr[3] = hw_addr[2];
2149 data->hw_addr[4] = hw_addr[5];

--- 15 unchanged lines hidden (view full) ---

2165 const uint16_t *nvm_hw, const uint16_t *nvm_sw,
2166 const uint16_t *nvm_calib, const uint16_t *mac_override,
2167 const uint16_t *phy_sku, const uint16_t *regulatory)
2168{
2169 struct iwm_nvm_data *data;
2170 uint32_t sku, radio_cfg;
2171 uint16_t lar_config;
2172
2142 const uint8_t *hw_addr = (const uint8_t *)(nvm_hw + IWM_HW_ADDR);
2143
2144 /* The byte order is little endian 16 bit, meaning 214365 */
2145 data->hw_addr[0] = hw_addr[1];
2146 data->hw_addr[1] = hw_addr[0];
2147 data->hw_addr[2] = hw_addr[3];
2148 data->hw_addr[3] = hw_addr[2];
2149 data->hw_addr[4] = hw_addr[5];

--- 15 unchanged lines hidden (view full) ---

2165 const uint16_t *nvm_hw, const uint16_t *nvm_sw,
2166 const uint16_t *nvm_calib, const uint16_t *mac_override,
2167 const uint16_t *phy_sku, const uint16_t *regulatory)
2168{
2169 struct iwm_nvm_data *data;
2170 uint32_t sku, radio_cfg;
2171 uint16_t lar_config;
2172
2173 if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) {
2173 if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) {
2174 data = malloc(sizeof(*data) +
2175 IWM_NUM_CHANNELS * sizeof(uint16_t),
2176 M_DEVBUF, M_NOWAIT | M_ZERO);
2177 } else {
2178 data = malloc(sizeof(*data) +
2179 IWM_NUM_CHANNELS_8000 * sizeof(uint16_t),
2180 M_DEVBUF, M_NOWAIT | M_ZERO);
2181 }

--- 7 unchanged lines hidden (view full) ---

2189
2190 sku = iwm_get_sku(sc, nvm_sw, phy_sku);
2191 data->sku_cap_band_24GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_24GHZ;
2192 data->sku_cap_band_52GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_52GHZ;
2193 data->sku_cap_11n_enable = 0;
2194
2195 data->n_hw_addrs = iwm_get_n_hw_addrs(sc, nvm_sw);
2196
2174 data = malloc(sizeof(*data) +
2175 IWM_NUM_CHANNELS * sizeof(uint16_t),
2176 M_DEVBUF, M_NOWAIT | M_ZERO);
2177 } else {
2178 data = malloc(sizeof(*data) +
2179 IWM_NUM_CHANNELS_8000 * sizeof(uint16_t),
2180 M_DEVBUF, M_NOWAIT | M_ZERO);
2181 }

--- 7 unchanged lines hidden (view full) ---

2189
2190 sku = iwm_get_sku(sc, nvm_sw, phy_sku);
2191 data->sku_cap_band_24GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_24GHZ;
2192 data->sku_cap_band_52GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_52GHZ;
2193 data->sku_cap_11n_enable = 0;
2194
2195 data->n_hw_addrs = iwm_get_n_hw_addrs(sc, nvm_sw);
2196
2197 if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
2197 if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) {
2198 /* TODO: use IWL_NVM_EXT */
2198 uint16_t lar_offset = data->nvm_version < 0xE39 ?
2199 IWM_NVM_LAR_OFFSET_8000_OLD :
2200 IWM_NVM_LAR_OFFSET_8000;
2201
2202 lar_config = le16_to_cpup(regulatory + lar_offset);
2203 data->lar_enabled = !!(lar_config &
2204 IWM_NVM_LAR_ENABLED_8000);
2205 }

--- 31 unchanged lines hidden (view full) ---

2237 /* Checking for required sections */
2238 if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) {
2239 if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
2240 !sections[sc->cfg->nvm_hw_section_num].data) {
2241 device_printf(sc->sc_dev,
2242 "Can't parse empty OTP/NVM sections\n");
2243 return NULL;
2244 }
2199 uint16_t lar_offset = data->nvm_version < 0xE39 ?
2200 IWM_NVM_LAR_OFFSET_8000_OLD :
2201 IWM_NVM_LAR_OFFSET_8000;
2202
2203 lar_config = le16_to_cpup(regulatory + lar_offset);
2204 data->lar_enabled = !!(lar_config &
2205 IWM_NVM_LAR_ENABLED_8000);
2206 }

--- 31 unchanged lines hidden (view full) ---

2238 /* Checking for required sections */
2239 if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) {
2240 if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
2241 !sections[sc->cfg->nvm_hw_section_num].data) {
2242 device_printf(sc->sc_dev,
2243 "Can't parse empty OTP/NVM sections\n");
2244 return NULL;
2245 }
2245 } else if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
2246 } else if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) {
2246 /* SW and REGULATORY sections are mandatory */
2247 if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
2248 !sections[IWM_NVM_SECTION_TYPE_REGULATORY].data) {
2249 device_printf(sc->sc_dev,
2250 "Can't parse empty OTP/NVM sections\n");
2251 return NULL;
2252 }
2253 /* MAC_OVERRIDE or at least HW section must exist */

--- 413 unchanged lines hidden (view full) ---

2667 iwm_enable_fw_load_int(sc);
2668
2669 /* really make sure rfkill handshake bits are cleared */
2670 /* maybe we should write a few times more? just to make sure */
2671 IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
2672 IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
2673
2674 /* Load the given image to the HW */
2247 /* SW and REGULATORY sections are mandatory */
2248 if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
2249 !sections[IWM_NVM_SECTION_TYPE_REGULATORY].data) {
2250 device_printf(sc->sc_dev,
2251 "Can't parse empty OTP/NVM sections\n");
2252 return NULL;
2253 }
2254 /* MAC_OVERRIDE or at least HW section must exist */

--- 413 unchanged lines hidden (view full) ---

2668 iwm_enable_fw_load_int(sc);
2669
2670 /* really make sure rfkill handshake bits are cleared */
2671 /* maybe we should write a few times more? just to make sure */
2672 IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
2673 IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
2674
2675 /* Load the given image to the HW */
2675 if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000)
2676 if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000)
2676 ret = iwm_pcie_load_given_ucode_8000(sc, fw);
2677 else
2678 ret = iwm_pcie_load_given_ucode(sc, fw);
2679
2680 /* XXX re-check RF-Kill state */
2681
2682out:
2683 return ret;

--- 134 unchanged lines hidden (view full) ---

2818 * Some things may run in the background now, but we
2819 * just wait for the ALIVE notification here.
2820 */
2821 IWM_UNLOCK(sc);
2822 error = iwm_wait_notification(sc->sc_notif_wait, &alive_wait,
2823 IWM_MVM_UCODE_ALIVE_TIMEOUT);
2824 IWM_LOCK(sc);
2825 if (error) {
2677 ret = iwm_pcie_load_given_ucode_8000(sc, fw);
2678 else
2679 ret = iwm_pcie_load_given_ucode(sc, fw);
2680
2681 /* XXX re-check RF-Kill state */
2682
2683out:
2684 return ret;

--- 134 unchanged lines hidden (view full) ---

2819 * Some things may run in the background now, but we
2820 * just wait for the ALIVE notification here.
2821 */
2822 IWM_UNLOCK(sc);
2823 error = iwm_wait_notification(sc->sc_notif_wait, &alive_wait,
2824 IWM_MVM_UCODE_ALIVE_TIMEOUT);
2825 IWM_LOCK(sc);
2826 if (error) {
2826 if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
2827 if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) {
2827 uint32_t a = 0x5a5a5a5a, b = 0x5a5a5a5a;
2828 if (iwm_nic_lock(sc)) {
2829 a = iwm_read_prph(sc, IWM_SB_CPU_1_STATUS);
2830 b = iwm_read_prph(sc, IWM_SB_CPU_2_STATUS);
2831 iwm_nic_unlock(sc);
2832 }
2833 device_printf(sc->sc_dev,
2834 "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",

--- 1618 unchanged lines hidden (view full) ---

4453
4454 if (iwm_lar_disable)
4455 return FALSE;
4456
4457 /*
4458 * Enable LAR only if it is supported by the FW (TLV) &&
4459 * enabled in the NVM
4460 */
2828 uint32_t a = 0x5a5a5a5a, b = 0x5a5a5a5a;
2829 if (iwm_nic_lock(sc)) {
2830 a = iwm_read_prph(sc, IWM_SB_CPU_1_STATUS);
2831 b = iwm_read_prph(sc, IWM_SB_CPU_2_STATUS);
2832 iwm_nic_unlock(sc);
2833 }
2834 device_printf(sc->sc_dev,
2835 "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",

--- 1618 unchanged lines hidden (view full) ---

4454
4455 if (iwm_lar_disable)
4456 return FALSE;
4457
4458 /*
4459 * Enable LAR only if it is supported by the FW (TLV) &&
4460 * enabled in the NVM
4461 */
4461 if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000)
4462 if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000)
4462 return nvm_lar && tlv_lar;
4463 else
4464 return tlv_lar;
4465}
4466
4467static boolean_t
4468iwm_mvm_is_wifi_mcc_supported(struct iwm_softc *sc)
4469{

--- 1327 unchanged lines hidden (view full) ---

5797
5798 sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV);
5799 /*
5800 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
5801 * changed, and now the revision step also includes bit 0-1 (no more
5802 * "dash" value). To keep hw_rev backwards compatible - we'll store it
5803 * in the old format.
5804 */
4463 return nvm_lar && tlv_lar;
4464 else
4465 return tlv_lar;
4466}
4467
4468static boolean_t
4469iwm_mvm_is_wifi_mcc_supported(struct iwm_softc *sc)
4470{

--- 1327 unchanged lines hidden (view full) ---

5798
5799 sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV);
5800 /*
5801 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
5802 * changed, and now the revision step also includes bit 0-1 (no more
5803 * "dash" value). To keep hw_rev backwards compatible - we'll store it
5804 * in the old format.
5805 */
5805 if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) {
5806 if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) {
5806 int ret;
5807 uint32_t hw_step;
5808
5809 sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) |
5810 (IWM_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2);
5811
5812 if (iwm_prepare_card_hw(sc) != 0) {
5813 device_printf(dev, "could not initialize hardware\n");

--- 598 unchanged lines hidden ---
5807 int ret;
5808 uint32_t hw_step;
5809
5810 sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) |
5811 (IWM_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2);
5812
5813 if (iwm_prepare_card_hw(sc) != 0) {
5814 device_printf(dev, "could not initialize hardware\n");

--- 598 unchanged lines hidden ---