Lines Matching +full:hw +full:- +full:channels

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2019, 2021-2024 Intel Corporation
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5 * Copyright (C) 2016-2017 Intel Deutschland GmbH
11 #include "iwl-trans.h"
12 #include "iwl-csr.h"
14 #include "iwl-nvm-utils.h"
15 #include "iwl-nvm-parse.h"
16 #include "iwl-prph.h"
62 nvm_resp = (void *)pkt->data;
63 if (le16_to_cpu(nvm_resp->status) != READ_NVM_CHUNK_SUCCEED) {
66 section, le16_to_cpu(nvm_resp->status));
67 ret = -EIO;
102 nvm_resp = (void *)pkt->data;
103 ret = le16_to_cpu(nvm_resp->status);
104 bytes_read = le16_to_cpu(nvm_resp->length);
105 offset_read = le16_to_cpu(nvm_resp->offset);
106 resp_data = nvm_resp->data;
118 IWL_DEBUG_EEPROM(mvm->trans->dev,
123 IWL_DEBUG_EEPROM(mvm->trans->dev,
125 ret, mvm->trans->name);
126 ret = -ENODATA;
134 ret = -EINVAL;
158 length - offset);
196 mvm->trans->trans_cfg->base_params->eeprom_size) {
198 return -ENOBUFS;
203 IWL_DEBUG_EEPROM(mvm->trans->dev,
211 iwl_nvm_fixups(mvm->trans->hw_id, section, data, offset);
213 IWL_DEBUG_EEPROM(mvm->trans->dev,
221 struct iwl_nvm_section *sections = mvm->nvm_sections;
222 const __be16 *hw;
224 u8 tx_ant = mvm->fw->valid_tx_ant;
225 u8 rx_ant = mvm->fw->valid_rx_ant;
229 if (mvm->trans->cfg->nvm_type == IWL_NVM) {
230 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
231 !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) {
236 if (mvm->trans->cfg->nvm_type == IWL_NVM_SDP)
242 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
243 !mvm->nvm_sections[regulatory_type].data) {
248 /* MAC_OVERRIDE or at least HW section must exist */
249 if (!mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data &&
250 !mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data) {
257 if (mvm->trans->cfg->nvm_type == IWL_NVM_EXT &&
258 !mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) {
265 hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data;
272 regulatory = mvm->trans->cfg->nvm_type == IWL_NVM_SDP ?
276 if (mvm->set_tx_ant)
277 tx_ant &= mvm->set_tx_ant;
279 if (mvm->set_rx_ant)
280 rx_ant &= mvm->set_rx_ant;
282 return iwl_parse_nvm_data(mvm->trans, mvm->cfg, mvm->fw, hw, sw, calib,
287 /* Loads the NVM data stored in mvm->nvm_sections into the NIC */
291 struct iwl_nvm_section *sections = mvm->nvm_sections;
293 IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n");
295 for (i = 0; i < ARRAY_SIZE(mvm->nvm_sections); i++) {
296 if (!mvm->nvm_sections[i].data || !mvm->nvm_sections[i].length)
313 const char *nvm_file_C = mvm->cfg->default_nvm_file_C_step;
315 if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS))
316 return -EINVAL;
320 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
322 nvm_buffer = kmalloc(mvm->trans->trans_cfg->base_params->eeprom_size,
325 return -ENOMEM;
330 if (ret == -ENODATA) {
339 ret = -ENOMEM;
343 iwl_nvm_fixups(mvm->trans->hw_id, section, temp, ret);
345 mvm->nvm_sections[section].data = temp;
346 mvm->nvm_sections[section].length = ret;
351 mvm->nvm_sw_blob.data = temp;
352 mvm->nvm_sw_blob.size = ret;
355 mvm->nvm_calib_blob.data = temp;
356 mvm->nvm_calib_blob.size = ret;
359 mvm->nvm_prod_blob.data = temp;
360 mvm->nvm_prod_blob.size = ret;
363 mvm->nvm_phy_sku_blob.data = temp;
364 mvm->nvm_phy_sku_blob.size = ret;
368 mvm->nvm_reg_blob.data = temp;
369 mvm->nvm_reg_blob.size = ret;
372 if (section == mvm->cfg->nvm_hw_section_num) {
373 mvm->nvm_hw_blob.data = temp;
374 mvm->nvm_hw_blob.size = ret;
384 /* Only if PNVM selected in the mod param - load external NVM */
385 if (mvm->nvm_file_name) {
387 ret = iwl_read_external_nvm(mvm->trans, mvm->nvm_file_name,
388 mvm->nvm_sections);
390 mvm->nvm_file_name = nvm_file_C;
392 if ((ret == -EFAULT || ret == -ENOENT) &&
393 mvm->nvm_file_name) {
395 ret = iwl_read_external_nvm(mvm->trans,
396 mvm->nvm_file_name,
397 mvm->nvm_sections);
407 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
408 if (!mvm->nvm_data)
409 return -ENODATA;
410 IWL_DEBUG_EEPROM(mvm->trans->dev, "nvm version = %x\n",
411 mvm->nvm_data->nvm_version);
438 return ERR_PTR(-EOPNOTSUPP);
451 resp_ver = iwl_fw_lookup_notif_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP,
456 struct iwl_mcc_update_resp_v8 *mcc_resp_v8 = (void *)pkt->data;
458 n_channels = __le32_to_cpu(mcc_resp_v8->n_channels);
460 struct_size(mcc_resp_v8, channels, n_channels)) {
461 resp_cp = ERR_PTR(-EINVAL);
464 resp_len = struct_size(resp_cp, channels, n_channels);
467 resp_cp = ERR_PTR(-ENOMEM);
470 resp_cp->status = mcc_resp_v8->status;
471 resp_cp->mcc = mcc_resp_v8->mcc;
472 resp_cp->cap = mcc_resp_v8->cap;
473 resp_cp->source_id = mcc_resp_v8->source_id;
474 resp_cp->time = mcc_resp_v8->time;
475 resp_cp->geo_info = mcc_resp_v8->geo_info;
476 resp_cp->n_channels = mcc_resp_v8->n_channels;
477 memcpy(resp_cp->channels, mcc_resp_v8->channels,
479 } else if (fw_has_capa(&mvm->fw->ucode_capa,
481 struct iwl_mcc_update_resp_v4 *mcc_resp_v4 = (void *)pkt->data;
483 n_channels = __le32_to_cpu(mcc_resp_v4->n_channels);
485 struct_size(mcc_resp_v4, channels, n_channels)) {
486 resp_cp = ERR_PTR(-EINVAL);
489 resp_len = struct_size(resp_cp, channels, n_channels);
492 resp_cp = ERR_PTR(-ENOMEM);
496 resp_cp->status = mcc_resp_v4->status;
497 resp_cp->mcc = mcc_resp_v4->mcc;
498 resp_cp->cap = cpu_to_le32(le16_to_cpu(mcc_resp_v4->cap));
499 resp_cp->source_id = mcc_resp_v4->source_id;
500 resp_cp->time = mcc_resp_v4->time;
501 resp_cp->geo_info = mcc_resp_v4->geo_info;
502 resp_cp->n_channels = mcc_resp_v4->n_channels;
503 memcpy(resp_cp->channels, mcc_resp_v4->channels,
506 struct iwl_mcc_update_resp_v3 *mcc_resp_v3 = (void *)pkt->data;
508 n_channels = __le32_to_cpu(mcc_resp_v3->n_channels);
510 struct_size(mcc_resp_v3, channels, n_channels)) {
511 resp_cp = ERR_PTR(-EINVAL);
514 resp_len = struct_size(resp_cp, channels, n_channels);
517 resp_cp = ERR_PTR(-ENOMEM);
521 resp_cp->status = mcc_resp_v3->status;
522 resp_cp->mcc = mcc_resp_v3->mcc;
523 resp_cp->cap = cpu_to_le32(mcc_resp_v3->cap);
524 resp_cp->source_id = mcc_resp_v3->source_id;
525 resp_cp->time = mcc_resp_v3->time;
526 resp_cp->geo_info = mcc_resp_v3->geo_info;
527 resp_cp->n_channels = mcc_resp_v3->n_channels;
528 memcpy(resp_cp->channels, mcc_resp_v3->channels,
532 status = le32_to_cpu(resp_cp->status);
534 mcc = le16_to_cpu(resp_cp->mcc);
536 /* W/A for a FW/NVM issue - returns 0x00 for the world domain */
538 mcc = 0x3030; /* "00" - world */
539 resp_cp->mcc = cpu_to_le16(mcc);
559 if (mvm->cfg->nvm_type == IWL_NVM_EXT) {
560 tlv_lar = fw_has_capa(&mvm->fw->ucode_capa,
562 nvm_lar = mvm->nvm_data->lar_enabled;
578 if (retval != -ENOENT)
587 mvm->lar_regdom_set = false;
591 return -EIO;
594 !iwl_bios_get_mcc(&mvm->fwrt, mcc)) {
596 regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc,
599 return -EIO;
602 retval = regulatory_set_wiphy_regd_sync(mvm->hw->wiphy, regd);
611 struct iwl_mcc_chub_notif *notif = (void *)pkt->data;
617 lockdep_assert_held(&mvm->mutex);
619 if (iwl_mvm_is_vif_assoc(mvm) && notif->source_id == MCC_SOURCE_WIFI) {
627 mcc[0] = le16_to_cpu(notif->mcc) >> 8;
628 mcc[1] = le16_to_cpu(notif->mcc) & 0xff;
630 src = notif->source_id;
635 regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc, src, NULL);
648 regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);