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 --- |