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