Path: blob/main/sys/contrib/dev/iwlwifi/fw/init.c
105932 views
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause1/*2* Copyright (C) 2017 Intel Deutschland GmbH3* Copyright (C) 2019-2021, 2024-2025 Intel Corporation4*/5#include "iwl-drv.h"6#include "runtime.h"7#include "dbg.h"8#include "debugfs.h"910#include "fw/api/system.h"11#include "fw/api/commands.h"12#include "fw/api/rx.h"13#include "fw/api/datapath.h"1415void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,16const struct iwl_fw *fw,17const struct iwl_fw_runtime_ops *ops, void *ops_ctx,18const struct iwl_dump_sanitize_ops *sanitize_ops,19void *sanitize_ctx,20struct dentry *dbgfs_dir)21{22int i;2324memset(fwrt, 0, sizeof(*fwrt));25fwrt->trans = trans;26fwrt->fw = fw;27fwrt->dev = trans->dev;28fwrt->dump.conf = FW_DBG_INVALID;29fwrt->ops = ops;30fwrt->sanitize_ops = sanitize_ops;31fwrt->sanitize_ctx = sanitize_ctx;32fwrt->ops_ctx = ops_ctx;33for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) {34fwrt->dump.wks[i].idx = i;35INIT_DELAYED_WORK(&fwrt->dump.wks[i].wk, iwl_fw_error_dump_wk);36}37iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir);38}39IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);4041/* Assumes the appropriate lock is held by the caller */42void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)43{44iwl_fw_suspend_timestamp(fwrt);45iwl_dbg_tlv_time_point_sync(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START,46NULL);47}48IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend);4950void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt)51{52iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_END, NULL);53iwl_fw_resume_timestamp(fwrt);54}55IWL_EXPORT_SYMBOL(iwl_fw_runtime_resume);5657/* set device type and latency */58int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt)59{60struct iwl_soc_configuration_cmd cmd = {};61struct iwl_host_cmd hcmd = {62.id = WIDE_ID(SYSTEM_GROUP, SOC_CONFIGURATION_CMD),63.data[0] = &cmd,64.len[0] = sizeof(cmd),65};66int ret;6768/*69* In VER_1 of this command, the discrete value is considered70* an integer; In VER_2, it's a bitmask. Since we have only 271* values in VER_1, this is backwards-compatible with VER_2,72* as long as we don't set any other bits.73*/74if (!fwrt->trans->mac_cfg->integrated)75cmd.flags = cpu_to_le32(SOC_CONFIG_CMD_FLAGS_DISCRETE);7677BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_NONE !=78SOC_FLAGS_LTR_APPLY_DELAY_NONE);79BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_200US !=80SOC_FLAGS_LTR_APPLY_DELAY_200);81BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_2500US !=82SOC_FLAGS_LTR_APPLY_DELAY_2500);83BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_1820US !=84SOC_FLAGS_LTR_APPLY_DELAY_1820);8586if (fwrt->trans->mac_cfg->ltr_delay != IWL_CFG_TRANS_LTR_DELAY_NONE &&87!WARN_ON(!fwrt->trans->mac_cfg->integrated))88cmd.flags |= le32_encode_bits(fwrt->trans->mac_cfg->ltr_delay,89SOC_FLAGS_LTR_APPLY_DELAY_MASK);9091if (iwl_fw_lookup_cmd_ver(fwrt->fw, SCAN_REQ_UMAC,92IWL_FW_CMD_VER_UNKNOWN) >= 2 &&93fwrt->trans->mac_cfg->low_latency_xtal)94cmd.flags |= cpu_to_le32(SOC_CONFIG_CMD_FLAGS_LOW_LATENCY);9596cmd.latency = cpu_to_le32(fwrt->trans->mac_cfg->xtal_latency);9798ret = iwl_trans_send_cmd(fwrt->trans, &hcmd);99if (ret)100IWL_ERR(fwrt, "Failed to set soc latency: %d\n", ret);101return ret;102}103IWL_EXPORT_SYMBOL(iwl_set_soc_latency);104105int iwl_configure_rxq(struct iwl_fw_runtime *fwrt)106{107int i, num_queues, size, ret;108struct iwl_rfh_queue_config *cmd;109struct iwl_host_cmd hcmd = {110.id = WIDE_ID(DATA_PATH_GROUP, RFH_QUEUE_CONFIG_CMD),111.dataflags[0] = IWL_HCMD_DFL_NOCOPY,112};113114/*115* The default queue is configured via context info, so if we116* have a single queue, there's nothing to do here.117*/118if (fwrt->trans->info.num_rxqs == 1)119return 0;120121if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_22000)122return 0;123124/* skip the default queue */125num_queues = fwrt->trans->info.num_rxqs - 1;126127size = struct_size(cmd, data, num_queues);128129cmd = kzalloc(size, GFP_KERNEL);130if (!cmd)131return -ENOMEM;132133cmd->num_queues = num_queues;134135for (i = 0; i < num_queues; i++) {136struct iwl_trans_rxq_dma_data data;137138cmd->data[i].q_num = i + 1;139ret = iwl_trans_get_rxq_dma_data(fwrt->trans, i + 1, &data);140if (ret)141goto out;142143cmd->data[i].fr_bd_cb = cpu_to_le64(data.fr_bd_cb);144cmd->data[i].urbd_stts_wrptr =145cpu_to_le64(data.urbd_stts_wrptr);146cmd->data[i].ur_bd_cb = cpu_to_le64(data.ur_bd_cb);147cmd->data[i].fr_bd_wid = cpu_to_le32(data.fr_bd_wid);148}149150hcmd.data[0] = cmd;151hcmd.len[0] = size;152153ret = iwl_trans_send_cmd(fwrt->trans, &hcmd);154155out:156kfree(cmd);157158if (ret)159IWL_ERR(fwrt, "Failed to configure RX queues: %d\n", ret);160161return ret;162}163IWL_EXPORT_SYMBOL(iwl_configure_rxq);164165166