iwlwifi: mvm: rfi: don't lock mvm->mutex when sending config command
[linux-2.6-microblaze.git] / drivers / net / wireless / intel / iwlwifi / mvm / rfi.c
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 const static struct iwl_rfi_lut_entry iwl_rfi_table[IWL_RFI_LUT_SIZE] = {
15         /* LPDDR4 */
16
17         /* frequency 3733MHz */
18         {cpu_to_le16(223), {114, 116, 118, 120, 122,},
19               {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,}},
20
21         /* frequency 4267MHz */
22         {cpu_to_le16(256), {79, 83, 85, 87, 89, 91, 93,},
23                {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
24                 PHY_BAND_6, PHY_BAND_6,}},
25
26         /* DDR5ePOR */
27
28         /* frequency 4000MHz */
29         {cpu_to_le16(240), {3, 5, 7, 9, 11, 13, 15,},
30               {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
31                PHY_BAND_6, PHY_BAND_6,}},
32
33         /* frequency 4400MHz */
34         {cpu_to_le16(264), {111, 119, 123, 125, 129, 131, 133, 135, 143,},
35               {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
36                PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,}},
37
38         /* LPDDR5iPOR */
39
40         /* frequency 5200MHz */
41         {cpu_to_le16(312), {36, 38, 40, 42, 50,},
42                {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5,}},
43
44         /* frequency 6000MHz */
45         {cpu_to_le16(360), {3, 5, 7, 9, 11, 13, 15,},
46                {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
47                 PHY_BAND_6, PHY_BAND_6,}},
48
49         /* frequency 6400MHz */
50         {cpu_to_le16(384), {79, 83, 85, 87, 89, 91, 93,},
51                {PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6, PHY_BAND_6,
52                 PHY_BAND_6, PHY_BAND_6,}},
53 };
54
55 int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, struct iwl_rfi_lut_entry *rfi_table)
56 {
57         int ret;
58         struct iwl_rfi_config_cmd cmd;
59         struct iwl_host_cmd hcmd = {
60                 .id = WIDE_ID(SYSTEM_GROUP, RFI_CONFIG_CMD),
61                 .dataflags[0] = IWL_HCMD_DFL_DUP,
62                 .data[0] = &cmd,
63                 .len[0] = sizeof(cmd),
64         };
65
66         if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT))
67                 return -EOPNOTSUPP;
68
69         lockdep_assert_held(&mvm->mutex);
70
71         /* in case no table is passed, use the default one */
72         if (!rfi_table) {
73                 memcpy(cmd.table, iwl_rfi_table, sizeof(cmd.table));
74         } else {
75                 memcpy(cmd.table, rfi_table, sizeof(cmd.table));
76                 /* notify FW the table is not the default one */
77                 cmd.oem = 1;
78         }
79
80         ret = iwl_mvm_send_cmd(mvm, &hcmd);
81
82         if (ret)
83                 IWL_ERR(mvm, "Failed to send RFI config cmd %d\n", ret);
84
85         return ret;
86 }
87
88 struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm)
89 {
90         struct iwl_rfi_freq_table_resp_cmd *resp;
91         int resp_size = sizeof(*resp);
92         int ret;
93         struct iwl_host_cmd cmd = {
94                 .id = WIDE_ID(SYSTEM_GROUP, RFI_GET_FREQ_TABLE_CMD),
95                 .flags = CMD_WANT_SKB,
96         };
97
98         if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT))
99                 return ERR_PTR(-EOPNOTSUPP);
100
101         mutex_lock(&mvm->mutex);
102         ret = iwl_mvm_send_cmd(mvm, &cmd);
103         mutex_unlock(&mvm->mutex);
104         if (ret)
105                 return ERR_PTR(ret);
106
107         if (WARN_ON_ONCE(iwl_rx_packet_payload_len(cmd.resp_pkt) != resp_size))
108                 return ERR_PTR(-EIO);
109
110         resp = kzalloc(resp_size, GFP_KERNEL);
111         if (!resp)
112                 return ERR_PTR(-ENOMEM);
113
114         memcpy(resp, cmd.resp_pkt->data, resp_size);
115
116         iwl_free_resp(&cmd);
117         return resp;
118 }