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