158 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause2/*3 * Copyright (C) 2020 - 2022 Intel Corporation4 */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 the12 * 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 now76 * it's always disabled.77 * When the platform support detection is implemented we should78 * 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}158