xref: /linux/drivers/net/wireless/intel/iwlwifi/fw/init.c (revision e80bfd117d89e8f9d71893edc03bc7b3c6c1eea3)
17174beb6SJohannes Berg /******************************************************************************
27174beb6SJohannes Berg  *
37174beb6SJohannes Berg  * This file is provided under a dual BSD/GPLv2 license.  When using or
47174beb6SJohannes Berg  * redistributing this file, you may do so under either license.
57174beb6SJohannes Berg  *
67174beb6SJohannes Berg  * GPL LICENSE SUMMARY
77174beb6SJohannes Berg  *
87174beb6SJohannes Berg  * Copyright(c) 2017 Intel Deutschland GmbH
9a8eb340fSEmmanuel Grumbach  * Copyright(c) 2019 - 2020 Intel Corporation
107174beb6SJohannes Berg  *
117174beb6SJohannes Berg  * This program is free software; you can redistribute it and/or modify
127174beb6SJohannes Berg  * it under the terms of version 2 of the GNU General Public License as
137174beb6SJohannes Berg  * published by the Free Software Foundation.
147174beb6SJohannes Berg  *
157174beb6SJohannes Berg  * This program is distributed in the hope that it will be useful, but
167174beb6SJohannes Berg  * WITHOUT ANY WARRANTY; without even the implied warranty of
177174beb6SJohannes Berg  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
187174beb6SJohannes Berg  * General Public License for more details.
197174beb6SJohannes Berg  *
207174beb6SJohannes Berg  * The full GNU General Public License is included in this distribution
217174beb6SJohannes Berg  * in the file called COPYING.
227174beb6SJohannes Berg  *
237174beb6SJohannes Berg  * Contact Information:
247174beb6SJohannes Berg  *  Intel Linux Wireless <linuxwifi@intel.com>
257174beb6SJohannes Berg  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
267174beb6SJohannes Berg  *
277174beb6SJohannes Berg  * BSD LICENSE
287174beb6SJohannes Berg  *
297174beb6SJohannes Berg  * Copyright(c) 2017 Intel Deutschland GmbH
30a8eb340fSEmmanuel Grumbach  * Copyright(c) 2019 - 2020 Intel Corporation
317174beb6SJohannes Berg  * All rights reserved.
327174beb6SJohannes Berg  *
337174beb6SJohannes Berg  * Redistribution and use in source and binary forms, with or without
347174beb6SJohannes Berg  * modification, are permitted provided that the following conditions
357174beb6SJohannes Berg  * are met:
367174beb6SJohannes Berg  *
377174beb6SJohannes Berg  *  * Redistributions of source code must retain the above copyright
387174beb6SJohannes Berg  *    notice, this list of conditions and the following disclaimer.
397174beb6SJohannes Berg  *  * Redistributions in binary form must reproduce the above copyright
407174beb6SJohannes Berg  *    notice, this list of conditions and the following disclaimer in
417174beb6SJohannes Berg  *    the documentation and/or other materials provided with the
427174beb6SJohannes Berg  *    distribution.
437174beb6SJohannes Berg  *  * Neither the name Intel Corporation nor the names of its
447174beb6SJohannes Berg  *    contributors may be used to endorse or promote products derived
457174beb6SJohannes Berg  *    from this software without specific prior written permission.
467174beb6SJohannes Berg  *
477174beb6SJohannes Berg  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
487174beb6SJohannes Berg  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
497174beb6SJohannes Berg  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
507174beb6SJohannes Berg  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
517174beb6SJohannes Berg  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
527174beb6SJohannes Berg  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
537174beb6SJohannes Berg  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
547174beb6SJohannes Berg  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
557174beb6SJohannes Berg  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
567174beb6SJohannes Berg  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
577174beb6SJohannes Berg  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
587174beb6SJohannes Berg  *
597174beb6SJohannes Berg  *****************************************************************************/
607174beb6SJohannes Berg #include "iwl-drv.h"
617174beb6SJohannes Berg #include "runtime.h"
627174beb6SJohannes Berg #include "dbg.h"
6393b167c1SMordechay Goodstein #include "debugfs.h"
647174beb6SJohannes Berg 
65a8eb340fSEmmanuel Grumbach #include "fw/api/soc.h"
66a8eb340fSEmmanuel Grumbach #include "fw/api/commands.h"
67a8eb340fSEmmanuel Grumbach 
687174beb6SJohannes Berg void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
697174beb6SJohannes Berg 			const struct iwl_fw *fw,
7093b167c1SMordechay Goodstein 			const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
7193b167c1SMordechay Goodstein 			struct dentry *dbgfs_dir)
727174beb6SJohannes Berg {
73c7ab138eSShahar S Matityahu 	int i;
74c7ab138eSShahar S Matityahu 
757174beb6SJohannes Berg 	memset(fwrt, 0, sizeof(*fwrt));
767174beb6SJohannes Berg 	fwrt->trans = trans;
777174beb6SJohannes Berg 	fwrt->fw = fw;
787174beb6SJohannes Berg 	fwrt->dev = trans->dev;
797174beb6SJohannes Berg 	fwrt->dump.conf = FW_DBG_INVALID;
807174beb6SJohannes Berg 	fwrt->ops = ops;
817174beb6SJohannes Berg 	fwrt->ops_ctx = ops_ctx;
82c7ab138eSShahar S Matityahu 	for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) {
83c7ab138eSShahar S Matityahu 		fwrt->dump.wks[i].idx = i;
84c7ab138eSShahar S Matityahu 		INIT_DELAYED_WORK(&fwrt->dump.wks[i].wk, iwl_fw_error_dump_wk);
85c7ab138eSShahar S Matityahu 	}
8693b167c1SMordechay Goodstein 	iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir);
877174beb6SJohannes Berg }
887174beb6SJohannes Berg IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
897f8ae00fSHaim Dreyfuss 
907f8ae00fSHaim Dreyfuss void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)
917f8ae00fSHaim Dreyfuss {
927f8ae00fSHaim Dreyfuss 	iwl_fw_suspend_timestamp(fwrt);
937f8ae00fSHaim Dreyfuss }
947f8ae00fSHaim Dreyfuss IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend);
957f8ae00fSHaim Dreyfuss 
967f8ae00fSHaim Dreyfuss void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt)
977f8ae00fSHaim Dreyfuss {
987f8ae00fSHaim Dreyfuss 	iwl_fw_resume_timestamp(fwrt);
997f8ae00fSHaim Dreyfuss }
1007f8ae00fSHaim Dreyfuss IWL_EXPORT_SYMBOL(iwl_fw_runtime_resume);
101a8eb340fSEmmanuel Grumbach 
102a8eb340fSEmmanuel Grumbach /* set device type and latency */
103a8eb340fSEmmanuel Grumbach int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt)
104a8eb340fSEmmanuel Grumbach {
105a8eb340fSEmmanuel Grumbach 	struct iwl_soc_configuration_cmd cmd = {};
106a8eb340fSEmmanuel Grumbach 	struct iwl_host_cmd hcmd = {
107a8eb340fSEmmanuel Grumbach 		.id = iwl_cmd_id(SOC_CONFIGURATION_CMD, SYSTEM_GROUP, 0),
108a8eb340fSEmmanuel Grumbach 		.data[0] = &cmd,
109a8eb340fSEmmanuel Grumbach 		.len[0] = sizeof(cmd),
110a8eb340fSEmmanuel Grumbach 	};
111a8eb340fSEmmanuel Grumbach 	int ret;
112a8eb340fSEmmanuel Grumbach 
113a8eb340fSEmmanuel Grumbach 	/*
114a8eb340fSEmmanuel Grumbach 	 * In VER_1 of this command, the discrete value is considered
115a8eb340fSEmmanuel Grumbach 	 * an integer; In VER_2, it's a bitmask.  Since we have only 2
116a8eb340fSEmmanuel Grumbach 	 * values in VER_1, this is backwards-compatible with VER_2,
117a8eb340fSEmmanuel Grumbach 	 * as long as we don't set any other bits.
118a8eb340fSEmmanuel Grumbach 	 */
119a8eb340fSEmmanuel Grumbach 	if (!fwrt->trans->trans_cfg->integrated)
120a8eb340fSEmmanuel Grumbach 		cmd.flags = cpu_to_le32(SOC_CONFIG_CMD_FLAGS_DISCRETE);
121a8eb340fSEmmanuel Grumbach 
122a8eb340fSEmmanuel Grumbach 	BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_NONE !=
123a8eb340fSEmmanuel Grumbach 		     SOC_FLAGS_LTR_APPLY_DELAY_NONE);
124a8eb340fSEmmanuel Grumbach 	BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_200US !=
125a8eb340fSEmmanuel Grumbach 		     SOC_FLAGS_LTR_APPLY_DELAY_200);
126a8eb340fSEmmanuel Grumbach 	BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_2500US !=
127a8eb340fSEmmanuel Grumbach 		     SOC_FLAGS_LTR_APPLY_DELAY_2500);
128a8eb340fSEmmanuel Grumbach 	BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_1820US !=
129a8eb340fSEmmanuel Grumbach 		     SOC_FLAGS_LTR_APPLY_DELAY_1820);
130a8eb340fSEmmanuel Grumbach 
131a8eb340fSEmmanuel Grumbach 	if (fwrt->trans->trans_cfg->ltr_delay != IWL_CFG_TRANS_LTR_DELAY_NONE &&
132a8eb340fSEmmanuel Grumbach 	    !WARN_ON(!fwrt->trans->trans_cfg->integrated))
133a8eb340fSEmmanuel Grumbach 		cmd.flags |= le32_encode_bits(fwrt->trans->trans_cfg->ltr_delay,
134a8eb340fSEmmanuel Grumbach 					      SOC_FLAGS_LTR_APPLY_DELAY_MASK);
135a8eb340fSEmmanuel Grumbach 
136a8eb340fSEmmanuel Grumbach 	if (iwl_fw_lookup_cmd_ver(fwrt->fw, IWL_ALWAYS_LONG_GROUP,
137*e80bfd11SMordechay Goodstein 				  SCAN_REQ_UMAC,
138*e80bfd11SMordechay Goodstein 				  IWL_FW_CMD_VER_UNKNOWN) >= 2 &&
139a8eb340fSEmmanuel Grumbach 	    fwrt->trans->trans_cfg->low_latency_xtal)
140a8eb340fSEmmanuel Grumbach 		cmd.flags |= cpu_to_le32(SOC_CONFIG_CMD_FLAGS_LOW_LATENCY);
141a8eb340fSEmmanuel Grumbach 
142a8eb340fSEmmanuel Grumbach 	cmd.latency = cpu_to_le32(fwrt->trans->trans_cfg->xtal_latency);
143a8eb340fSEmmanuel Grumbach 
144a8eb340fSEmmanuel Grumbach 	ret = iwl_trans_send_cmd(fwrt->trans, &hcmd);
145a8eb340fSEmmanuel Grumbach 	if (ret)
146a8eb340fSEmmanuel Grumbach 		IWL_ERR(fwrt, "Failed to set soc latency: %d\n", ret);
147a8eb340fSEmmanuel Grumbach 	return ret;
148a8eb340fSEmmanuel Grumbach }
149a8eb340fSEmmanuel Grumbach IWL_EXPORT_SYMBOL(iwl_set_soc_latency);
150