ath10k: add support to configure BB timing over wmi

Add wmi configuration cmd to configure base band(BB) power amplifier(PA)
off timing values in hardware. The default PA off timings were fine tuned
to make proper DFS radar detection in QCA reference design. If ODM uses
different PA in their design, then the same default PA off timing values
cannot be used, it requires different settling time to detect radar pulses
very sooner and avoid radar detection problems. In that case it provides
provision to select proper PA off timing values based on the PA hardware used.
The PA component is part of FEM hardware and new device tree entry
"ext-fem-name" is used to indentify the FEM hardware. And this wmi configuration
cmd is enabled via wmi service flag "WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT".

Other way is to apply these values through calibration data, but recalibration
of all boards out there might not be feasible.

This change tested on firmware ver 10.2.4-1.0-00042 in QCA988X chipset.

Signed-off-by: Bhagavathi Perumal S <bperumal@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Bhagavathi Perumal S
2018-12-20 14:26:00 +02:00
committed by Kalle Valo
parent f3f587995c
commit 84758d4d43
4 changed files with 116 additions and 0 deletions

View File

@@ -22,6 +22,7 @@
#include <net/mac80211.h>
#include <linux/etherdevice.h>
#include <linux/acpi.h>
#include <linux/of.h>
#include "hif.h"
#include "core.h"
@@ -4637,11 +4638,44 @@ static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
return ret;
}
static int __ath10k_fetch_bb_timing_dt(struct ath10k *ar,
struct wmi_bb_timing_cfg_arg *bb_timing)
{
struct device_node *node;
const char *fem_name;
int ret;
node = ar->dev->of_node;
if (!node)
return -ENOENT;
ret = of_property_read_string_index(node, "ext-fem-name", 0, &fem_name);
if (ret)
return -ENOENT;
/*
* If external Front End module used in hardware, then default base band timing
* parameter cannot be used since they were fine tuned for reference hardware,
* so choosing different value suitable for that external FEM.
*/
if (!strcmp("microsemi-lx5586", fem_name)) {
bb_timing->bb_tx_timing = 0x00;
bb_timing->bb_xpa_timing = 0x0101;
} else {
return -ENOENT;
}
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot bb_tx_timing 0x%x bb_xpa_timing 0x%x\n",
bb_timing->bb_tx_timing, bb_timing->bb_xpa_timing);
return 0;
}
static int ath10k_start(struct ieee80211_hw *hw)
{
struct ath10k *ar = hw->priv;
u32 param;
int ret = 0;
struct wmi_bb_timing_cfg_arg bb_timing = {0};
/*
* This makes sense only when restarting hw. It is harmless to call
@@ -4796,6 +4830,19 @@ static int ath10k_start(struct ieee80211_hw *hw)
clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
}
if (test_bit(WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, ar->wmi.svc_map)) {
ret = __ath10k_fetch_bb_timing_dt(ar, &bb_timing);
if (!ret) {
ret = ath10k_wmi_pdev_bb_timing(ar, &bb_timing);
if (ret) {
ath10k_warn(ar,
"failed to set bb timings: %d\n",
ret);
goto err_core_stop;
}
}
}
ar->num_started_vdevs = 0;
ath10k_regd_update(ar);