diff options
author | Matti Gottlieb <matti.gottlieb@intel.com> | 2016-01-04 14:38:41 +0300 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2016-01-07 20:01:25 +0300 |
commit | 6fa52430f0b3a45a31fb706084288884532e857c (patch) | |
tree | 33a7bbe7d234f9cc443642d8879dc7b1f4cc0868 /drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | |
parent | 1e3c3c3529a7d0455b38f74d287d296cb9c786aa (diff) | |
download | linux-6fa52430f0b3a45a31fb706084288884532e857c.tar.xz |
iwlwifi: mvm: change mcc update API
New functionality for testing that is not relevant for
this driver has been added. This required an API change.
Add new cmd & response versions for the MCC update cmd & response.
Add new TLV indicating that the FW is using the new API.
Signed-off-by: Matti Gottlieb <matti.gottlieb@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/nvm.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index d8dcb67b7ff9..e4fe8a66a3a0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c @@ -7,6 +7,7 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH + * Copyright(c) 2016 Intel Deutschland GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -33,6 +34,7 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH + * Copyright(c) 2016 Intel Deutschland GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -670,6 +672,7 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2, .source_id = (u8)src_id, }; struct iwl_mcc_update_resp *mcc_resp, *resp_cp = NULL; + struct iwl_mcc_update_resp_v1 *mcc_resp_v1 = NULL; struct iwl_rx_packet *pkt; struct iwl_host_cmd cmd = { .id = MCC_UPDATE_CMD, @@ -681,11 +684,15 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2, u32 status; int resp_len, n_channels; u16 mcc; + bool resp_v2 = fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2); if (WARN_ON_ONCE(!iwl_mvm_is_lar_supported(mvm))) return ERR_PTR(-EOPNOTSUPP); cmd.len[0] = sizeof(struct iwl_mcc_update_cmd); + if (!resp_v2) + cmd.len[0] = sizeof(struct iwl_mcc_update_cmd_v1); IWL_DEBUG_LAR(mvm, "send MCC update to FW with '%c%c' src = %d\n", alpha2[0], alpha2[1], src_id); @@ -697,31 +704,50 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2, pkt = cmd.resp_pkt; /* Extract MCC response */ - mcc_resp = (void *)pkt->data; - status = le32_to_cpu(mcc_resp->status); + if (resp_v2) { + mcc_resp = (void *)pkt->data; + n_channels = __le32_to_cpu(mcc_resp->n_channels); + } else { + mcc_resp_v1 = (void *)pkt->data; + n_channels = __le32_to_cpu(mcc_resp_v1->n_channels); + } - mcc = le16_to_cpu(mcc_resp->mcc); + resp_len = sizeof(struct iwl_mcc_update_resp) + n_channels * + sizeof(__le32); + + resp_cp = kzalloc(resp_len, GFP_KERNEL); + if (!resp_cp) { + ret = -ENOMEM; + goto exit; + } + + if (resp_v2) { + memcpy(resp_cp, mcc_resp, resp_len); + } else { + resp_cp->status = mcc_resp_v1->status; + resp_cp->mcc = mcc_resp_v1->mcc; + resp_cp->cap = mcc_resp_v1->cap; + resp_cp->source_id = mcc_resp_v1->source_id; + resp_cp->n_channels = mcc_resp_v1->n_channels; + memcpy(resp_cp->channels, mcc_resp_v1->channels, + n_channels * sizeof(__le32)); + } + + status = le32_to_cpu(resp_cp->status); + + mcc = le16_to_cpu(resp_cp->mcc); /* W/A for a FW/NVM issue - returns 0x00 for the world domain */ if (mcc == 0) { mcc = 0x3030; /* "00" - world */ - mcc_resp->mcc = cpu_to_le16(mcc); + resp_cp->mcc = cpu_to_le16(mcc); } - n_channels = __le32_to_cpu(mcc_resp->n_channels); IWL_DEBUG_LAR(mvm, "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') change: %d n_chans: %d\n", status, mcc, mcc >> 8, mcc & 0xff, !!(status == MCC_RESP_NEW_CHAN_PROFILE), n_channels); - resp_len = sizeof(*mcc_resp) + n_channels * sizeof(__le32); - resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL); - if (!resp_cp) { - ret = -ENOMEM; - goto exit; - } - - ret = 0; exit: iwl_free_resp(&cmd); if (ret) |