Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

Mar 24-27, 2025, special US time zones
Register
Loading...
  1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2/*
  3 * Copyright (C) 2020 - 2022 Intel Corporation
  4 */
  5
  6#include "mvm.h"
  7#include "fw/api/commands.h"
  8#include "fw/api/phy-ctxt.h"
  9
 10/*
 11 * DDR needs frequency in units of 16.666MHz, so provide FW with the
 12 * frequency values in the adjusted format.
 13 */
 14static const struct iwl_rfi_lut_entry iwl_rfi_table[IWL_RFI_LUT_SIZE] = {
 15	/* frequency 2667MHz */
 16	{cpu_to_le16(160), {50, 58, 60, 62, 64, 52, 54, 56},
 17	      {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,
 18	       PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,}},
 19
 20	/* frequency 2933MHz */
 21	{cpu_to_le16(176), {149, 151, 153, 157, 159, 161, 165, 163, 167, 169,
 22			    171, 173, 175},
 23	      {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,
 24	       PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,
 25	       PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,}},
 26
 27	/* frequency 3200MHz */
 28	{cpu_to_le16(192), {79, 81, 83, 85, 87, 89, 91, 93},
 29	      {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
 30	       PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,}},
 31
 32	/* frequency 3733MHz */
 33	{cpu_to_le16(223), {114, 116, 118, 120, 122, 106, 110, 124, 126},
 34	      {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,
 35	       PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,}},
 36
 37	/* frequency 4000MHz */
 38	{cpu_to_le16(240), {114, 151, 155, 157, 159, 161, 165},
 39	      {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,
 40	       PHY_BAND_5, PHY_BAND_5,}},
 41
 42	/* frequency 4267MHz */
 43	{cpu_to_le16(256), {79, 83, 85, 87, 89, 91, 93,},
 44	       {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
 45		PHY_BAND_6, PHY_BAND_6,}},
 46
 47	/* frequency 4400MHz */
 48	{cpu_to_le16(264), {111, 119, 123, 125, 129, 131, 133, 135, 143,},
 49	      {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
 50	       PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,}},
 51
 52	/* frequency 5200MHz */
 53	{cpu_to_le16(312), {36, 38, 40, 42, 44, 46, 50,},
 54	       {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,
 55		PHY_BAND_5, PHY_BAND_5,}},
 56
 57	/* frequency 5600MHz */
 58	{cpu_to_le16(336), {106, 110, 112, 114, 116, 118, 120, 122},
 59	       {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,
 60		PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,}},
 61
 62	/* frequency 6000MHz */
 63	{cpu_to_le16(360), {3, 5, 7, 9, 11, 13, 15,},
 64	       {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
 65		PHY_BAND_6, PHY_BAND_6,}},
 66
 67	/* frequency 6400MHz */
 68	{cpu_to_le16(384), {79, 83, 85, 87, 89, 91, 93,},
 69	       {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
 70		PHY_BAND_6, PHY_BAND_6,}},
 71};
 72
 73bool iwl_rfi_supported(struct iwl_mvm *mvm)
 74{
 75	/* The feature depends on a platform bugfix, so for now
 76	 * it's always disabled.
 77	 * When the platform support detection is implemented we should
 78	 * check FW TLV and platform support instead.
 79	 */
 80	return false;
 81}
 82
 83int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, struct iwl_rfi_lut_entry *rfi_table)
 84{
 85	int ret;
 86	struct iwl_rfi_config_cmd cmd;
 87	struct iwl_host_cmd hcmd = {
 88		.id = WIDE_ID(SYSTEM_GROUP, RFI_CONFIG_CMD),
 89		.dataflags[0] = IWL_HCMD_DFL_DUP,
 90		.data[0] = &cmd,
 91		.len[0] = sizeof(cmd),
 92	};
 93
 94	if (!iwl_rfi_supported(mvm))
 95		return -EOPNOTSUPP;
 96
 97	lockdep_assert_held(&mvm->mutex);
 98
 99	/* in case no table is passed, use the default one */
100	if (!rfi_table) {
101		memcpy(cmd.table, iwl_rfi_table, sizeof(cmd.table));
102	} else {
103		memcpy(cmd.table, rfi_table, sizeof(cmd.table));
104		/* notify FW the table is not the default one */
105		cmd.oem = 1;
106	}
107
108	ret = iwl_mvm_send_cmd(mvm, &hcmd);
109
110	if (ret)
111		IWL_ERR(mvm, "Failed to send RFI config cmd %d\n", ret);
112
113	return ret;
114}
115
116struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm)
117{
118	struct iwl_rfi_freq_table_resp_cmd *resp;
119	int resp_size = sizeof(*resp);
120	int ret;
121	struct iwl_host_cmd cmd = {
122		.id = WIDE_ID(SYSTEM_GROUP, RFI_GET_FREQ_TABLE_CMD),
123		.flags = CMD_WANT_SKB,
124	};
125
126	if (!iwl_rfi_supported(mvm))
127		return ERR_PTR(-EOPNOTSUPP);
128
129	mutex_lock(&mvm->mutex);
130	ret = iwl_mvm_send_cmd(mvm, &cmd);
131	mutex_unlock(&mvm->mutex);
132	if (ret)
133		return ERR_PTR(ret);
134
135	if (WARN_ON_ONCE(iwl_rx_packet_payload_len(cmd.resp_pkt) !=
136			 resp_size)) {
137		iwl_free_resp(&cmd);
138		return ERR_PTR(-EIO);
139	}
140
141	resp = kmemdup(cmd.resp_pkt->data, resp_size, GFP_KERNEL);
142	iwl_free_resp(&cmd);
143
144	if (!resp)
145		return ERR_PTR(-ENOMEM);
146
147	return resp;
148}
149
150void iwl_rfi_deactivate_notif_handler(struct iwl_mvm *mvm,
151				      struct iwl_rx_cmd_buffer *rxb)
152{
153	struct iwl_rx_packet *pkt = rxb_addr(rxb);
154	struct iwl_rfi_deactivate_notif *notif = (void *)pkt->data;
155
156	IWL_INFO(mvm, "RFIm is deactivated, reason = %d\n", notif->reason);
157}