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