diff mbox series

[RFC,v2,10/96] cl8k: add calib.h

Message ID 20220524113502.1094459-11-viktor.barna@celeno.com
State New
Headers show
Series wireless: cl8k driver for Celeno IEEE 802.11ax devices | expand

Commit Message

Viktor Barna May 24, 2022, 11:33 a.m. UTC
From: Viktor Barna <viktor.barna@celeno.com>

(Part of the split. Please, take a look at the cover letter for more
details).

Signed-off-by: Viktor Barna <viktor.barna@celeno.com>
---
 drivers/net/wireless/celeno/cl8k/calib.h | 390 +++++++++++++++++++++++
 1 file changed, 390 insertions(+)
 create mode 100644 drivers/net/wireless/celeno/cl8k/calib.h
diff mbox series

Patch

diff --git a/drivers/net/wireless/celeno/cl8k/calib.h b/drivers/net/wireless/celeno/cl8k/calib.h
new file mode 100644
index 000000000000..6eb286392dd6
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/calib.h
@@ -0,0 +1,390 @@ 
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/* Copyright(c) 2019-2022, Celeno Communications Ltd. */
+
+#ifndef CL_CALIB_H
+#define CL_CALIB_H
+
+#include <linux/workqueue.h>
+#include <net/cfg80211.h>
+
+#include "def.h"
+
+#define DCOC_LNA_GAIN_NUM     8
+#define MAX_SX                2
+#define IQ_NUM_TONES_REQ      8
+#define IQ_NUM_TONES_CFM      (2 * IQ_NUM_TONES_REQ)
+#define SINGLETONS_MAX_NUM    1
+#define LOOPS_MAX_NUM         (2 + SINGLETONS_MAX_NUM) /* 1: pre,2-11:singletone,12:post */
+#define SX_FREQ_OFFSET_Q2     5
+
+enum calib_cfm_id_type {
+	CALIB_CFM_DCOC,
+	CALIB_CFM_IQ,
+	CALIB_CFM_MAX
+};
+
+enum calib_channel_idx_24g {
+	CALIB_CHAN_24G_1,
+	CALIB_CHAN_24G_6,
+	CALIB_CHAN_24G_11,
+	CALIB_CHAN_24G_MAX,
+};
+
+enum calib_channel_idx_5g {
+	CALIB_CHAN_5G_36,
+	CALIB_CHAN_5G_40,
+	CALIB_CHAN_5G_44,
+	CALIB_CHAN_5G_48,
+	CALIB_CHAN_5G_52,
+	CALIB_CHAN_5G_56,
+	CALIB_CHAN_5G_60,
+	CALIB_CHAN_5G_64,
+	CALIB_CHAN_5G_100,
+	CALIB_CHAN_5G_104,
+	CALIB_CHAN_5G_108,
+	CALIB_CHAN_5G_112,
+	CALIB_CHAN_5G_116,
+	CALIB_CHAN_5G_120,
+	CALIB_CHAN_5G_124,
+	CALIB_CHAN_5G_128,
+	CALIB_CHAN_5G_132,
+	CALIB_CHAN_5G_136,
+	CALIB_CHAN_5G_140,
+	CALIB_CHAN_5G_144,
+	CALIB_CHAN_5G_149,
+	CALIB_CHAN_5G_153,
+	CALIB_CHAN_5G_157,
+	CALIB_CHAN_5G_161,
+	CALIB_CHAN_5G_165,
+	CALIB_CHAN_5G_MAX
+};
+
+enum calib_channel_idx_6g {
+	CALIB_CHAN_6G_1,
+	CALIB_CHAN_6G_5,
+	CALIB_CHAN_6G_9,
+	CALIB_CHAN_6G_13,
+	CALIB_CHAN_6G_17,
+	CALIB_CHAN_6G_21,
+	CALIB_CHAN_6G_25,
+	CALIB_CHAN_6G_29,
+	CALIB_CHAN_6G_33,
+	CALIB_CHAN_6G_37,
+	CALIB_CHAN_6G_41,
+	CALIB_CHAN_6G_45,
+	CALIB_CHAN_6G_49,
+	CALIB_CHAN_6G_53,
+	CALIB_CHAN_6G_57,
+	CALIB_CHAN_6G_61,
+	CALIB_CHAN_6G_65,
+	CALIB_CHAN_6G_69,
+	CALIB_CHAN_6G_73,
+	CALIB_CHAN_6G_77,
+	CALIB_CHAN_6G_81,
+	CALIB_CHAN_6G_85,
+	CALIB_CHAN_6G_89,
+	CALIB_CHAN_6G_93,
+	CALIB_CHAN_6G_97,
+	CALIB_CHAN_6G_101,
+	CALIB_CHAN_6G_105,
+	CALIB_CHAN_6G_109,
+	CALIB_CHAN_6G_113,
+	CALIB_CHAN_6G_117,
+	CALIB_CHAN_6G_121,
+	CALIB_CHAN_6G_125,
+	CALIB_CHAN_6G_129,
+	CALIB_CHAN_6G_133,
+	CALIB_CHAN_6G_137,
+	CALIB_CHAN_6G_141,
+	CALIB_CHAN_6G_145,
+	CALIB_CHAN_6G_149,
+	CALIB_CHAN_6G_153,
+	CALIB_CHAN_6G_157,
+	CALIB_CHAN_6G_161,
+	CALIB_CHAN_6G_165,
+	CALIB_CHAN_6G_169,
+	CALIB_CHAN_6G_173,
+	CALIB_CHAN_6G_177,
+	CALIB_CHAN_6G_181,
+	CALIB_CHAN_6G_185,
+	CALIB_CHAN_6G_189,
+	CALIB_CHAN_6G_193,
+	CALIB_CHAN_6G_197,
+	CALIB_CHAN_6G_201,
+	CALIB_CHAN_6G_205,
+	CALIB_CHAN_6G_209,
+	CALIB_CHAN_6G_213,
+	CALIB_CHAN_6G_217,
+	CALIB_CHAN_6G_221,
+	CALIB_CHAN_6G_225,
+	CALIB_CHAN_6G_229,
+	CALIB_CHAN_6G_233,
+	CALIB_CHAN_6G_MAX,
+};
+
+/* MAX(CALIB_CHAN_24G_MAX, CALIB_CHAN_5G_MAX, CALIB_CHAN_6G_MAX) */
+#define CALIB_CHAN_MAX CALIB_CHAN_6G_MAX
+
+struct cl_dcoc_calib {
+	s8 i;
+	s8 q;
+};
+
+struct cl_dcoc_report {
+	__le16 i_dc;
+	__le16 i_iterations;
+	__le16 q_dc;
+	__le16 q_iterations;
+};
+
+struct cl_iq_report {
+	u8 status;
+	__le16 amplitude_mismatch[IQ_NUM_TONES_CFM];
+	__le16 phase_mismatch[IQ_NUM_TONES_CFM];
+	s8 ir_db[LOOPS_MAX_NUM][IQ_NUM_TONES_CFM];
+	s8 ir_db_avg_post;
+};
+
+struct cl_iq_calib {
+	__le32 coef0;
+	__le32 coef1;
+	__le32 coef2;
+	__le32 gain;
+};
+
+struct cl_lolc_report {
+	u8 status;
+	u8 n_iter;
+	__le16 lolc_qual;
+};
+
+struct cl_gain_report {
+	u8 status;
+	u8 rx_gain;
+	u8 tx_gain;
+	u8 gain_quality;
+	__le16 final_p2p;
+	__le16 initial_p2p;
+};
+
+struct cl_iq_dcoc_conf {
+	bool dcoc_calib_needed[TCV_MAX];
+	u8 dcoc_file_num_ant[TCV_MAX];
+	bool iq_calib_needed;
+	u8 iq_file_num_ant[TCV_MAX];
+	bool force_calib;
+};
+
+struct cl_iq_dcoc_info {
+	struct cl_dcoc_calib dcoc[DCOC_LNA_GAIN_NUM][MAX_ANTENNAS];
+	struct cl_iq_calib iq_tx[MAX_ANTENNAS];
+	__le32 iq_tx_lolc[MAX_ANTENNAS];
+	struct cl_iq_calib iq_rx[MAX_ANTENNAS];
+};
+
+struct cl_iq_dcoc_report {
+	struct cl_dcoc_report dcoc[DCOC_LNA_GAIN_NUM][MAX_ANTENNAS];
+	struct cl_gain_report gain_tx[MAX_ANTENNAS];
+	struct cl_gain_report gain_rx[MAX_ANTENNAS];
+	struct cl_lolc_report lolc_report[MAX_ANTENNAS];
+	struct cl_iq_report iq_tx[MAX_ANTENNAS];
+	struct cl_iq_report iq_rx[MAX_ANTENNAS];
+};
+
+struct calib_cfm {
+	u8 status;
+	__le16 raw_bits_data_0;
+	__le16 raw_bits_data_1;
+};
+
+struct cl_iq_dcoc_data {
+	struct cl_iq_dcoc_info iq_dcoc_db;
+	struct cl_iq_dcoc_report report;
+	struct calib_cfm dcoc_iq_cfm[CALIB_CFM_MAX];
+};
+
+struct cl_iq_dcoc_data_info {
+	struct cl_iq_dcoc_data *iq_dcoc_data;
+	u32 dma_addr;
+};
+
+struct cl_calib_params {
+	u8 mode;
+	bool first_channel;
+	s8 sx_freq_offset_mhz;
+	u32 plan_bitmap;
+};
+
+struct cl_calib_work {
+	struct work_struct ws;
+	struct cl_hw *cl_hw;
+};
+
+struct cl_calib_chain {
+	u8 pair;
+	u8 initial_tx_gain;
+	u8 initial_rx_gain;
+};
+
+enum cl_calib_flags {
+	CALIB_FLAG_CREATE = 1 << 0,
+	CALIB_FLAG_VERSION = 1 << 1,
+	CALIB_FLAG_TITLE = 1 << 2,
+	CALIB_FLAG_HEADER_TCV0 = 1 << 3,
+	CALIB_FLAG_HEADER_TCV1 = 1 << 4,
+
+	CALIB_FLAG_HEADER_TCV01 = (CALIB_FLAG_HEADER_TCV0 |
+				   CALIB_FLAG_HEADER_TCV1),
+	CALIB_FLAG_ALL_REPORT = (CALIB_FLAG_CREATE |
+				 CALIB_FLAG_VERSION |
+				 CALIB_FLAG_TITLE),
+	CALIB_FLAG_ALL = (CALIB_FLAG_CREATE |
+			  CALIB_FLAG_VERSION |
+			  CALIB_FLAG_TITLE |
+			  CALIB_FLAG_HEADER_TCV0 |
+			  CALIB_FLAG_HEADER_TCV1)
+};
+
+struct cl_calib_file_flags {
+	u8 dcoc;
+	u8 dcoc_report;
+	u8 lolc;
+	u8 lolc_report;
+	u8 iq_tx;
+	u8 iq_tx_report;
+	u8 iq_rx;
+	u8 iq_rx_report;
+	u8 rx_gain_report;
+	bool iq_plan;
+};
+
+struct cl_calib_errors {
+	u16 dcoc;
+	u16 lolc;
+	u16 iq_tx;
+	u16 iq_rx;
+};
+
+struct cl_calib_db {
+	struct cl_dcoc_calib
+		dcoc[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX][MAX_SX][MAX_ANTENNAS][DCOC_LNA_GAIN_NUM];
+	u32 iq_tx_lolc[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX][MAX_SX][MAX_ANTENNAS];
+	struct cl_iq_calib iq_tx[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX][MAX_SX][MAX_ANTENNAS];
+	struct cl_iq_calib iq_rx[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX][MAX_SX][MAX_ANTENNAS];
+	struct cl_calib_file_flags file_flags;
+	struct cl_calib_errors errors[TCV_MAX];
+	struct list_head plan[TCV_MAX][CALIB_CHAN_MAX][CHNL_BW_MAX];
+	bool is_plan_initialized;
+};
+
+#define SET_PHY_DATA_FLAGS_DCOC       0x1 /* Set DCOC calibration data.*/
+#define SET_PHY_DATA_FLAGS_IQ_TX      0x2 /* Set IQ Tx calibration data.*/
+#define SET_PHY_DATA_FLAGS_IQ_RX      0x4 /* Set IQ Rx calibration data.*/
+#define SET_PHY_DATA_FLAGS_IQ_TX_LOLC 0x8 /* Set IQ Tx LOLC calibration data.*/
+#define SET_PHY_DATA_FLAGS_ALL ( \
+	SET_PHY_DATA_FLAGS_DCOC | \
+	SET_PHY_DATA_FLAGS_IQ_TX | \
+	SET_PHY_DATA_FLAGS_IQ_RX | \
+	SET_PHY_DATA_FLAGS_IQ_TX_LOLC)
+#define SET_PHY_DATA_FLAGS_LISTENER ( \
+	SET_PHY_DATA_FLAGS_DCOC | \
+	SET_PHY_DATA_FLAGS_IQ_RX)
+
+#define CL_CALIB_PARAMS_DEFAULT_STRUCT \
+	((struct cl_calib_params){SET_CHANNEL_MODE_OPERETIONAL, false, 0, 0})
+
+#define CALIB_CHAN_5G_PLAN 6
+#define CALIB_CHAN_6G_PLAN 15
+
+struct cl_chip;
+
+void cl_calib_dcoc_init_calibration(struct cl_hw *cl_hw);
+u8 cl_calib_dcoc_channel_bw_to_idx(struct cl_hw *cl_hw, u8 channel, u8 bw);
+void cl_calib_dcoc_fill_data(struct cl_hw *cl_hw, struct cl_iq_dcoc_info *iq_dcoc_db);
+u8 cl_calib_dcoc_tcv_channel_to_idx(struct cl_chip *chip, u8 tcv_idx, u8 channel, u8 bw);
+void cl_calib_dcoc_handle_set_channel_cfm(struct cl_hw *cl_hw, bool first_channel);
+void cl_calib_common_start_work(struct cl_hw *cl_hw);
+void cl_calib_common_fill_phy_data(struct cl_hw *cl_hw, struct cl_iq_dcoc_info *iq_dcoc_db,
+				   u8 flags);
+int cl_calib_common_tables_alloc(struct cl_hw *cl_hw);
+void cl_calib_common_tables_free(struct cl_hw *cl_hw);
+int cl_calib_common_handle_set_channel_cfm(struct cl_hw *cl_hw,
+					   struct cl_calib_params calib_params);
+int cl_calib_common_check_errors(struct cl_hw *cl_hw);
+s16 cl_calib_common_get_temperature(struct cl_hw *cl_hw, u8 cfm_type);
+
+/* Calibration constants */
+#define CALIB_TX_GAIN_DEFAULT        (0x75)
+#define GAIN_SLEEVE_TRSHLD_DEFAULT   (2)
+#define CALIB_NCO_AMP_DEFAULT        (-10)
+#define CALIB_NCO_FREQ_DEFAULT       (16)       /* 5M/312.5K for LO & RGC */
+#define LO_P_THRESH                  (1000000)
+#define N_SAMPLES_EXP_LOLC           (13)
+#define N_SAMPLES_EXP_IQC            (13)
+#define N_BIT_FIR_SCALE              (11)
+#define N_BIT_AMP_SCALE              (10)
+#define N_BIT_PHASE_SCALE            (10)
+#define GP_RAD_TRSHLD_DEFAULT        (1144) /* Represents 1 degree in Q(16,16): 1*(pi/180) */
+#define GA_LIN_UPPER_TRSHLD_DEFAULT  (66295) /* Represents 0.1 db in Q(16,16): 10^( 0.1/20)*2^16 */
+#define GA_LIN_LOWER_TRSHLD_DEFAULT  (64786) /* Represents -0.1 db in Q(16,16): 10^(-0.1/20)*2^16 */
+#define COMP_FILTER_LEN_DEFAULT      (9)
+#define SINGLETONS_NUM_DEFAULT       (10) /* Set to SINGLETONS_MAX_NUM for now */
+#define IQ_POST_IDX                  (LOOPS_MAX_NUM - 1)
+#define RAMPUP_TIME                  (50)
+#define LO_COARSE_STEP               (20)
+#define LO_FINE_STEP                 (1)
+
+#define DCOC_MAX_VGA                      0x14
+#define CALIB_RX_GAIN_DEFAULT             0x83
+#define CALIB_RX_GAIN_UPPER_LIMIT         0x14
+#define CALIB_RX_GAIN_LOWER_LIMIT         0x0
+#define DCOC_MAX_VGA_ATHOS                0x1E
+#define CALIB_RX_GAIN_DEFAULT_ATHOS       0x8D
+#define CALIB_RX_GAIN_UPPER_LIMIT_ATHOS   0x1E
+#define CALIB_RX_GAIN_LOWER_LIMIT_ATHOS   0x0A
+#define DCOC_MAX_VGA_ATHOS_B              0x14
+#define CALIB_RX_GAIN_DEFAULT_ATHOS_B     0x81
+#define CALIB_RX_GAIN_UPPER_LIMIT_ATHOS_B 0x14
+#define CALIB_RX_GAIN_LOWER_LIMIT_ATHOS_B 0x0
+
+struct cl_calib_iq_restore {
+	u8 bw;
+	u32 primary;
+	u32 center;
+	u8 channel;
+};
+
+bool cl_calib_iq_calibration_needed(struct cl_hw *cl_hw);
+void cl_calib_iq_file_flags_clear(struct cl_chip *chip);
+void cl_calib_iq_file_flags_set(struct cl_chip *chip);
+int cl_calib_iq_post_read_actions(struct cl_chip *chip, char *buf);
+void cl_calib_iq_init_calibration(struct cl_hw *cl_hw);
+void cl_calib_iq_fill_data(struct cl_hw *cl_hw, struct cl_iq_calib *iq_data,
+			   struct cl_iq_calib *iq_chip_data);
+void cl_calib_iq_lolc_fill_data(struct cl_hw *cl_hw, __le32 *iq_lolc);
+void cl_calib_iq_handle_set_channel_cfm(struct cl_hw *cl_hw, u8 plan_bitmap);
+void cl_calib_iq_lolc_handle_set_channel_cfm(struct cl_hw *cl_hw, u8 plan_bitmap);
+int cl_calib_iq_lolc_write_version(struct cl_hw *cl_hw);
+int cl_calib_iq_lolc_report_write_version(struct cl_hw *cl_hw);
+int cl_calib_iq_lolc_write_file(struct cl_hw *cl_hw, s32 *params);
+int cl_calib_iq_lolc_report_write_file(struct cl_hw *cl_hw, s32 *params);
+void cl_calib_iq_get_tone_vector(struct cl_hw *cl_hw, __le16 *tone_vector);
+void cl_calib_iq_init_production(struct cl_hw *cl_hw);
+int cl_calib_iq_set_idle(struct cl_hw *cl_hw, bool idle);
+void cl_calib_restore_channel(struct cl_hw *cl_hw, struct cl_calib_iq_restore *iq_restore);
+void cl_calib_save_channel(struct cl_hw *cl_hw, struct cl_calib_iq_restore *iq_restore);
+
+#define UNCALIBRATED_POWER        15
+#define UNCALIBRATED_POWER_OFFSET 0
+#define UNCALIBRATED_TEMPERATURE  35
+
+struct point;
+void cl_calib_power_read(struct cl_hw *cl_hw);
+void cl_calib_power_offset_fill(struct cl_hw *cl_hw, u8 channel,
+				u8 bw, u8 offset[MAX_ANTENNAS]);
+int cl_calib_runtime_and_switch_channel(struct cl_hw *cl_hw, u32 channel, u8 bw, u32 primary,
+					u32 center);
+void cl_calib_runtime_work(struct cl_hw *cl_hw, u32 channel, u8 bw, u16 primary, u16 center);
+bool cl_calib_runtime_is_allowed(struct cl_hw *cl_hw);
+
+#endif /* CL_CALIB_H */