1 /*
2  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: wlan_hdd_mlo.h
20  *
21  * WLAN Host Device Driver file for 802.11be (Extremely High Throughput)
22  * support.
23  *
24  */
25 #if !defined(WLAN_HDD_MLO_H)
26 #define WLAN_HDD_MLO_H
27 #include <wlan_hdd_main.h>
28 #include "wlan_osif_features.h"
29 
30 /**
31  * struct hdd_adapter_create_param - adapter create parameters
32  * @only_wdev_register:  Register only the wdev not the netdev
33  * @associate_with_ml_adapter: Vdev points to the same netdev adapter
34  * @is_ml_adapter: is a ml adapter with associated netdev
35  * @is_add_virtual_iface: is netdev create request from add virtual interface
36  * @is_single_link: Is the adapter single link ML
37  * @num_sessions: No of session to create on start adapter
38  * @is_pre_cac_adapter: is a pre cac adapter with associated netdev
39  * @unused: Reserved spare bits
40  */
41 struct hdd_adapter_create_param {
42 	uint32_t only_wdev_register:1,
43 		 associate_with_ml_adapter:1,
44 		 is_ml_adapter:1,
45 		 is_add_virtual_iface:1,
46 		 is_single_link:1,
47 		 num_sessions:4,
48 		 is_pre_cac_adapter:1,
49 		 unused:22;
50 };
51 
52 #ifdef WLAN_FEATURE_11BE_MLO
53 #define MAX_SIMULTANEOUS_STA_ML_LINKS 1
54 #define MAX_NUM_STA_ML_LINKS 3
55 #endif
56 
57 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
58 #define hdd_adapter_is_ml_adapter(x)   ((x)->mlo_adapter_info.is_ml_adapter)
59 
60 /* MLO_STATE_COMMANDS */
61 #define FEATURE_ML_LINK_STATE_COMMANDS					\
62 	{								\
63 		.info.vendor_id = QCA_NL80211_VENDOR_ID,		\
64 		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MLO_LINK_STATE,\
65 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |			\
66 			 WIPHY_VENDOR_CMD_NEED_NETDEV |			\
67 			 WIPHY_VENDOR_CMD_NEED_RUNNING,			\
68 		.doit = wlan_hdd_cfg80211_process_ml_link_state,	\
69 		vendor_command_policy(ml_link_state_request_policy,	\
70 				QCA_WLAN_VENDOR_ATTR_LINK_STATE_MAX)	\
71 	},
72 
73 #ifndef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
74 #define hdd_adapter_is_link_adapter(x) ((x)->mlo_adapter_info.is_link_adapter)
75 #define hdd_adapter_is_sl_ml_adapter(x) \
76 			   ((x)->mlo_adapter_info.is_single_link_ml)
77 #define hdd_adapter_is_associated_with_ml_adapter(x) \
78 			   ((x)->mlo_adapter_info.associate_with_ml_adapter)
79 #define hdd_adapter_get_mlo_adapter_from_link(x) \
80 			   ((x)->mlo_adapter_info.ml_adapter)
81 
82 #else
83 #define hdd_adapter_is_link_adapter(x) (0)
84 #define hdd_adapter_is_sl_ml_adapter(x) (0)
85 #define hdd_adapter_is_associated_with_ml_adapter(x) (0)
86 #define hdd_adapter_get_mlo_adapter_from_link(x) (NULL)
87 #endif /* WLAN_HDD_MULTI_VDEV_SINGLE_NDEV */
88 #else
89 #define hdd_adapter_is_link_adapter(x) (0)
90 #define hdd_adapter_is_ml_adapter(x)   (0)
91 #define hdd_adapter_is_sl_ml_adapter(x) (0)
92 #define hdd_adapter_is_associated_with_ml_adapter(x) (0)
93 #define hdd_adapter_get_mlo_adapter_from_link(x) (NULL)
94 #endif /* WLAN_FEATURE_11BE_MLO && CFG80211_11BE_BASIC */
95 
96 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
97 #ifndef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
98 /**
99  * struct hdd_mlo_adapter_info - Mlo specific adapter information
100  * @is_ml_adapter: Whether this is the main ml adaper attached to netdev
101  * @is_link_adapter: Whether this a link adapter without netdev
102  * @associate_with_ml_adapter: adapter which shares the vdev object with the ml
103  * adapter
104  * @num_of_vdev_links: Num of vdevs/links part of the association
105  * @is_single_link_ml: Is the adapter a single link ML adapter
106  * @unused: Reserved spare bits
107  * @ml_adapter: ML adapter backpointer
108  * @link_adapter: backpointers to link adapters part of association
109  */
110 struct hdd_mlo_adapter_info {
111 	uint32_t is_ml_adapter:1,
112 		 is_link_adapter:1,
113 		 associate_with_ml_adapter:1,
114 		 num_of_vdev_links:2,
115 		 is_single_link_ml:1,
116 		 unused:26;
117 	struct hdd_adapter *ml_adapter;
118 	struct hdd_adapter *link_adapter[WLAN_MAX_MLD];
119 };
120 #else
121 struct hdd_mlo_adapter_info {
122 	uint32_t is_ml_adapter:1,
123 		 unused:31;
124 };
125 #endif
126 #endif
127 
128 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC) && \
129 	!defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
130 /**
131  * hdd_register_wdev() - Function to register only wdev
132  * @sta_adapter : Station adapter linked with netdevice
133  * @link_adapter: Link adapter
134  * @adapter_params: Adapter params
135  *
136  * Function to register only the wdev not the netdev
137  * Return: none
138  */
139 void hdd_register_wdev(struct hdd_adapter *sta_adapter,
140 		       struct hdd_adapter *link_adapter,
141 		       struct hdd_adapter_create_param *adapter_params);
142 /**
143  * hdd_wlan_unregister_mlo_interfaces() - Function to unregister mlo
144  * interfaces
145  * @adapter: Link adapter
146  * @rtnl_held: RTNL held or not
147  *
148  * Function to unregister only the link adapter/wdev.
149  * Return: none
150  */
151 QDF_STATUS hdd_wlan_unregister_mlo_interfaces(struct hdd_adapter *adapter,
152 					      bool rtnl_held);
153 /**
154  * hdd_wlan_register_mlo_interfaces() - Function to register mlo wdev interfaces
155  * @hdd_ctx: hdd context
156  *
157  * Function to register mlo wdev interfaces.
158  * Return: none
159  */
160 void hdd_wlan_register_mlo_interfaces(struct hdd_context *hdd_ctx);
161 
162 /**
163  * hdd_get_assoc_link_adapter() - get assoc link adapter
164  * @ml_adapter: ML adapter
165  *
166  * This function returns assoc link adapter.
167  * For single link ML adapter, function returns
168  * same adapter pointer.
169  *
170  * Return: adapter or NULL
171  */
172 struct hdd_adapter *hdd_get_assoc_link_adapter(struct hdd_adapter *ml_adapter);
173 
174 /**
175  * hdd_adapter_set_sl_ml_adapter() - Set adapter as sl ml adapter
176  * @adapter: HDD adapter
177  *
178  * This function sets adapter as single link ML adapter
179  * Return: None
180  */
181 void hdd_adapter_set_sl_ml_adapter(struct hdd_adapter *adapter);
182 
183 /**
184  * hdd_adapter_clear_sl_ml_adapter() - Set adapter as sl ml adapter
185  * @adapter: HDD adapter
186  *
187  * This function clears adapter single link ML adapter flag
188  * Return: None
189  */
190 void hdd_adapter_clear_sl_ml_adapter(struct hdd_adapter *adapter);
191 
192 /**
193  * hdd_get_ml_adapter() - get an ml adapter
194  * @hdd_ctx: HDD context
195  *
196  * This function returns ml adapter from adapter list
197  * Return: adapter or NULL
198  */
199 struct hdd_adapter *hdd_get_ml_adapter(struct hdd_context *hdd_ctx);
200 
201 #else
202 static inline
hdd_wlan_unregister_mlo_interfaces(struct hdd_adapter * adapter,bool rtnl_held)203 QDF_STATUS hdd_wlan_unregister_mlo_interfaces(struct hdd_adapter *adapter,
204 					      bool rtnl_held)
205 {
206 	return QDF_STATUS_SUCCESS;
207 }
208 
209 static inline
hdd_wlan_register_mlo_interfaces(struct hdd_context * hdd_ctx)210 void hdd_wlan_register_mlo_interfaces(struct hdd_context *hdd_ctx)
211 {
212 }
213 
214 static inline
hdd_register_wdev(struct hdd_adapter * sta_adapter,struct hdd_adapter * link_adapter,struct hdd_adapter_create_param * adapter_params)215 void hdd_register_wdev(struct hdd_adapter *sta_adapter,
216 		       struct hdd_adapter *link_adapter,
217 		       struct hdd_adapter_create_param *adapter_params)
218 {
219 }
220 
221 static inline
hdd_get_assoc_link_adapter(struct hdd_adapter * ml_adapter)222 struct hdd_adapter *hdd_get_assoc_link_adapter(struct hdd_adapter *ml_adapter)
223 {
224 	return NULL;
225 }
226 
227 static inline void
hdd_adapter_set_sl_ml_adapter(struct hdd_adapter * adapter)228 hdd_adapter_set_sl_ml_adapter(struct hdd_adapter *adapter)
229 {
230 }
231 
232 static inline void
hdd_adapter_clear_sl_ml_adapter(struct hdd_adapter * adapter)233 hdd_adapter_clear_sl_ml_adapter(struct hdd_adapter *adapter)
234 {
235 }
236 
237 static inline
hdd_get_ml_adapter(struct hdd_context * hdd_ctx)238 struct hdd_adapter *hdd_get_ml_adapter(struct hdd_context *hdd_ctx)
239 {
240 	return NULL;
241 }
242 #endif
243 
244 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
245 /**
246  * hdd_adapter_set_ml_adapter() - set adapter as ml adapter
247  * @adapter: HDD adapter
248  *
249  * This function sets adapter as ml adapter
250  * Return: None
251  */
252 void hdd_adapter_set_ml_adapter(struct hdd_adapter *adapter);
253 
254 /**
255  * hdd_adapter_link_switch_notification() - Get HDD notification on link switch
256  * start.
257  * @vdev: VDEV on which link switch will happen
258  * @non_trans_vdev_id: VDEV not part of link switch.
259  *
260  * Return: QDF_STATUS.
261  */
262 QDF_STATUS hdd_adapter_link_switch_notification(struct wlan_objmgr_vdev *vdev,
263 						uint8_t non_trans_vdev_id);
264 
265 /**
266  * hdd_mlo_t2lm_register_callback() - Register T2LM callback
267  * @vdev: Pointer to vdev
268  *
269  * Return: None
270  */
271 void hdd_mlo_t2lm_register_callback(struct wlan_objmgr_vdev *vdev);
272 
273 /**
274  * hdd_mlo_t2lm_unregister_callback() - Unregister T2LM callback
275  * @vdev: Pointer to vdev
276  *
277  * Return: None
278  */
279 void hdd_mlo_t2lm_unregister_callback(struct wlan_objmgr_vdev *vdev);
280 
281 /**
282  * wlan_handle_mlo_link_state_operation() - mlo link state operation
283  * @adapter: HDD adapter
284  * @wiphy: wiphy pointer
285  * @vdev: vdev handler
286  * @hdd_ctx: hdd context
287  * @data: pointer to incoming NL vendor data
288  * @data_len: length of @data
289  *
290  * Based on the data get or set the mlo link state
291  *
292  * Return: 0 on success and error number otherwise.
293  */
294 int wlan_handle_mlo_link_state_operation(struct hdd_adapter *adapter,
295 					 struct wiphy *wiphy,
296 					 struct wlan_objmgr_vdev *vdev,
297 					 struct hdd_context *hdd_ctx,
298 					 const void *data, int data_len);
299 
300 extern const struct nla_policy
301 ml_link_state_request_policy[QCA_WLAN_VENDOR_ATTR_LINK_STATE_MAX + 1];
302 
303 /**
304  * wlan_hdd_send_t2lm_event() - Send t2lm info to userspace
305  * @vdev: vdev handler
306  * @t2lm: tid to link mapping info
307  *
308  * This function is called when driver needs to send vendor specific
309  * t2lm info to userspace
310  */
311 QDF_STATUS wlan_hdd_send_t2lm_event(struct wlan_objmgr_vdev *vdev,
312 				    struct wlan_t2lm_info *t2lm);
313 
314 /**
315  * wlan_hdd_cfg80211_process_ml_link_state() - process ml link state
316  * @wiphy: wiphy pointer
317  * @wdev: pointer to struct wireless_dev
318  * @data: pointer to incoming NL vendor data
319  * @data_len: length of @data
320  *
321  * Set (or) get the ml link state.
322  *
323  * Return:  0 on success; error number otherwise.
324  */
325 int wlan_hdd_cfg80211_process_ml_link_state(struct wiphy *wiphy,
326 					    struct wireless_dev *wdev,
327 					    const void *data, int data_len);
328 /**
329  * hdd_update_link_state_cached_timestamp() - update link state cached timestamp
330  * @adapter: HDD adapter
331  *
332  * Return: none
333  */
334 void hdd_update_link_state_cached_timestamp(struct hdd_adapter *adapter);
335 
336 /**
337  * hdd_derive_link_address_from_mld() - Function to derive link address from
338  * MLD address which is passed as input argument.
339  * @psoc: PSOC object manager
340  * @mld_addr: Input MLD address
341  * @link_addr_list: Start index of array to hold derived MAC addresses
342  * @max_idx: Number of addresses to derive
343  *
344  * The API will generate link addresses from the input MLD address and saves
345  * each link address as an array in @link_addr_list.
346  *
347  * If CFG_MLO_SAME_LINK_MLD_ADDR is enabled, then API will not derive first
348  * link address and will use MLD address in that place.
349  *
350  * Return: QDF_STATUS
351  */
352 QDF_STATUS hdd_derive_link_address_from_mld(struct wlan_objmgr_psoc *psoc,
353 					    struct qdf_mac_addr *mld_addr,
354 					    struct qdf_mac_addr *link_addr_list,
355 					    uint8_t max_idx);
356 
357 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
358 /**
359  * hdd_adapter_restore_link_vdev_map() - Change the VDEV to link info mapping
360  * in adapter.
361  * @adapter: HDD adapter pointer
362  * @same_vdev_mac_map: Maintain VDEV to MAC address mapping during the restore.
363  *
364  * This API restores the VDEV to HDD link info mapping to its initial order
365  * which could have got remapped in the process of link switch. If
366  * @same_vdev_mac_map is set to %true then the MAC address to VDEV mapping is
367  * preserved.
368  *
369  * Returns: %true if any mapping changes or %false otherwise.
370  */
371 bool hdd_adapter_restore_link_vdev_map(struct hdd_adapter *adapter,
372 				       bool same_vdev_mac_map);
373 
374 /**
375  * hdd_mlo_mgr_register_osif_ops() - Register OSIF ops with global MLO manager
376  * for callback to notify.
377  *
378  * The @ops contain callback functions which are triggered to update OSIF about
379  * necessary events from MLO manager.
380  *
381  * Return: QDF_STATUS
382  */
383 QDF_STATUS hdd_mlo_mgr_register_osif_ops(void);
384 
385 /**
386  * hdd_mlo_mgr_unregister_osif_ops() - Deregister OSIF ops with
387  * global MLO manager
388  *
389  * Deregister the calbacks registered with global MLO manager for OSIF
390  *
391  * Return: QDF_STATUS
392  */
393 QDF_STATUS hdd_mlo_mgr_unregister_osif_ops(void);
394 #else
395 static inline bool
hdd_adapter_restore_link_vdev_map(struct hdd_adapter * adapter,bool same_vdev_mac_map)396 hdd_adapter_restore_link_vdev_map(struct hdd_adapter *adapter,
397 				  bool same_vdev_mac_map)
398 {
399 	return false;
400 }
401 
hdd_mlo_mgr_register_osif_ops(void)402 static inline QDF_STATUS hdd_mlo_mgr_register_osif_ops(void)
403 {
404 	return QDF_STATUS_SUCCESS;
405 }
406 
hdd_mlo_mgr_unregister_osif_ops(void)407 static inline QDF_STATUS hdd_mlo_mgr_unregister_osif_ops(void)
408 {
409 	return QDF_STATUS_SUCCESS;
410 }
411 #endif
412 #else
413 static inline void
hdd_adapter_set_ml_adapter(struct hdd_adapter * adapter)414 hdd_adapter_set_ml_adapter(struct hdd_adapter *adapter)
415 {
416 }
417 
hdd_mlo_mgr_register_osif_ops(void)418 static inline QDF_STATUS hdd_mlo_mgr_register_osif_ops(void)
419 {
420 	return QDF_STATUS_SUCCESS;
421 }
422 
hdd_mlo_mgr_unregister_osif_ops(void)423 static inline QDF_STATUS hdd_mlo_mgr_unregister_osif_ops(void)
424 {
425 	return QDF_STATUS_SUCCESS;
426 }
427 
428 static inline
hdd_mlo_t2lm_register_callback(struct wlan_objmgr_vdev * vdev)429 void hdd_mlo_t2lm_register_callback(struct wlan_objmgr_vdev *vdev)
430 {
431 }
432 
433 static inline
hdd_mlo_t2lm_unregister_callback(struct wlan_objmgr_vdev * vdev)434 void hdd_mlo_t2lm_unregister_callback(struct wlan_objmgr_vdev *vdev)
435 {
436 }
437 
438 static inline int
wlan_handle_mlo_link_state_operation(struct hdd_adapter * adapter,struct wiphy * wiphy,struct wlan_objmgr_vdev * vdev,struct hdd_context * hdd_ctx,const void * data,int data_len)439 wlan_handle_mlo_link_state_operation(struct hdd_adapter *adapter,
440 				     struct wiphy *wiphy,
441 				     struct wlan_objmgr_vdev *vdev,
442 				     struct hdd_context *hdd_ctx,
443 				     const void *data, int data_len)
444 {
445 	return 0;
446 }
447 
448 static inline
wlan_hdd_cfg80211_process_ml_link_state(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)449 int wlan_hdd_cfg80211_process_ml_link_state(struct wiphy *wiphy,
450 					    struct wireless_dev *wdev,
451 					    const void *data, int data_len)
452 {
453 	return -ENOTSUPP;
454 }
455 
456 static inline
hdd_derive_link_address_from_mld(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * mld_addr,struct qdf_mac_addr * link_addr_list,uint8_t max_idx)457 QDF_STATUS hdd_derive_link_address_from_mld(struct wlan_objmgr_psoc *psoc,
458 					    struct qdf_mac_addr *mld_addr,
459 					    struct qdf_mac_addr *link_addr_list,
460 					    uint8_t max_idx)
461 {
462 	return QDF_STATUS_E_NOSUPPORT;
463 }
464 
465 static inline
wlan_hdd_send_t2lm_event(struct wlan_objmgr_vdev * vdev,struct wlan_t2lm_info * t2lm)466 QDF_STATUS wlan_hdd_send_t2lm_event(struct wlan_objmgr_vdev *vdev,
467 				    struct wlan_t2lm_info *t2lm)
468 {
469 	return QDF_STATUS_E_NOSUPPORT;
470 }
471 
472 static inline
hdd_update_link_state_cached_timestamp(struct hdd_adapter * adapter)473 void hdd_update_link_state_cached_timestamp(struct hdd_adapter *adapter)
474 {
475 }
476 
477 #define FEATURE_ML_LINK_STATE_COMMANDS
478 #endif
479 #endif
480