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