From: Viktor Barna <viktor.barna@xxxxxxxxxx> (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna <viktor.barna@xxxxxxxxxx> --- drivers/net/wireless/celeno/cl8k/calib.h | 390 +++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/calib.h 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 */ -- 2.36.1