summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/fw.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c141
1 files changed, 109 insertions, 32 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 1d5ee4330..403bd17b8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -15,6 +15,7 @@
#include "iwl-prph.h"
#include "fw/acpi.h"
#include "fw/pnvm.h"
+#include "fw/uefi.h"
#include "mvm.h"
#include "fw/dbg.h"
@@ -23,12 +24,15 @@
#include "iwl-nvm-parse.h"
#include "time-sync.h"
-#define MVM_UCODE_ALIVE_TIMEOUT (HZ)
+#define MVM_UCODE_ALIVE_TIMEOUT (2 * HZ)
#define MVM_UCODE_CALIB_TIMEOUT (2 * HZ)
#define IWL_TAS_US_MCC 0x5553
#define IWL_TAS_CANADA_MCC 0x4341
+#define IWL_UATS_VLP_AP_SUPPORTED BIT(29)
+#define IWL_UATS_AFC_AP_SUPPORTED BIT(30)
+
struct iwl_mvm_alive_data {
bool valid;
u32 scd_base_addr;
@@ -487,6 +491,52 @@ static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm,
}
#if defined(CONFIG_ACPI) && defined(CONFIG_EFI)
+static void iwl_mvm_uats_init(struct iwl_mvm *mvm)
+{
+ u8 cmd_ver;
+ int ret;
+ struct iwl_host_cmd cmd = {
+ .id = WIDE_ID(REGULATORY_AND_NVM_GROUP,
+ UATS_TABLE_CMD),
+ .flags = 0,
+ .data[0] = &mvm->fwrt.uats_table,
+ .len[0] = sizeof(mvm->fwrt.uats_table),
+ .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
+ };
+
+ if (!(mvm->trans->trans_cfg->device_family >=
+ IWL_DEVICE_FAMILY_AX210)) {
+ IWL_DEBUG_RADIO(mvm, "UATS feature is not supported\n");
+ return;
+ }
+
+ if (!mvm->fwrt.uats_enabled) {
+ IWL_DEBUG_RADIO(mvm, "UATS feature is disabled\n");
+ return;
+ }
+
+ cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id,
+ IWL_FW_CMD_VER_UNKNOWN);
+ if (cmd_ver != 1) {
+ IWL_DEBUG_RADIO(mvm,
+ "UATS_TABLE_CMD ver %d not supported\n",
+ cmd_ver);
+ return;
+ }
+
+ ret = iwl_uefi_get_uats_table(mvm->trans, &mvm->fwrt);
+ if (ret < 0) {
+ IWL_ERR(mvm, "failed to read UATS table (%d)\n", ret);
+ return;
+ }
+
+ ret = iwl_mvm_send_cmd(mvm, &cmd);
+ if (ret < 0)
+ IWL_ERR(mvm, "failed to send UATS_TABLE_CMD (%d)\n", ret);
+ else
+ IWL_DEBUG_RADIO(mvm, "UATS_TABLE_CMD sent to FW\n");
+}
+
static int iwl_mvm_sgom_init(struct iwl_mvm *mvm)
{
u8 cmd_ver;
@@ -526,6 +576,10 @@ static int iwl_mvm_sgom_init(struct iwl_mvm *mvm)
{
return 0;
}
+
+static void iwl_mvm_uats_init(struct iwl_mvm *mvm)
+{
+}
#endif
static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
@@ -583,6 +637,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm)
static const u16 init_complete[] = {
INIT_COMPLETE_NOTIF,
};
+ u32 sb_cfg;
int ret;
if (mvm->trans->cfg->tx_with_siso_diversity)
@@ -592,6 +647,14 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm)
mvm->rfkill_safe_init_done = false;
+ if (mvm->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
+ sb_cfg = iwl_read_umac_prph(mvm->trans, SB_MODIFY_CFG_FLAG);
+ /* if needed, we'll reset this on our way out later */
+ mvm->pldr_sync = sb_cfg == SB_CFG_RESIDES_IN_ROM;
+ if (mvm->pldr_sync && iwl_mei_pldr_req())
+ return -EBUSY;
+ }
+
iwl_init_notification_wait(&mvm->notif_wait,
&init_wait,
init_complete,
@@ -605,6 +668,13 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm)
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
if (ret) {
IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
+
+ /* if we needed reset then fail here, but notify and remove */
+ if (mvm->pldr_sync) {
+ iwl_mei_alive_notif(false);
+ iwl_trans_pcie_remove(mvm->trans, true);
+ }
+
goto error;
}
iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE,
@@ -667,7 +737,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm)
/* Read the NVM only at driver load time, no need to do this twice */
if (!IWL_MVM_PARSE_NVM && !mvm->nvm_data) {
- mvm->nvm_data = iwl_get_nvm(mvm->trans, mvm->fw);
+ mvm->nvm_data = iwl_get_nvm(mvm->trans, mvm->fw,
+ mvm->set_tx_ant, mvm->set_rx_ant);
if (IS_ERR(mvm->nvm_data)) {
ret = PTR_ERR(mvm->nvm_data);
mvm->nvm_data = NULL;
@@ -1084,6 +1155,12 @@ static const struct dmi_system_id dmi_tas_approved_list[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
},
},
+ { .ident = "GOOGLE-HP",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Google"),
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ },
+ },
{ .ident = "MSI",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
@@ -1209,7 +1286,10 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
{
int ret;
u32 value;
- struct iwl_lari_config_change_cmd_v6 cmd = {};
+ struct iwl_lari_config_change_cmd_v7 cmd = {};
+ u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
+ WIDE_ID(REGULATORY_AND_NVM_GROUP,
+ LARI_CONFIG_CHANGE), 1);
cmd.config_bitmap = iwl_acpi_get_lari_config_bitmap(&mvm->fwrt);
@@ -1227,8 +1307,11 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0,
DSM_FUNC_ACTIVATE_CHANNEL,
&iwl_guid, &value);
- if (!ret)
+ if (!ret) {
+ if (cmd_ver < 8)
+ value &= ~ACTIVATE_5G2_IN_WW_MASK;
cmd.chan_state_active_bitmap = cpu_to_le32(value);
+ }
ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0,
DSM_FUNC_ENABLE_6E,
@@ -1242,18 +1325,26 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
if (!ret)
cmd.force_disable_channels_bitmap = cpu_to_le32(value);
+ ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0,
+ DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
+ &iwl_guid, &value);
+ if (!ret)
+ cmd.edt_bitmap = cpu_to_le32(value);
+
if (cmd.config_bitmap ||
cmd.oem_uhb_allow_bitmap ||
cmd.oem_11ax_allow_bitmap ||
cmd.oem_unii4_allow_bitmap ||
cmd.chan_state_active_bitmap ||
- cmd.force_disable_channels_bitmap) {
+ cmd.force_disable_channels_bitmap ||
+ cmd.edt_bitmap) {
size_t cmd_size;
- u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
- WIDE_ID(REGULATORY_AND_NVM_GROUP,
- LARI_CONFIG_CHANGE),
- 1);
+
switch (cmd_ver) {
+ case 8:
+ case 7:
+ cmd_size = sizeof(struct iwl_lari_config_change_cmd_v7);
+ break;
case 6:
cmd_size = sizeof(struct iwl_lari_config_change_cmd_v6);
break;
@@ -1287,6 +1378,9 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
"sending LARI_CONFIG_CHANGE, oem_uhb_allow_bitmap=0x%x, force_disable_channels_bitmap=0x%x\n",
le32_to_cpu(cmd.oem_uhb_allow_bitmap),
le32_to_cpu(cmd.force_disable_channels_bitmap));
+ IWL_DEBUG_RADIO(mvm,
+ "sending LARI_CONFIG_CHANGE, edt_bitmap=0x%x\n",
+ le32_to_cpu(cmd.edt_bitmap));
ret = iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(REGULATORY_AND_NVM_GROUP,
LARI_CONFIG_CHANGE),
@@ -1296,6 +1390,10 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
"Failed to send LARI_CONFIG_CHANGE (%d)\n",
ret);
}
+
+ if (le32_to_cpu(cmd.oem_uhb_allow_bitmap) & IWL_UATS_VLP_AP_SUPPORTED ||
+ le32_to_cpu(cmd.oem_uhb_allow_bitmap) & IWL_UATS_AFC_AP_SUPPORTED)
+ mvm->fwrt.uats_enabled = TRUE;
}
void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm)
@@ -1499,10 +1597,7 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
int iwl_mvm_up(struct iwl_mvm *mvm)
{
int ret, i;
- struct ieee80211_channel *chan;
- struct cfg80211_chan_def chandef;
struct ieee80211_supported_band *sband = NULL;
- u32 sb_cfg;
lockdep_assert_held(&mvm->mutex);
@@ -1510,11 +1605,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
if (ret)
return ret;
- sb_cfg = iwl_read_umac_prph(mvm->trans, SB_MODIFY_CFG_FLAG);
- mvm->pldr_sync = !(sb_cfg & SB_CFG_RESIDES_IN_OTP_MASK);
- if (mvm->pldr_sync && iwl_mei_pldr_req())
- return -EBUSY;
-
ret = iwl_mvm_load_rt_fw(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
@@ -1527,6 +1617,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
/* FW loaded successfully */
mvm->pldr_sync = false;
+ iwl_fw_disable_dbg_asserts(&mvm->fwrt);
iwl_get_shared_mem_conf(&mvm->fwrt);
ret = iwl_mvm_sf_update(mvm, NULL, false);
@@ -1630,21 +1721,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error;
}
- chan = &sband->channels[0];
-
- cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
- for (i = 0; i < NUM_PHY_CTX; i++) {
- /*
- * The channel used here isn't relevant as it's
- * going to be overwritten in the other flows.
- * For now use the first channel we have.
- */
- ret = iwl_mvm_phy_ctxt_add(mvm, &mvm->phy_ctxts[i],
- &chandef, 1, 1);
- if (ret)
- goto error;
- }
-
if (iwl_mvm_is_tt_in_fw(mvm)) {
/* in order to give the responsibility of ct-kill and
* TX backoff to FW we need to send empty temperature reporting
@@ -1727,6 +1803,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
iwl_mvm_tas_init(mvm);
iwl_mvm_leds_sync(mvm);
+ iwl_mvm_uats_init(mvm);
if (iwl_rfi_supported(mvm)) {
if (iwl_mvm_eval_dsm_rfi(mvm) == DSM_VALUE_RFI_ENABLE)