1 /*
2  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /**
18  * DOC: contains EPCS APIs
19  */
20 
21 #ifndef _WLAN_MLO_EPCS_H_
22 #define _WLAN_MLO_EPCS_H_
23 
24 #include <wlan_cmn_ieee80211.h>
25 #include <wlan_mlo_mgr_public_structs.h>
26 #ifdef WMI_AP_SUPPORT
27 #include <wlan_cmn.h>
28 #endif
29 
30 struct wlan_mlo_peer_context;
31 
32 /**
33  * enum wlan_epcs_category - epcs category
34  *
35  * @WLAN_EPCS_CATEGORY_NONE: none
36  * @WLAN_EPCS_CATEGORY_REQUEST: EPCS request
37  * @WLAN_EPCS_CATEGORY_RESPONSE: EPCS response
38  * @WLAN_EPCS_CATEGORY_TEARDOWN: EPCS teardown
39  * @WLAN_EPCS_CATEGORY_INVALID: Invalid
40  */
41 enum wlan_epcs_category {
42 	WLAN_EPCS_CATEGORY_NONE = 0,
43 	WLAN_EPCS_CATEGORY_REQUEST = 3,
44 	WLAN_EPCS_CATEGORY_RESPONSE = 4,
45 	WLAN_EPCS_CATEGORY_TEARDOWN = 5,
46 	WLAN_EPCS_CATEGORY_INVALID,
47 };
48 
49 /**
50  * struct ml_pa_partner_link_info - Priority Access ML partner information
51  * @link_id: Link ID
52  * @edca_ie_present: EDCA IE present
53  * @muedca_ie_present: MU EDCA IE present
54  * @ven_wme_ie_present: WME IE present
55  * @edca: EDCA IE
56  * @muedca: MU EDCA IE
57  * @ven_wme_ie_bytes: WME IE
58  */
59 struct ml_pa_partner_link_info {
60 	uint8_t link_id;
61 	uint8_t edca_ie_present:1,
62 		muedca_ie_present:1,
63 		ven_wme_ie_present:1;
64 	union {
65 		struct edca_ie edca;
66 		uint8_t ven_wme_ie_bytes[WLAN_VENDOR_WME_IE_LEN + 2];
67 	};
68 	struct muedca_ie muedca;
69 };
70 
71 /**
72  * struct ml_pa_info - priority access ML info
73  * @mld_mac_addr: MLD mac address
74  * @num_links: Number of Links
75  * @link_info: Partner link information
76  */
77 struct ml_pa_info {
78 	struct qdf_mac_addr mld_mac_addr;
79 	uint8_t num_links;
80 	struct ml_pa_partner_link_info link_info[WLAN_UMAC_MLO_MAX_VDEVS];
81 };
82 
83 /**
84  * struct wlan_epcs_info - EPCS information of frame
85  * @cat: frame category
86  * @dialog_token: dialog token
87  * @status: status
88  * @pa_info: Priority access ML info
89  */
90 struct wlan_epcs_info {
91 	enum wlan_epcs_category cat;
92 	uint8_t dialog_token;
93 	uint16_t status;
94 	struct ml_pa_info pa_info;
95 };
96 
97 /**
98  * enum peer_epcs_state - epcs stat of peer
99  * @EPCS_DOWN: EPCS state down
100  * @EPCS_ENABLE: EPCS state enabled
101  */
102 enum peer_epcs_state {
103 	EPCS_DOWN,
104 	EPCS_ENABLE
105 };
106 
107 /**
108  * struct wlan_mlo_peer_epcs_info - Peer EPCS information
109  * @epcs_dev_peer_lock: epcs dev peer lock
110  * @state: EPCS state of peer
111  * @self_gen_dialog_token: selfgenerated dialog token
112  */
113 struct wlan_mlo_peer_epcs_info {
114 #ifdef WLAN_MLO_USE_SPINLOCK
115 	qdf_spinlock_t epcs_dev_peer_lock;
116 #else
117 	qdf_mutex_t epcs_dev_peer_lock;
118 #endif
119 	enum peer_epcs_state state;
120 	uint8_t self_gen_dialog_token;
121 };
122 
123 #define EPCS_MAX_AUTHORIZE_MAC_ADDR 32
124 /**
125  * struct epcs_peer_authorize_info - EPCS authorized mac addresses
126  * @valid: valid index if set t0 true
127  * @peer_mld_mac: mld mac address
128  */
129 struct epcs_peer_authorize_info {
130 	bool valid;
131 	uint8_t peer_mld_mac[QDF_MAC_ADDR_SIZE];
132 };
133 
134 /**
135  * struct wlan_epcs_context - EPCS context if MLD
136  * @epcs_dev_lock: epcs dev context lock
137  * @authorize_info: Array of Authorization info containing peer mac address
138  */
139 struct wlan_epcs_context {
140 #ifdef WLAN_MLO_USE_SPINLOCK
141 	qdf_spinlock_t epcs_dev_lock;
142 #else
143 	qdf_mutex_t epcs_dev_lock;
144 #endif
145 	struct epcs_peer_authorize_info
146 			authorize_info[EPCS_MAX_AUTHORIZE_MAC_ADDR];
147 };
148 
149 /**
150  * struct epcs_frm - EPCS action frame format
151  * @category: category
152  * @protected_eht_action: Protected EHT Action
153  * @dialog_token: Dialog Token
154  * @status_code: Status Code
155  * @req: Request frame
156  * @resp: Response frame
157  * @bytes: Priority Access Multi-Link element bytes
158  */
159 struct epcs_frm {
160 	uint8_t category;
161 	uint8_t protected_eht_action;
162 	uint8_t dialog_token;
163 	union {
164 		struct {
165 			uint8_t bytes[0];
166 		} req;
167 		struct {
168 			uint8_t status_code[2];
169 			uint8_t bytes[0];
170 		} resp;
171 	};
172 };
173 
174 /* MIN EPCS request frame length */
175 #define EPCS_REQ_MIN_LENGTH 3
176 
177 /* MIN EPCS response frame length */
178 #define EPCS_RESP_MIN_LENGTH 5
179 
180 #define epcs_alert(format, args...) \
181 		QDF_TRACE_FATAL(QDF_MODULE_ID_EPCS, format, ## args)
182 
183 #define epcs_err(format, args...) \
184 		QDF_TRACE_ERROR(QDF_MODULE_ID_EPCS, format, ## args)
185 
186 #define epcs_warn(format, args...) \
187 		QDF_TRACE_WARN(QDF_MODULE_ID_EPCS, format, ## args)
188 
189 #define epcs_info(format, args...) \
190 		QDF_TRACE_INFO(QDF_MODULE_ID_EPCS, format, ## args)
191 
192 #define epcs_debug(format, args...) \
193 		QDF_TRACE_DEBUG(QDF_MODULE_ID_EPCS, format, ## args)
194 
195 #define epcs_rl_debug(format, args...) \
196 		QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_EPCS, format, ## args)
197 
198 #ifdef WLAN_MLO_USE_SPINLOCK
199 /**
200  * epcs_dev_lock_create - Create EPCS device mutex/spinlock
201  * @epcs_ctx: EPCS context
202  *
203  * Creates mutex/spinlock
204  *
205  * Return: void
206  */
207 static inline void
epcs_dev_lock_create(struct wlan_epcs_context * epcs_ctx)208 epcs_dev_lock_create(struct wlan_epcs_context *epcs_ctx)
209 {
210 	qdf_spinlock_create(&epcs_ctx->epcs_dev_lock);
211 }
212 
213 /**
214  * epcs_dev_lock_destroy - Destroy EPCS mutex/spinlock
215  * @epcs_ctx: EPCS context
216  *
217  * Destroy mutex/spinlock
218  *
219  * Return: void
220  */
221 static inline void
epcs_dev_lock_destroy(struct wlan_epcs_context * epcs_ctx)222 epcs_dev_lock_destroy(struct wlan_epcs_context *epcs_ctx)
223 {
224 	qdf_spinlock_destroy(&epcs_ctx->epcs_dev_lock);
225 }
226 
227 /**
228  * epcs_dev_lock_acquire - acquire EPCS mutex/spinlock
229  * @epcs_ctx: EPCS context
230  *
231  * acquire mutex/spinlock
232  *
233  * return: void
234  */
235 static inline
epcs_dev_lock_acquire(struct wlan_epcs_context * epcs_ctx)236 void epcs_dev_lock_acquire(struct wlan_epcs_context *epcs_ctx)
237 {
238 	qdf_spin_lock_bh(&epcs_ctx->epcs_dev_lock);
239 }
240 
241 /**
242  * epcs_dev_lock_release - release EPCS dev mutex/spinlock
243  * @epcs_ctx: EPCS context
244  *
245  * release mutex/spinlock
246  *
247  * return: void
248  */
249 static inline
epcs_dev_lock_release(struct wlan_epcs_context * epcs_ctx)250 void epcs_dev_lock_release(struct wlan_epcs_context *epcs_ctx)
251 {
252 	qdf_spin_unlock_bh(&epcs_ctx->epcs_dev_lock);
253 }
254 #else /* WLAN_MLO_USE_SPINLOCK */
255 static inline
epcs_dev_lock_create(struct wlan_epcs_context * epcs_ctx)256 void epcs_dev_lock_create(struct wlan_epcs_context *epcs_ctx)
257 {
258 	qdf_mutex_create(&epcs_ctx->epcs_dev_lock);
259 }
260 
261 static inline
epcs_dev_lock_destroy(struct wlan_epcs_context * epcs_ctx)262 void epcs_dev_lock_destroy(struct wlan_epcs_context *epcs_ctx)
263 {
264 	qdf_mutex_destroy(&epcs_ctx->epcs_dev_lock);
265 }
266 
epcs_dev_lock_acquire(struct wlan_epcs_context * epcs_ctx)267 static inline void epcs_dev_lock_acquire(struct wlan_epcs_context *epcs_ctx)
268 {
269 	qdf_mutex_acquire(&epcs_ctx->epcs_dev_lock);
270 }
271 
epcs_dev_lock_release(struct wlan_epcs_context * epcs_ctx)272 static inline void epcs_dev_lock_release(struct wlan_epcs_context *epcs_ctx)
273 {
274 	qdf_mutex_release(&epcs_ctx->epcs_dev_lock);
275 }
276 #endif
277 
278 #ifdef WLAN_MLO_USE_SPINLOCK
279 /**
280  * epcs_dev_peer_lock_create - Create EPCS device mutex/spinlock
281  * @epcs_info: EPCS info
282  *
283  * Creates mutex/spinlock
284  *
285  * Return: void
286  */
287 static inline
epcs_dev_peer_lock_create(struct wlan_mlo_peer_epcs_info * epcs_info)288 void epcs_dev_peer_lock_create(struct wlan_mlo_peer_epcs_info *epcs_info)
289 {
290 	qdf_spinlock_create(&epcs_info->epcs_dev_peer_lock);
291 }
292 
293 /**
294  * epcs_dev_peer_lock_destroy - Destroy EPCS mutex/spinlock
295  * @epcs_info: EPCS info
296  *
297  * Destroy mutex/spinlock
298  *
299  * Return: void
300  */
301 static inline
epcs_dev_peer_lock_destroy(struct wlan_mlo_peer_epcs_info * epcs_info)302 void epcs_dev_peer_lock_destroy(struct wlan_mlo_peer_epcs_info *epcs_info)
303 {
304 	qdf_spinlock_destroy(&epcs_info->epcs_dev_peer_lock);
305 }
306 
307 /**
308  * epcs_dev_peer_lock_acquire - acquire EPCS mutex/spinlock
309  * @epcs_info: EPCS info
310  *
311  * acquire mutex/spinlock
312  *
313  * return: void
314  */
315 static inline
epcs_dev_peer_lock_acquire(struct wlan_mlo_peer_epcs_info * epcs_info)316 void epcs_dev_peer_lock_acquire(struct wlan_mlo_peer_epcs_info *epcs_info)
317 {
318 	qdf_spin_lock_bh(&epcs_info->epcs_dev_peer_lock);
319 }
320 
321 /**
322  * epcs_dev_peer_lock_release - release EPCS dev mutex/spinlock
323  * @epcs_info: EPCS info
324  *
325  * release mutex/spinlock
326  *
327  * return: void
328  */
329 static inline
epcs_dev_peer_lock_release(struct wlan_mlo_peer_epcs_info * epcs_info)330 void epcs_dev_peer_lock_release(struct wlan_mlo_peer_epcs_info *epcs_info)
331 {
332 	qdf_spin_unlock_bh(&epcs_info->epcs_dev_peer_lock);
333 }
334 #else /* WLAN_MLO_USE_SPINLOCK */
335 static inline
epcs_dev_peer_lock_create(struct wlan_mlo_peer_epcs_info * epcs_info)336 void epcs_dev_peer_lock_create(struct wlan_mlo_peer_epcs_info *epcs_info)
337 {
338 	qdf_mutex_create(&epcs_info->epcs_dev_peer_lock);
339 }
340 
341 static inline
epcs_dev_peer_lock_destroy(struct wlan_mlo_peer_epcs_info * epcs_info)342 void epcs_dev_peer_lock_destroy(struct wlan_mlo_peer_epcs_info *epcs_info)
343 {
344 	qdf_mutex_destroy(&epcs_info->epcs_dev_peer_lock);
345 }
346 
347 static inline
epcs_dev_peer_lock_acquire(struct wlan_mlo_peer_epcs_info * epcs_info)348 void epcs_dev_peer_lock_acquire(struct wlan_mlo_peer_epcs_info *epcs_info)
349 {
350 	qdf_mutex_acquire(&epcs_info->epcs_dev_peer_lock);
351 }
352 
353 static inline
epcs_dev_peer_lock_release(struct wlan_mlo_peer_epcs_info * epcs_info)354 void epcs_dev_peer_lock_release(struct wlan_mlo_peer_epcs_info *epcs_info)
355 {
356 	qdf_mutex_release(&epcs_info->epcs_dev_peer_lock);
357 }
358 #endif
359 
360 /**
361  * wlan_mlo_add_epcs_action_frame() - API to add EPCS action frame
362  * @frm: Pointer to a frame to add EPCS information
363  * @args: EPCS action frame related info
364  * @buf: Pointer to EPCS IE values
365  *
366  * Return: Pointer to the updated frame buffer
367  */
368 uint8_t *wlan_mlo_add_epcs_action_frame(uint8_t *frm,
369 					struct wlan_action_frame_args *args,
370 					uint8_t *buf);
371 
372 /**
373  * wlan_mlo_parse_epcs_action_frame() - API to parse EPCS action frame
374  * @epcs: Pointer to EPCS information
375  * @action_frm: EPCS action frame
376  * @frm_len: frame length
377  *
378  * Return: QDF_STATUS
379  */
380 QDF_STATUS
381 wlan_mlo_parse_epcs_action_frame(struct wlan_epcs_info *epcs,
382 				 struct wlan_action_frame *action_frm,
383 				 uint32_t frm_len);
384 
385 /**
386  * wlan_mlo_peer_rcv_cmd() - API to process EPCS command
387  * @ml_peer: Pointer to ML peer received
388  * @epcs: Pointer to EPCS information
389  * @updparam: pointer to fill update parameters
390  *
391  * Return: QDF_STATUS
392  */
393 QDF_STATUS
394 wlan_mlo_peer_rcv_cmd(struct wlan_mlo_peer_context *ml_peer,
395 		      struct wlan_epcs_info *epcs,
396 		      bool *updparam);
397 
398 /**
399  * wlan_mlo_peer_rcv_action_frame() - API to process EPCS frame receive event
400  * @ml_peer: Pointer to ML peer received
401  * @epcs: Pointer to EPCS information
402  * @respond: pointer to fill response required or not
403  * @updparam: pointer to fill update parameters
404  *
405  * Return: QDF_STATUS
406  */
407 QDF_STATUS
408 wlan_mlo_peer_rcv_action_frame(struct wlan_mlo_peer_context *ml_peer,
409 			       struct wlan_epcs_info *epcs,
410 			       bool *respond,
411 			       bool *updparam);
412 
413 /**
414  * wlan_mlo_update_authorize_epcs_mac_addr() - API to authorize mac addr
415  * @vdev: pointer to vdev
416  * @peer_mld_mac: mld mac address
417  *
418  * Return: QDF_STATUS
419  */
420 QDF_STATUS
421 wlan_mlo_update_authorize_epcs_mac_addr(struct wlan_objmgr_vdev *vdev,
422 					uint8_t *peer_mld_mac);
423 
424 /**
425  * wlan_mlo_update_deauthorize_epcs_mac_addr() - API to deauthorize mac addr
426  * @vdev: pointer to vdev
427  * @peer_mld_mac: mld mac address
428  *
429  * Return: QDF_STATUS
430  */
431 QDF_STATUS
432 wlan_mlo_update_deauthorize_epcs_mac_addr(struct wlan_objmgr_vdev *vdev,
433 					  uint8_t *peer_mld_mac);
434 #endif /* _WLAN_MLO_EPCS_H_ */
435