Date: Thu, 1 Mar 2018 06:47:52 +0000 (UTC) From: Eitan Adler <eadler@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r330217 - stable/11/sys/dev/iwm Message-ID: <201803010647.w216lqrx064000@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: eadler Date: Thu Mar 1 06:47:52 2018 New Revision: 330217 URL: https://svnweb.freebsd.org/changeset/base/330217 Log: MFC r319578: [iwm] Check for lar_disable tunable, and lar_enabled flag from NVM. * LAR can be disabled with the hw.iwm.lar.disable tunable now. * On Family 8000 devices we need to check the lar_enabled flag from nvm_data in addition to the TLV_CAPA_LAR_SUPPORT flag from the firmware. * Add a separate IWM_DEBUG_LAR debugging flag. Modified: stable/11/sys/dev/iwm/if_iwm.c stable/11/sys/dev/iwm/if_iwm_debug.h stable/11/sys/dev/iwm/if_iwmvar.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/iwm/if_iwm.c ============================================================================== --- stable/11/sys/dev/iwm/if_iwm.c Thu Mar 1 06:46:56 2018 (r330216) +++ stable/11/sys/dev/iwm/if_iwm.c Thu Mar 1 06:47:52 2018 (r330217) @@ -359,6 +359,8 @@ static void iwm_mvm_fill_sf_command(struct iwm_softc * struct ieee80211_node *); static int iwm_mvm_sf_config(struct iwm_softc *, enum iwm_sf_state); static int iwm_send_bt_init_conf(struct iwm_softc *); +static boolean_t iwm_mvm_is_lar_supported(struct iwm_softc *); +static boolean_t iwm_mvm_is_wifi_mcc_supported(struct iwm_softc *); static int iwm_send_update_mcc_cmd(struct iwm_softc *, const char *); static void iwm_mvm_tt_tx_backoff(struct iwm_softc *, uint32_t); static int iwm_init_hw(struct iwm_softc *); @@ -397,6 +399,9 @@ static void iwm_scan_curchan(struct ieee80211_scan_sta static void iwm_scan_mindwell(struct ieee80211_scan_state *); static int iwm_detach(device_t); +static int iwm_lar_disable = 0; +TUNABLE_INT("hw.iwm.lar.disable", &iwm_lar_disable); + /* * Firmware parser. */ @@ -2189,6 +2194,7 @@ iwm_parse_nvm_data(struct iwm_softc *sc, { struct iwm_nvm_data *data; uint32_t sku, radio_cfg; + uint16_t lar_config; if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) { data = malloc(sizeof(*data) + @@ -2214,6 +2220,16 @@ iwm_parse_nvm_data(struct iwm_softc *sc, data->n_hw_addrs = iwm_get_n_hw_addrs(sc, nvm_sw); + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) { + uint16_t lar_offset = data->nvm_version < 0xE39 ? + IWM_NVM_LAR_OFFSET_8000_OLD : + IWM_NVM_LAR_OFFSET_8000; + + lar_config = le16_to_cpup(regulatory + lar_offset); + data->lar_enabled = !!(lar_config & + IWM_NVM_LAR_ENABLED_8000); + } + /* If no valid mac address was found - bail out */ if (iwm_set_hw_address(sc, data, nvm_hw, mac_override)) { free(data, M_DEVBUF); @@ -4661,6 +4677,35 @@ iwm_send_bt_init_conf(struct iwm_softc *sc) &bt_cmd); } +static boolean_t +iwm_mvm_is_lar_supported(struct iwm_softc *sc) +{ + boolean_t nvm_lar = sc->nvm_data->lar_enabled; + boolean_t tlv_lar = fw_has_capa(&sc->ucode_capa, + IWM_UCODE_TLV_CAPA_LAR_SUPPORT); + + if (iwm_lar_disable) + return FALSE; + + /* + * Enable LAR only if it is supported by the FW (TLV) && + * enabled in the NVM + */ + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) + return nvm_lar && tlv_lar; + else + return tlv_lar; +} + +static boolean_t +iwm_mvm_is_wifi_mcc_supported(struct iwm_softc *sc) +{ + return fw_has_api(&sc->ucode_capa, + IWM_UCODE_TLV_API_WIFI_MCC_UPDATE) || + fw_has_capa(&sc->ucode_capa, + IWM_UCODE_TLV_CAPA_LAR_MULTI_MCC); +} + static int iwm_send_update_mcc_cmd(struct iwm_softc *sc, const char *alpha2) { @@ -4681,10 +4726,15 @@ iwm_send_update_mcc_cmd(struct iwm_softc *sc, const ch int resp_v2 = fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_LAR_SUPPORT_V2); + if (!iwm_mvm_is_lar_supported(sc)) { + IWM_DPRINTF(sc, IWM_DEBUG_LAR, "%s: no LAR support\n", + __func__); + return 0; + } + memset(&mcc_cmd, 0, sizeof(mcc_cmd)); mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]); - if (fw_has_api(&sc->ucode_capa, IWM_UCODE_TLV_API_WIFI_MCC_UPDATE) || - fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_LAR_MULTI_MCC)) + if (iwm_mvm_is_wifi_mcc_supported(sc)) mcc_cmd.source_id = IWM_MCC_SOURCE_GET_CURRENT; else mcc_cmd.source_id = IWM_MCC_SOURCE_OLD_FW; @@ -4694,7 +4744,7 @@ iwm_send_update_mcc_cmd(struct iwm_softc *sc, const ch else hcmd.len[0] = sizeof(struct iwm_mcc_update_cmd_v1); - IWM_DPRINTF(sc, IWM_DEBUG_NODE, + IWM_DPRINTF(sc, IWM_DEBUG_LAR, "send MCC update to FW with '%c%c' src = %d\n", alpha2[0], alpha2[1], mcc_cmd.source_id); @@ -4720,7 +4770,7 @@ iwm_send_update_mcc_cmd(struct iwm_softc *sc, const ch if (mcc == 0) mcc = 0x3030; /* "00" - world */ - IWM_DPRINTF(sc, IWM_DEBUG_NODE, + IWM_DPRINTF(sc, IWM_DEBUG_LAR, "regulatory domain '%c%c' (%d channels available)\n", mcc >> 8, mcc & 0xff, n_channels); #endif @@ -4823,10 +4873,8 @@ iwm_init_hw(struct iwm_softc *sc) if (error) goto error; - if (fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_LAR_SUPPORT)) { - if ((error = iwm_send_update_mcc_cmd(sc, "ZZ")) != 0) - goto error; - } + if ((error = iwm_send_update_mcc_cmd(sc, "ZZ")) != 0) + goto error; if (fw_has_capa(&sc->ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) { if ((error = iwm_mvm_config_umac_scan(sc)) != 0) @@ -5423,7 +5471,7 @@ iwm_handle_rxb(struct iwm_softc *sc, struct mbuf *m) sc->sc_fw_mcc[0] = (notif->mcc & 0xff00) >> 8; sc->sc_fw_mcc[1] = notif->mcc & 0xff; sc->sc_fw_mcc[2] = '\0'; - IWM_DPRINTF(sc, IWM_DEBUG_RESET, + IWM_DPRINTF(sc, IWM_DEBUG_LAR, "fw source %d sent CC '%s'\n", notif->source_id, sc->sc_fw_mcc); break; Modified: stable/11/sys/dev/iwm/if_iwm_debug.h ============================================================================== --- stable/11/sys/dev/iwm/if_iwm_debug.h Thu Mar 1 06:46:56 2018 (r330216) +++ stable/11/sys/dev/iwm/if_iwm_debug.h Thu Mar 1 06:47:52 2018 (r330217) @@ -43,6 +43,7 @@ enum { IWM_DEBUG_EEPROM = 0x00080000, /* EEPROM/channel information */ IWM_DEBUG_TEMP = 0x00100000, /* Thermal Sensor handling */ IWM_DEBUG_FW = 0x00200000, /* Firmware management */ + IWM_DEBUG_LAR = 0x00400000, /* Location Aware Regulatory */ IWM_DEBUG_REGISTER = 0x20000000, /* print chipset register */ IWM_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */ IWM_DEBUG_FATAL = 0x80000000, /* fatal errors */ Modified: stable/11/sys/dev/iwm/if_iwmvar.h ============================================================================== --- stable/11/sys/dev/iwm/if_iwmvar.h Thu Mar 1 06:46:56 2018 (r330216) +++ stable/11/sys/dev/iwm/if_iwmvar.h Thu Mar 1 06:47:52 2018 (r330217) @@ -232,6 +232,7 @@ struct iwm_nvm_data { uint16_t nvm_version; uint8_t max_tx_pwr_half_dbm; + boolean_t lar_enabled; uint16_t nvm_ch_flags[]; };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803010647.w216lqrx064000>