linux/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c
<<
>>
Prefs
   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 */
  14static const 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
  55int 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
  88struct 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}
 119