xref: /openbmc/linux/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h (revision 976e3645923bdd2fe7893aae33fd7a21098bfb28)
1*0e3d6777SRyder Lee /* SPDX-License-Identifier: ISC */
2e40803f2SLorenzo Bianconi /*
3e40803f2SLorenzo Bianconi  * Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
4e40803f2SLorenzo Bianconi  */
5e40803f2SLorenzo Bianconi 
6e40803f2SLorenzo Bianconi #ifndef __MT76x02_DFS_H
7e40803f2SLorenzo Bianconi #define __MT76x02_DFS_H
8e40803f2SLorenzo Bianconi 
9e40803f2SLorenzo Bianconi #include <linux/types.h>
10e40803f2SLorenzo Bianconi #include <linux/nl80211.h>
11e40803f2SLorenzo Bianconi 
12e40803f2SLorenzo Bianconi #define MT_DFS_GP_INTERVAL		(10 << 4) /* 64 us unit */
13e40803f2SLorenzo Bianconi #define MT_DFS_NUM_ENGINES		4
14e40803f2SLorenzo Bianconi 
15e40803f2SLorenzo Bianconi /* bbp params */
16e40803f2SLorenzo Bianconi #define MT_DFS_SYM_ROUND		0
17e40803f2SLorenzo Bianconi #define MT_DFS_DELTA_DELAY		2
18e40803f2SLorenzo Bianconi #define MT_DFS_VGA_MASK			0
19e40803f2SLorenzo Bianconi #define MT_DFS_PWR_GAIN_OFFSET		3
20e40803f2SLorenzo Bianconi #define MT_DFS_PWR_DOWN_TIME		0xf
21e40803f2SLorenzo Bianconi #define MT_DFS_RX_PE_MASK		0xff
22e40803f2SLorenzo Bianconi #define MT_DFS_PKT_END_MASK		0
23e40803f2SLorenzo Bianconi #define MT_DFS_CH_EN			0xf
24e40803f2SLorenzo Bianconi 
25e40803f2SLorenzo Bianconi /* sw detector params */
26e40803f2SLorenzo Bianconi #define MT_DFS_EVENT_LOOP		64
27e40803f2SLorenzo Bianconi #define MT_DFS_SW_TIMEOUT		(HZ / 20)
28e40803f2SLorenzo Bianconi #define MT_DFS_EVENT_WINDOW		(HZ / 5)
29e40803f2SLorenzo Bianconi #define MT_DFS_SEQUENCE_WINDOW		(200 * (1 << 20))
30e40803f2SLorenzo Bianconi #define MT_DFS_EVENT_TIME_MARGIN	2000
31e40803f2SLorenzo Bianconi #define MT_DFS_PRI_MARGIN		4
32e40803f2SLorenzo Bianconi #define MT_DFS_SEQUENCE_TH		6
33e40803f2SLorenzo Bianconi 
34e40803f2SLorenzo Bianconi #define MT_DFS_FCC_MAX_PRI		((28570 << 1) + 1000)
35e40803f2SLorenzo Bianconi #define MT_DFS_FCC_MIN_PRI		(3000 - 2)
36e40803f2SLorenzo Bianconi #define MT_DFS_JP_MAX_PRI		((80000 << 1) + 1000)
37e40803f2SLorenzo Bianconi #define MT_DFS_JP_MIN_PRI		(28500 - 2)
38e40803f2SLorenzo Bianconi #define MT_DFS_ETSI_MAX_PRI		(133333 + 125000 + 117647 + 1000)
39e40803f2SLorenzo Bianconi #define MT_DFS_ETSI_MIN_PRI		(4500 - 20)
40e40803f2SLorenzo Bianconi 
41e40803f2SLorenzo Bianconi struct mt76x02_radar_specs {
42e40803f2SLorenzo Bianconi 	u8 mode;
43e40803f2SLorenzo Bianconi 	u16 avg_len;
44e40803f2SLorenzo Bianconi 	u16 e_low;
45e40803f2SLorenzo Bianconi 	u16 e_high;
46e40803f2SLorenzo Bianconi 	u16 w_low;
47e40803f2SLorenzo Bianconi 	u16 w_high;
48e40803f2SLorenzo Bianconi 	u16 w_margin;
49e40803f2SLorenzo Bianconi 	u32 t_low;
50e40803f2SLorenzo Bianconi 	u32 t_high;
51e40803f2SLorenzo Bianconi 	u16 t_margin;
52e40803f2SLorenzo Bianconi 	u32 b_low;
53e40803f2SLorenzo Bianconi 	u32 b_high;
54e40803f2SLorenzo Bianconi 	u32 event_expiration;
55e40803f2SLorenzo Bianconi 	u16 pwr_jmp;
56e40803f2SLorenzo Bianconi };
57e40803f2SLorenzo Bianconi 
58e40803f2SLorenzo Bianconi #define MT_DFS_CHECK_EVENT(x)		((x) != GENMASK(31, 0))
59e40803f2SLorenzo Bianconi #define MT_DFS_EVENT_ENGINE(x)		(((x) & BIT(31)) ? 2 : 0)
60e40803f2SLorenzo Bianconi #define MT_DFS_EVENT_TIMESTAMP(x)	((x) & GENMASK(21, 0))
61e40803f2SLorenzo Bianconi #define MT_DFS_EVENT_WIDTH(x)		((x) & GENMASK(11, 0))
62e40803f2SLorenzo Bianconi struct mt76x02_dfs_event {
63e40803f2SLorenzo Bianconi 	unsigned long fetch_ts;
64e40803f2SLorenzo Bianconi 	u32 ts;
65e40803f2SLorenzo Bianconi 	u16 width;
66e40803f2SLorenzo Bianconi 	u8 engine;
67e40803f2SLorenzo Bianconi };
68e40803f2SLorenzo Bianconi 
69e40803f2SLorenzo Bianconi #define MT_DFS_EVENT_BUFLEN		256
70e40803f2SLorenzo Bianconi struct mt76x02_dfs_event_rb {
71e40803f2SLorenzo Bianconi 	struct mt76x02_dfs_event data[MT_DFS_EVENT_BUFLEN];
72e40803f2SLorenzo Bianconi 	int h_rb, t_rb;
73e40803f2SLorenzo Bianconi };
74e40803f2SLorenzo Bianconi 
75e40803f2SLorenzo Bianconi struct mt76x02_dfs_sequence {
76e40803f2SLorenzo Bianconi 	struct list_head head;
77e40803f2SLorenzo Bianconi 	u32 first_ts;
78e40803f2SLorenzo Bianconi 	u32 last_ts;
79e40803f2SLorenzo Bianconi 	u32 pri;
80e40803f2SLorenzo Bianconi 	u16 count;
81e40803f2SLorenzo Bianconi 	u8 engine;
82e40803f2SLorenzo Bianconi };
83e40803f2SLorenzo Bianconi 
84e40803f2SLorenzo Bianconi struct mt76x02_dfs_hw_pulse {
85e40803f2SLorenzo Bianconi 	u8 engine;
86e40803f2SLorenzo Bianconi 	u32 period;
87e40803f2SLorenzo Bianconi 	u32 w1;
88e40803f2SLorenzo Bianconi 	u32 w2;
89e40803f2SLorenzo Bianconi 	u32 burst;
90e40803f2SLorenzo Bianconi };
91e40803f2SLorenzo Bianconi 
92e40803f2SLorenzo Bianconi struct mt76x02_dfs_sw_detector_params {
93e40803f2SLorenzo Bianconi 	u32 min_pri;
94e40803f2SLorenzo Bianconi 	u32 max_pri;
95e40803f2SLorenzo Bianconi 	u32 pri_margin;
96e40803f2SLorenzo Bianconi };
97e40803f2SLorenzo Bianconi 
98e40803f2SLorenzo Bianconi struct mt76x02_dfs_engine_stats {
99e40803f2SLorenzo Bianconi 	u32 hw_pattern;
100e40803f2SLorenzo Bianconi 	u32 hw_pulse_discarded;
101e40803f2SLorenzo Bianconi 	u32 sw_pattern;
102e40803f2SLorenzo Bianconi };
103e40803f2SLorenzo Bianconi 
104e40803f2SLorenzo Bianconi struct mt76x02_dfs_seq_stats {
105e40803f2SLorenzo Bianconi 	u32 seq_pool_len;
106e40803f2SLorenzo Bianconi 	u32 seq_len;
107e40803f2SLorenzo Bianconi };
108e40803f2SLorenzo Bianconi 
109e40803f2SLorenzo Bianconi struct mt76x02_dfs_pattern_detector {
110e40803f2SLorenzo Bianconi 	u8 chirp_pulse_cnt;
111e40803f2SLorenzo Bianconi 	u32 chirp_pulse_ts;
112e40803f2SLorenzo Bianconi 
113e40803f2SLorenzo Bianconi 	struct mt76x02_dfs_sw_detector_params sw_dpd_params;
114e40803f2SLorenzo Bianconi 	struct mt76x02_dfs_event_rb event_rb[2];
115e40803f2SLorenzo Bianconi 
116e40803f2SLorenzo Bianconi 	struct list_head sequences;
117e40803f2SLorenzo Bianconi 	struct list_head seq_pool;
118e40803f2SLorenzo Bianconi 	struct mt76x02_dfs_seq_stats seq_stats;
119e40803f2SLorenzo Bianconi 
120e40803f2SLorenzo Bianconi 	unsigned long last_sw_check;
121e40803f2SLorenzo Bianconi 	u32 last_event_ts;
122e40803f2SLorenzo Bianconi 
123e40803f2SLorenzo Bianconi 	struct mt76x02_dfs_engine_stats stats[MT_DFS_NUM_ENGINES];
124e40803f2SLorenzo Bianconi 	struct tasklet_struct dfs_tasklet;
125e40803f2SLorenzo Bianconi };
126e40803f2SLorenzo Bianconi 
127e6cb3291SLorenzo Bianconi void mt76x02_dfs_init_params(struct mt76x02_dev *dev);
128e6cb3291SLorenzo Bianconi void mt76x02_dfs_init_detector(struct mt76x02_dev *dev);
129e6cb3291SLorenzo Bianconi void mt76x02_regd_notifier(struct wiphy *wiphy,
130e6cb3291SLorenzo Bianconi 			   struct regulatory_request *request);
131801ccc8aSLorenzo Bianconi void mt76x02_phy_dfs_adjust_agc(struct mt76x02_dev *dev);
132e40803f2SLorenzo Bianconi #endif /* __MT76x02_DFS_H */
133