1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3 * Copyright (C) 2020 - 2021 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 */
14 static 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
iwl_rfi_send_config_cmd(struct iwl_mvm * mvm,struct iwl_rfi_lut_entry * rfi_table)73 int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, struct iwl_rfi_lut_entry *rfi_table)
74 {
75 int ret;
76 struct iwl_rfi_config_cmd cmd;
77 struct iwl_host_cmd hcmd = {
78 .id = WIDE_ID(SYSTEM_GROUP, RFI_CONFIG_CMD),
79 .dataflags[0] = IWL_HCMD_DFL_DUP,
80 .data[0] = &cmd,
81 .len[0] = sizeof(cmd),
82 };
83
84 if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT))
85 return -EOPNOTSUPP;
86
87 lockdep_assert_held(&mvm->mutex);
88
89 /* in case no table is passed, use the default one */
90 if (!rfi_table) {
91 memcpy(cmd.table, iwl_rfi_table, sizeof(cmd.table));
92 } else {
93 memcpy(cmd.table, rfi_table, sizeof(cmd.table));
94 /* notify FW the table is not the default one */
95 cmd.oem = 1;
96 }
97
98 ret = iwl_mvm_send_cmd(mvm, &hcmd);
99
100 if (ret)
101 IWL_ERR(mvm, "Failed to send RFI config cmd %d\n", ret);
102
103 return ret;
104 }
105
iwl_rfi_get_freq_table(struct iwl_mvm * mvm)106 struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm)
107 {
108 struct iwl_rfi_freq_table_resp_cmd *resp;
109 int resp_size = sizeof(*resp);
110 int ret;
111 struct iwl_host_cmd cmd = {
112 .id = WIDE_ID(SYSTEM_GROUP, RFI_GET_FREQ_TABLE_CMD),
113 .flags = CMD_WANT_SKB,
114 };
115
116 if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT))
117 return ERR_PTR(-EOPNOTSUPP);
118
119 mutex_lock(&mvm->mutex);
120 ret = iwl_mvm_send_cmd(mvm, &cmd);
121 mutex_unlock(&mvm->mutex);
122 if (ret)
123 return ERR_PTR(ret);
124
125 if (WARN_ON_ONCE(iwl_rx_packet_payload_len(cmd.resp_pkt) != resp_size))
126 return ERR_PTR(-EIO);
127
128 resp = kmemdup(cmd.resp_pkt->data, resp_size, GFP_KERNEL);
129 if (!resp)
130 return ERR_PTR(-ENOMEM);
131
132 iwl_free_resp(&cmd);
133 return resp;
134 }
135
iwl_rfi_deactivate_notif_handler(struct iwl_mvm * mvm,struct iwl_rx_cmd_buffer * rxb)136 void iwl_rfi_deactivate_notif_handler(struct iwl_mvm *mvm,
137 struct iwl_rx_cmd_buffer *rxb)
138 {
139 struct iwl_rx_packet *pkt = rxb_addr(rxb);
140 struct iwl_rfi_deactivate_notif *notif = (void *)pkt->data;
141
142 IWL_INFO(mvm, "RFIm is deactivated, reason = %d\n", notif->reason);
143 }
144