xref: /freebsd/sys/contrib/dev/iwlwifi/mvm/rfi.c (revision bfcc09ddd422c95a1a2e4e794b63ee54c4902398)
1*bfcc09ddSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2*bfcc09ddSBjoern A. Zeeb /*
3*bfcc09ddSBjoern A. Zeeb  * Copyright (C) 2020 - 2021 Intel Corporation
4*bfcc09ddSBjoern A. Zeeb  */
5*bfcc09ddSBjoern A. Zeeb 
6*bfcc09ddSBjoern A. Zeeb #include "mvm.h"
7*bfcc09ddSBjoern A. Zeeb #include "fw/api/commands.h"
8*bfcc09ddSBjoern A. Zeeb #include "fw/api/phy-ctxt.h"
9*bfcc09ddSBjoern A. Zeeb 
10*bfcc09ddSBjoern A. Zeeb /**
11*bfcc09ddSBjoern A. Zeeb  * DDR needs frequency in units of 16.666MHz, so provide FW with the
12*bfcc09ddSBjoern A. Zeeb  * frequency values in the adjusted format.
13*bfcc09ddSBjoern A. Zeeb  */
14*bfcc09ddSBjoern A. Zeeb static const struct iwl_rfi_lut_entry iwl_rfi_table[IWL_RFI_LUT_SIZE] = {
15*bfcc09ddSBjoern A. Zeeb 	/* LPDDR4 */
16*bfcc09ddSBjoern A. Zeeb 
17*bfcc09ddSBjoern A. Zeeb 	/* frequency 3733MHz */
18*bfcc09ddSBjoern A. Zeeb 	{cpu_to_le16(223), {114, 116, 118, 120, 122,},
19*bfcc09ddSBjoern A. Zeeb 	      {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,}},
20*bfcc09ddSBjoern A. Zeeb 
21*bfcc09ddSBjoern A. Zeeb 	/* frequency 4267MHz */
22*bfcc09ddSBjoern A. Zeeb 	{cpu_to_le16(256), {79, 83, 85, 87, 89, 91, 93,},
23*bfcc09ddSBjoern A. Zeeb 	       {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
24*bfcc09ddSBjoern A. Zeeb 		PHY_BAND_6, PHY_BAND_6,}},
25*bfcc09ddSBjoern A. Zeeb 
26*bfcc09ddSBjoern A. Zeeb 	/* DDR5ePOR */
27*bfcc09ddSBjoern A. Zeeb 
28*bfcc09ddSBjoern A. Zeeb 	/* frequency 4000MHz */
29*bfcc09ddSBjoern A. Zeeb 	{cpu_to_le16(240), {3, 5, 7, 9, 11, 13, 15,},
30*bfcc09ddSBjoern A. Zeeb 	      {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
31*bfcc09ddSBjoern A. Zeeb 	       PHY_BAND_6, PHY_BAND_6,}},
32*bfcc09ddSBjoern A. Zeeb 
33*bfcc09ddSBjoern A. Zeeb 	/* frequency 4400MHz */
34*bfcc09ddSBjoern A. Zeeb 	{cpu_to_le16(264), {111, 119, 123, 125, 129, 131, 133, 135, 143,},
35*bfcc09ddSBjoern A. Zeeb 	      {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
36*bfcc09ddSBjoern A. Zeeb 	       PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,}},
37*bfcc09ddSBjoern A. Zeeb 
38*bfcc09ddSBjoern A. Zeeb 	/* LPDDR5iPOR */
39*bfcc09ddSBjoern A. Zeeb 
40*bfcc09ddSBjoern A. Zeeb 	/* frequency 5200MHz */
41*bfcc09ddSBjoern A. Zeeb 	{cpu_to_le16(312), {36, 38, 40, 42, 50,},
42*bfcc09ddSBjoern A. Zeeb 	       {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,}},
43*bfcc09ddSBjoern A. Zeeb 
44*bfcc09ddSBjoern A. Zeeb 	/* frequency 6000MHz */
45*bfcc09ddSBjoern A. Zeeb 	{cpu_to_le16(360), {3, 5, 7, 9, 11, 13, 15,},
46*bfcc09ddSBjoern A. Zeeb 	       {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
47*bfcc09ddSBjoern A. Zeeb 		PHY_BAND_6, PHY_BAND_6,}},
48*bfcc09ddSBjoern A. Zeeb 
49*bfcc09ddSBjoern A. Zeeb 	/* frequency 6400MHz */
50*bfcc09ddSBjoern A. Zeeb 	{cpu_to_le16(384), {79, 83, 85, 87, 89, 91, 93,},
51*bfcc09ddSBjoern A. Zeeb 	       {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
52*bfcc09ddSBjoern A. Zeeb 		PHY_BAND_6, PHY_BAND_6,}},
53*bfcc09ddSBjoern A. Zeeb };
54*bfcc09ddSBjoern A. Zeeb 
55*bfcc09ddSBjoern A. Zeeb int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, struct iwl_rfi_lut_entry *rfi_table)
56*bfcc09ddSBjoern A. Zeeb {
57*bfcc09ddSBjoern A. Zeeb 	int ret;
58*bfcc09ddSBjoern A. Zeeb 	struct iwl_rfi_config_cmd cmd;
59*bfcc09ddSBjoern A. Zeeb 	struct iwl_host_cmd hcmd = {
60*bfcc09ddSBjoern A. Zeeb 		.id = WIDE_ID(SYSTEM_GROUP, RFI_CONFIG_CMD),
61*bfcc09ddSBjoern A. Zeeb 		.dataflags[0] = IWL_HCMD_DFL_DUP,
62*bfcc09ddSBjoern A. Zeeb 		.data[0] = &cmd,
63*bfcc09ddSBjoern A. Zeeb 		.len[0] = sizeof(cmd),
64*bfcc09ddSBjoern A. Zeeb 	};
65*bfcc09ddSBjoern A. Zeeb 
66*bfcc09ddSBjoern A. Zeeb 	if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT))
67*bfcc09ddSBjoern A. Zeeb 		return -EOPNOTSUPP;
68*bfcc09ddSBjoern A. Zeeb 
69*bfcc09ddSBjoern A. Zeeb 	lockdep_assert_held(&mvm->mutex);
70*bfcc09ddSBjoern A. Zeeb 
71*bfcc09ddSBjoern A. Zeeb 	/* in case no table is passed, use the default one */
72*bfcc09ddSBjoern A. Zeeb 	if (!rfi_table) {
73*bfcc09ddSBjoern A. Zeeb 		memcpy(cmd.table, iwl_rfi_table, sizeof(cmd.table));
74*bfcc09ddSBjoern A. Zeeb 	} else {
75*bfcc09ddSBjoern A. Zeeb 		memcpy(cmd.table, rfi_table, sizeof(cmd.table));
76*bfcc09ddSBjoern A. Zeeb 		/* notify FW the table is not the default one */
77*bfcc09ddSBjoern A. Zeeb 		cmd.oem = 1;
78*bfcc09ddSBjoern A. Zeeb 	}
79*bfcc09ddSBjoern A. Zeeb 
80*bfcc09ddSBjoern A. Zeeb 	ret = iwl_mvm_send_cmd(mvm, &hcmd);
81*bfcc09ddSBjoern A. Zeeb 
82*bfcc09ddSBjoern A. Zeeb 	if (ret)
83*bfcc09ddSBjoern A. Zeeb 		IWL_ERR(mvm, "Failed to send RFI config cmd %d\n", ret);
84*bfcc09ddSBjoern A. Zeeb 
85*bfcc09ddSBjoern A. Zeeb 	return ret;
86*bfcc09ddSBjoern A. Zeeb }
87*bfcc09ddSBjoern A. Zeeb 
88*bfcc09ddSBjoern A. Zeeb struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm)
89*bfcc09ddSBjoern A. Zeeb {
90*bfcc09ddSBjoern A. Zeeb 	struct iwl_rfi_freq_table_resp_cmd *resp;
91*bfcc09ddSBjoern A. Zeeb 	int resp_size = sizeof(*resp);
92*bfcc09ddSBjoern A. Zeeb 	int ret;
93*bfcc09ddSBjoern A. Zeeb 	struct iwl_host_cmd cmd = {
94*bfcc09ddSBjoern A. Zeeb 		.id = WIDE_ID(SYSTEM_GROUP, RFI_GET_FREQ_TABLE_CMD),
95*bfcc09ddSBjoern A. Zeeb 		.flags = CMD_WANT_SKB,
96*bfcc09ddSBjoern A. Zeeb 	};
97*bfcc09ddSBjoern A. Zeeb 
98*bfcc09ddSBjoern A. Zeeb 	if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT))
99*bfcc09ddSBjoern A. Zeeb 		return ERR_PTR(-EOPNOTSUPP);
100*bfcc09ddSBjoern A. Zeeb 
101*bfcc09ddSBjoern A. Zeeb 	mutex_lock(&mvm->mutex);
102*bfcc09ddSBjoern A. Zeeb 	ret = iwl_mvm_send_cmd(mvm, &cmd);
103*bfcc09ddSBjoern A. Zeeb 	mutex_unlock(&mvm->mutex);
104*bfcc09ddSBjoern A. Zeeb 	if (ret)
105*bfcc09ddSBjoern A. Zeeb 		return ERR_PTR(ret);
106*bfcc09ddSBjoern A. Zeeb 
107*bfcc09ddSBjoern A. Zeeb 	if (WARN_ON_ONCE(iwl_rx_packet_payload_len(cmd.resp_pkt) != resp_size))
108*bfcc09ddSBjoern A. Zeeb 		return ERR_PTR(-EIO);
109*bfcc09ddSBjoern A. Zeeb 
110*bfcc09ddSBjoern A. Zeeb 	resp = kzalloc(resp_size, GFP_KERNEL);
111*bfcc09ddSBjoern A. Zeeb 	if (!resp)
112*bfcc09ddSBjoern A. Zeeb 		return ERR_PTR(-ENOMEM);
113*bfcc09ddSBjoern A. Zeeb 
114*bfcc09ddSBjoern A. Zeeb 	memcpy(resp, cmd.resp_pkt->data, resp_size);
115*bfcc09ddSBjoern A. Zeeb 
116*bfcc09ddSBjoern A. Zeeb 	iwl_free_resp(&cmd);
117*bfcc09ddSBjoern A. Zeeb 	return resp;
118*bfcc09ddSBjoern A. Zeeb }
119