new file mode 100644
@@ -0,0 +1,401 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/* Copyright(c) 2019-2022, Celeno Communications Ltd. */
+
+#ifndef CL_CHANNEL_H
+#define CL_CHANNEL_H
+
+#include <linux/types.h>
+#include <uapi/linux/nl80211.h>
+#include <net/cfg80211.h>
+
+#include "def.h"
+
+enum bitmap_chan_idx_6g {
+ b6g_ch1,
+ b6g_ch2,
+ b6g_ch5,
+ b6g_ch9,
+ b6g_ch13,
+ b6g_ch17,
+ b6g_ch21,
+ b6g_ch25,
+ b6g_ch29,
+ b6g_ch33,
+ b6g_ch37,
+ b6g_ch41,
+ b6g_ch45,
+ b6g_ch49,
+ b6g_ch53,
+ b6g_ch57,
+ b6g_ch61,
+ b6g_ch65,
+ b6g_ch69,
+ b6g_ch73,
+ b6g_ch77,
+ b6g_ch81,
+ b6g_ch85,
+ b6g_ch89,
+ b6g_ch93,
+ b6g_ch97,
+ b6g_ch101,
+ b6g_ch105,
+ b6g_ch109,
+ b6g_ch113,
+ b6g_ch117,
+ b6g_ch121,
+ b6g_ch125,
+ b6g_ch129,
+ b6g_ch133,
+ b6g_ch137,
+ b6g_ch141,
+ b6g_ch145,
+ b6g_ch149,
+ b6g_ch153,
+ b6g_ch157,
+ b6g_ch161,
+ b6g_ch165,
+ b6g_ch169,
+ b6g_ch173,
+ b6g_ch177,
+ b6g_ch181,
+ b6g_ch185,
+ b6g_ch189,
+ b6g_ch193,
+ b6g_ch197,
+ b6g_ch201,
+ b6g_ch205,
+ b6g_ch209,
+ b6g_ch213,
+ b6g_ch217,
+ b6g_ch221,
+ b6g_ch225,
+ b6g_ch229,
+ b6g_ch233,
+
+ NUM_BITMAP_CHANNELS_6G
+};
+
+enum ext_chan_idx_6g {
+ ext_b6g_ch1,
+ ext_b6g_ch2,
+ ext_b6g_ch3,
+ ext_b6g_ch5,
+ ext_b6g_ch7,
+ ext_b6g_ch9,
+ ext_b6g_ch11,
+ ext_b6g_ch13,
+ ext_b6g_ch15,
+ ext_b6g_ch17,
+ ext_b6g_ch19,
+ ext_b6g_ch21,
+ ext_b6g_ch23,
+ ext_b6g_ch25,
+ ext_b6g_ch27,
+ ext_b6g_ch29,
+ ext_b6g_ch31,
+ ext_b6g_ch33,
+ ext_b6g_ch35,
+ ext_b6g_ch37,
+ ext_b6g_ch39,
+ ext_b6g_ch41,
+ ext_b6g_ch43,
+ ext_b6g_ch45,
+ ext_b6g_ch47,
+ ext_b6g_ch49,
+ ext_b6g_ch51,
+ ext_b6g_ch53,
+ ext_b6g_ch55,
+ ext_b6g_ch57,
+ ext_b6g_ch59,
+ ext_b6g_ch61,
+ ext_b6g_ch63,
+ ext_b6g_ch65,
+ ext_b6g_ch67,
+ ext_b6g_ch69,
+ ext_b6g_ch71,
+ ext_b6g_ch73,
+ ext_b6g_ch75,
+ ext_b6g_ch77,
+ ext_b6g_ch79,
+ ext_b6g_ch81,
+ ext_b6g_ch83,
+ ext_b6g_ch85,
+ ext_b6g_ch87,
+ ext_b6g_ch89,
+ ext_b6g_ch91,
+ ext_b6g_ch93,
+ ext_b6g_ch95,
+ ext_b6g_ch97,
+ ext_b6g_ch99,
+ ext_b6g_ch101,
+ ext_b6g_ch103,
+ ext_b6g_ch105,
+ ext_b6g_ch107,
+ ext_b6g_ch109,
+ ext_b6g_ch111,
+ ext_b6g_ch113,
+ ext_b6g_ch115,
+ ext_b6g_ch117,
+ ext_b6g_ch119,
+ ext_b6g_ch121,
+ ext_b6g_ch123,
+ ext_b6g_ch125,
+ ext_b6g_ch127,
+ ext_b6g_ch129,
+ ext_b6g_ch131,
+ ext_b6g_ch133,
+ ext_b6g_ch135,
+ ext_b6g_ch137,
+ ext_b6g_ch139,
+ ext_b6g_ch141,
+ ext_b6g_ch143,
+ ext_b6g_ch145,
+ ext_b6g_ch147,
+ ext_b6g_ch149,
+ ext_b6g_ch151,
+ ext_b6g_ch153,
+ ext_b6g_ch155,
+ ext_b6g_ch157,
+ ext_b6g_ch159,
+ ext_b6g_ch161,
+ ext_b6g_ch163,
+ ext_b6g_ch165,
+ ext_b6g_ch167,
+ ext_b6g_ch169,
+ ext_b6g_ch171,
+ ext_b6g_ch173,
+ ext_b6g_ch175,
+ ext_b6g_ch177,
+ ext_b6g_ch179,
+ ext_b6g_ch181,
+ ext_b6g_ch183,
+ ext_b6g_ch185,
+ ext_b6g_ch187,
+ ext_b6g_ch189,
+ ext_b6g_ch191,
+ ext_b6g_ch193,
+ ext_b6g_ch195,
+ ext_b6g_ch197,
+ ext_b6g_ch199,
+ ext_b6g_ch201,
+ ext_b6g_ch203,
+ ext_b6g_ch205,
+ ext_b6g_ch207,
+ ext_b6g_ch209,
+ ext_b6g_ch211,
+ ext_b6g_ch213,
+ ext_b6g_ch215,
+ ext_b6g_ch217,
+ ext_b6g_ch219,
+ ext_b6g_ch221,
+ ext_b6g_ch223,
+ ext_b6g_ch225,
+ ext_b6g_ch227,
+ ext_b6g_ch229,
+ ext_b6g_ch231,
+ ext_b6g_ch233,
+
+ NUM_EXT_CHANNELS_6G
+};
+
+enum chan_idx_5g {
+ b5g_ch36,
+ b5g_ch38,
+ b5g_ch40,
+ b5g_ch42,
+ b5g_ch44,
+ b5g_ch46,
+ b5g_ch48,
+ b5g_ch50,
+ b5g_ch52,
+ b5g_ch54,
+ b5g_ch56,
+ b5g_ch58,
+ b5g_ch60,
+ b5g_ch62,
+ b5g_ch64,
+ b5g_ch100,
+ b5g_ch102,
+ b5g_ch104,
+ b5g_ch106,
+ b5g_ch108,
+ b5g_ch110,
+ b5g_ch112,
+ b5g_ch114,
+ b5g_ch116,
+ b5g_ch118,
+ b5g_ch120,
+ b5g_ch122,
+ b5g_ch124,
+ b5g_ch126,
+ b5g_ch128,
+ b5g_ch132,
+ b5g_ch134,
+ b5g_ch136,
+ b5g_ch138,
+ b5g_ch140,
+ b5g_ch142,
+ b5g_ch144,
+ b5g_ch149,
+ b5g_ch151,
+ b5g_ch153,
+ b5g_ch155,
+ b5g_ch157,
+ b5g_ch159,
+ b5g_ch161,
+ b5g_ch165,
+
+ NUM_CHANNELS_5G
+};
+
+enum chan_idx_24g {
+ b24g_ch1,
+ b24g_ch2,
+ b24g_ch3,
+ b24g_ch4,
+ b24g_ch5,
+ b24g_ch6,
+ b24g_ch7,
+ b24g_ch8,
+ b24g_ch9,
+ b24g_ch10,
+ b24g_ch11,
+ b24g_ch12,
+ b24g_ch13,
+ b24g_ch14,
+
+ NUM_CHANNELS_24G
+};
+
+/* 6g band has the largest list */
+#define MAX_CHANNELS NUM_BITMAP_CHANNELS_6G
+#define MAX_EXT_CHANNELS NUM_EXT_CHANNELS_6G
+#define START_CHAN_IDX_6G 1
+
+/* 1 ==> 5955 */
+#define FREQ6G(_chan) ((_chan) == 2 ? 5935 : 5950 + 5 * (_chan))
+/* 36 ==> 5180 */
+#define FREQ5G(_chan) (5000 + 5 * (_chan))
+/* 1 ==> 2412 */
+#define FREQ2G(_chan) ((_chan) == 14 ? 2484 : 2407 + (_chan) * 5)
+#define CHAN_BITMAP_IDX_6G_2_EXT_IDX(_idx) ((_idx) ? ((_idx) << 1) - 1 : 0)
+#define CHAN_EXT_IDX_6G_2_BITMAP_IDX(_ext_idx) (((_ext_idx) + 1) >> 1)
+
+/* 6G channels - UNII-5 */
+#define START_CHAN_IDX_UNII5 1
+#define END_CHAN_IDX_UNII5 85
+/* 6G channels - UNII-6 */
+#define START_CHAN_IDX_UNII6 89
+#define END_CHAN_IDX_UNII6 109
+/* 6G channels - UNII-7 */
+#define START_CHAN_IDX_UNII7 113
+#define END_CHAN_IDX_UNII7 165
+/* 6G channels - UNII-8 */
+#define START_CHAN_IDX_UNII8 169
+#define END_CHAN_IDX_UNII8 233
+
+#define INVALID_CHAN_IDX 0xff
+
+#ifndef IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS
+#define IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS 600000
+#endif
+
+struct cl_hw;
+
+u8 cl_channel_to_ext_index_6g(struct cl_hw *cl_hw, u32 channel);
+u8 cl_channel_to_index(struct cl_hw *cl_hw, u32 channel);
+u8 cl_channel_to_bitmap_index(struct cl_hw *cl_hw, u32 channel);
+u16 cl_channel_ext_idx_to_freq_6g(struct cl_hw *cl_hw, u8 index);
+u16 cl_channel_idx_to_freq(struct cl_hw *cl_hw, u8 index);
+bool cl_channel_is_valid(struct cl_hw *cl_hw, u8 channel);
+u32 cl_channel_num(struct cl_hw *cl_hw);
+bool cl_channel_is_dfs(struct cl_hw *cl_hw, u8 channel);
+u32 cl_channel_get_cac_time_ms(struct cl_hw *cl_hw, u8 channel);
+
+#define CL_MAX_STR_BUFFER_SIZE 1024
+
+#define CL_DEFAULT_CHANNEL_POWER_Q8 (30 << 8)
+
+#define CL_20MHZ_CH_GAP 4
+#define CL_40MHZ_CH_GAP 8
+#define CL_80MHZ_CH_GAP 16
+#define CL_160MHZ_CH_GAP 32
+#define CL_40MHZ_HOP 2
+#define CL_80MHZ_HOP 4
+#define CL_160MHZ_HOP 8
+
+struct cl_chan_info {
+ u8 channel;
+ u8 max_bw;
+ /* Resolution of 0.25dB */
+ u8 max_power_q2; /* MIN(country_max_power_q2, hardware_max_power_q2) */
+ u8 country_max_power_q2;
+ u8 hardware_max_power_q2;
+ u32 flags; /* channel flags from &enum ieee80211_channel_flags */
+ unsigned int dfs_cac_ms;
+};
+
+struct cl_channel_info {
+ bool use_channel_info;
+ struct cl_chan_info channels[CHNL_BW_MAX][MAX_CHANNELS];
+ enum nl80211_dfs_regions standard;
+ struct ieee80211_regdomain *rd;
+};
+
+void cl_chan_info_init(struct cl_hw *cl_hw);
+void cl_chan_info_deinit(struct cl_hw *cl_hw);
+struct cl_chan_info *cl_chan_info_get(struct cl_hw *cl_hw, u8 channel, u8 bw);
+u8 cl_chan_info_get_max_bw(struct cl_hw *cl_hw, u8 channel);
+s16 cl_chan_info_get_eirp_limit_q8(struct cl_hw *cl_hw, u8 bw);
+u8 cl_chan_info_get_max_power(struct cl_hw *cl_hw, u8 channel);
+void cl_chan_update_channels_info(struct cl_hw *cl_hw,
+ const struct ieee80211_supported_band *cfg_band);
+int cl_chandef_calc(struct cl_hw *cl_hw, u32 channel, u32 bw,
+ enum nl80211_chan_width *width, u32 *primary, u32 *center);
+int cl_chandef_get_default(struct cl_hw *cl_hw, u32 *channel, u8 *bw,
+ enum nl80211_chan_width *width,
+ u32 *primary, u32 *center);
+
+struct cl_channel_stats {
+ bool scan_enabled;
+ u8 channel;
+ enum cl_channel_bw scan_bw;
+
+ s8 avg_snr;
+ s8 avg_non_wifi_noise;
+ u32 avg_channel_util;
+ u32 avg_retry_rate;
+ u32 total_frames;
+ u32 total_retries;
+ u32 vendor_specific;
+
+ /* Time radio spent rx on channel + non wifi noise */
+ u64 edca_cca_time;
+ u64 edca_cca_time_total;
+
+ /* Time radio detected that channel was busy (Busy = Rx + Tx + Interference) */
+ u64 util_time_busy;
+
+ /* Time radio spent tx on channel */
+ u64 util_time_tx;
+ u64 util_time_tx_total;
+
+ /* Time radio spent rx on channel (Rx = Rx_obss + Rx_self + Rx_errr (self and obss errs) */
+ u64 util_time_rx;
+ u64 util_time_rx_total;
+
+ s8 ch_noise;
+
+ u64 scan_start_jiffies;
+ u32 scan_time_ms;
+
+ /* Currently this metric can't be calculated because fromat_mod in rxheader is always 0 */
+ /* u64 util_time_self; */
+};
+
+int cl_init_channel_stats(struct cl_hw *cl_hw,
+ struct cl_channel_stats *ch_stats, u32 freq);
+void cl_get_final_channel_stats(struct cl_hw *cl_hw, struct cl_channel_stats *ch_stats);
+void cl_get_initial_channel_stats(struct cl_hw *cl_hw, struct cl_channel_stats *ch_stats);
+
+#endif /* CL_CHANNEL_H */