summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtw89/chan.h
blob: 5b22764d5329574bbe2eb0af676532d09c66044f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 * Copyright(c) 2020-2022  Realtek Corporation
 */

#ifndef __RTW89_CHAN_H__
#define __RTW89_CHAN_H__

#include "core.h"

/* The dwell time in TU before doing rtw89_chanctx_work(). */
#define RTW89_CHANCTX_TIME_MCC_PREPARE 100
#define RTW89_CHANCTX_TIME_MCC 100

/* various MCC setting time in TU */
#define RTW89_MCC_LONG_TRIGGER_TIME 300
#define RTW89_MCC_SHORT_TRIGGER_TIME 100
#define RTW89_MCC_EARLY_TX_BCN_TIME 10
#define RTW89_MCC_EARLY_RX_BCN_TIME 5
#define RTW89_MCC_MIN_RX_BCN_TIME 10
#define RTW89_MCC_DFLT_BCN_OFST_TIME 40
#define RTW89_MCC_SWITCH_CH_TIME 3

#define RTW89_MCC_PROBE_TIMEOUT 100
#define RTW89_MCC_PROBE_MAX_TRIES 3

#define RTW89_MCC_DETECT_BCN_MAX_TRIES 2

#define RTW89_MCC_MIN_GO_DURATION \
	(RTW89_MCC_EARLY_TX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME)

#define RTW89_MCC_MIN_STA_DURATION \
	(RTW89_MCC_EARLY_RX_BCN_TIME + RTW89_MCC_MIN_RX_BCN_TIME)

#define RTW89_MCC_MIN_RX_BCN_WITH_SWITCH_CH_TIME \
	(RTW89_MCC_MIN_RX_BCN_TIME + RTW89_MCC_SWITCH_CH_TIME)

#define RTW89_MCC_DFLT_GROUP 0
#define RTW89_MCC_NEXT_GROUP(cur) (((cur) + 1) % 4)

#define RTW89_MCC_DFLT_TX_NULL_EARLY 7
#define RTW89_MCC_DFLT_COURTESY_SLOT 3

#define RTW89_MCC_REQ_COURTESY_TIME 5
#define RTW89_MCC_REQ_COURTESY(pattern, role)			\
({								\
	const struct rtw89_mcc_pattern *p = pattern;		\
	p->tob_ ## role <= RTW89_MCC_REQ_COURTESY_TIME ||	\
	p->toa_ ## role <= RTW89_MCC_REQ_COURTESY_TIME;		\
})

#define NUM_OF_RTW89_MCC_ROLES 2

enum rtw89_mr_wtype {
	RTW89_MR_WTYPE_NONE,
	RTW89_MR_WTYPE_NONMLD,
	RTW89_MR_WTYPE_MLD1L1R,
	RTW89_MR_WTYPE_MLD2L1R,
	RTW89_MR_WTYPE_MLD2L2R,
	RTW89_MR_WTYPE_NONMLD_NONMLD,
	RTW89_MR_WTYPE_MLD1L1R_NONMLD,
	RTW89_MR_WTYPE_MLD2L1R_NONMLD,
	RTW89_MR_WTYPE_MLD2L2R_NONMLD,
	RTW89_MR_WTYPE_UNKNOWN,
};

enum rtw89_mr_wmode {
	RTW89_MR_WMODE_NONE,
	RTW89_MR_WMODE_1CLIENT,
	RTW89_MR_WMODE_1AP,
	RTW89_MR_WMODE_1AP_1CLIENT,
	RTW89_MR_WMODE_2CLIENTS,
	RTW89_MR_WMODE_2APS,
	RTW89_MR_WMODE_UNKNOWN,
};

enum rtw89_mr_ctxtype {
	RTW89_MR_CTX_NONE,
	RTW89_MR_CTX1_2GHZ,
	RTW89_MR_CTX1_5GHZ,
	RTW89_MR_CTX1_6GHZ,
	RTW89_MR_CTX2_2GHZ,
	RTW89_MR_CTX2_5GHZ,
	RTW89_MR_CTX2_6GHZ,
	RTW89_MR_CTX2_2GHZ_5GHZ,
	RTW89_MR_CTX2_2GHZ_6GHZ,
	RTW89_MR_CTX2_5GHZ_6GHZ,
	RTW89_MR_CTX_UNKNOWN,
};

struct rtw89_mr_chanctx_info {
	enum rtw89_mr_wtype wtype;
	enum rtw89_mr_wmode wmode;
	enum rtw89_mr_ctxtype ctxtype;
};

enum rtw89_chanctx_pause_reasons {
	RTW89_CHANCTX_PAUSE_REASON_HW_SCAN,
	RTW89_CHANCTX_PAUSE_REASON_ROC,
	RTW89_CHANCTX_PAUSE_REASON_GC_BCN_LOSS,
};

struct rtw89_chanctx_pause_parm {
	const struct rtw89_vif_link *trigger;
	enum rtw89_chanctx_pause_reasons rsn;
};

struct rtw89_chanctx_cb_parm {
	int (*cb)(struct rtw89_dev *rtwdev, void *data);
	void *data;
	const char *caller;
};

struct rtw89_entity_weight {
	unsigned int registered_chanctxs;
	unsigned int active_chanctxs;
	unsigned int active_roles;
};

static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev,
					  enum rtw89_phy_idx phy_idx)
{
	struct rtw89_hal *hal = &rtwdev->hal;

	return READ_ONCE(hal->entity_active[phy_idx]);
}

static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev,
					  enum rtw89_phy_idx phy_idx,
					  bool active)
{
	struct rtw89_hal *hal = &rtwdev->hal;

	WRITE_ONCE(hal->entity_active[phy_idx], active);
}

static inline
enum rtw89_entity_mode rtw89_get_entity_mode(struct rtw89_dev *rtwdev)
{
	struct rtw89_hal *hal = &rtwdev->hal;

	return READ_ONCE(hal->entity_mode);
}

static inline void rtw89_set_entity_mode(struct rtw89_dev *rtwdev,
					 enum rtw89_entity_mode mode)
{
	struct rtw89_hal *hal = &rtwdev->hal;

	WRITE_ONCE(hal->entity_mode, mode);
}

void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
		       enum rtw89_band band, enum rtw89_bandwidth bandwidth);
bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
			      enum rtw89_chanctx_idx idx,
			      const struct rtw89_chan *new);
int rtw89_iterate_entity_chan(struct rtw89_dev *rtwdev,
			      int (*iterator)(const struct rtw89_chan *chan,
					      void *data),
			      void *data);
void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
				 enum rtw89_chanctx_idx idx,
				 const struct cfg80211_chan_def *chandef);
void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
			      struct rtw89_vif_link *rtwvif_link,
			      const struct cfg80211_chan_def *chandef);
void rtw89_entity_init(struct rtw89_dev *rtwdev);
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev);
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
				enum rtw89_chanctx_changes change);
void rtw89_query_mr_chanctx_info(struct rtw89_dev *rtwdev, u8 inst_idx,
				 struct rtw89_mr_chanctx_info *info);
void rtw89_chanctx_track(struct rtw89_dev *rtwdev);
void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
			 const struct rtw89_chanctx_pause_parm *parm);
void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev,
			   const struct rtw89_chanctx_cb_parm *cb_parm);

const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
					       const char *caller_message,
					       u8 link_index, bool nullchk);

#define rtw89_mgnt_chan_get(rtwdev, link_index) \
	__rtw89_mgnt_chan_get(rtwdev, __func__, link_index, false)

static inline const struct rtw89_chan *
rtw89_mgnt_chan_get_or_null(struct rtw89_dev *rtwdev, u8 link_index)
{
	return __rtw89_mgnt_chan_get(rtwdev, NULL, link_index, true);
}

struct rtw89_mcc_links_info {
	struct rtw89_vif_link *links[NUM_OF_RTW89_MCC_ROLES];
};

void rtw89_mcc_get_links(struct rtw89_dev *rtwdev, struct rtw89_mcc_links_info *info);
void rtw89_mcc_prepare_done_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_mcc_gc_detect_beacon_work(struct wiphy *wiphy, struct wiphy_work *work);
bool rtw89_mcc_detect_go_bcn(struct rtw89_dev *rtwdev,
			     struct rtw89_vif_link *rtwvif_link);

int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
			  struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
			      struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
			      struct ieee80211_chanctx_conf *ctx,
			      u32 changed);
int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
				 struct rtw89_vif_link *rtwvif_link,
				 struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
				    struct rtw89_vif_link *rtwvif_link,
				    struct ieee80211_chanctx_conf *ctx);
int rtw89_chanctx_ops_reassign_vif(struct rtw89_dev *rtwdev,
				   struct rtw89_vif_link *rtwvif_link,
				   struct ieee80211_chanctx_conf *old_ctx,
				   struct ieee80211_chanctx_conf *new_ctx,
				   bool replace);

#endif