1d1e879ecSMiri Korenblit /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2d1e879ecSMiri Korenblit /*
3d1e879ecSMiri Korenblit * Copyright (C) 2024-2025 Intel Corporation
4d1e879ecSMiri Korenblit */
5d1e879ecSMiri Korenblit #ifndef __iwl_mld_scan_h__
6d1e879ecSMiri Korenblit #define __iwl_mld_scan_h__
7d1e879ecSMiri Korenblit
8d1e879ecSMiri Korenblit int iwl_mld_alloc_scan_cmd(struct iwl_mld *mld);
9d1e879ecSMiri Korenblit
10d1e879ecSMiri Korenblit int iwl_mld_regular_scan_start(struct iwl_mld *mld, struct ieee80211_vif *vif,
11d1e879ecSMiri Korenblit struct cfg80211_scan_request *req,
12d1e879ecSMiri Korenblit struct ieee80211_scan_ies *ies);
13d1e879ecSMiri Korenblit
14d1e879ecSMiri Korenblit void iwl_mld_int_mlo_scan(struct iwl_mld *mld, struct ieee80211_vif *vif);
15d1e879ecSMiri Korenblit
16d1e879ecSMiri Korenblit void iwl_mld_handle_scan_iter_complete_notif(struct iwl_mld *mld,
17d1e879ecSMiri Korenblit struct iwl_rx_packet *pkt);
18d1e879ecSMiri Korenblit
19d1e879ecSMiri Korenblit int iwl_mld_scan_stop(struct iwl_mld *mld, int type, bool notify);
20d1e879ecSMiri Korenblit
21d1e879ecSMiri Korenblit int iwl_mld_sched_scan_start(struct iwl_mld *mld,
22d1e879ecSMiri Korenblit struct ieee80211_vif *vif,
23d1e879ecSMiri Korenblit struct cfg80211_sched_scan_request *req,
24d1e879ecSMiri Korenblit struct ieee80211_scan_ies *ies,
25d1e879ecSMiri Korenblit int type);
26d1e879ecSMiri Korenblit
27d1e879ecSMiri Korenblit void iwl_mld_handle_match_found_notif(struct iwl_mld *mld,
28d1e879ecSMiri Korenblit struct iwl_rx_packet *pkt);
29d1e879ecSMiri Korenblit
30d1e879ecSMiri Korenblit void iwl_mld_handle_scan_complete_notif(struct iwl_mld *mld,
31d1e879ecSMiri Korenblit struct iwl_rx_packet *pkt);
32d1e879ecSMiri Korenblit
33d1e879ecSMiri Korenblit #define WFA_TPC_IE_LEN 9
34d1e879ecSMiri Korenblit
iwl_mld_scan_max_template_size(void)35d1e879ecSMiri Korenblit static inline int iwl_mld_scan_max_template_size(void)
36d1e879ecSMiri Korenblit {
37d1e879ecSMiri Korenblit #define MAC_HDR_LEN 24
38d1e879ecSMiri Korenblit #define DS_IE_LEN 3
39d1e879ecSMiri Korenblit #define SSID_IE_LEN 2
40d1e879ecSMiri Korenblit
41d1e879ecSMiri Korenblit /* driver create the 802.11 header, WFA TPC IE, DS parameter and SSID IE */
42d1e879ecSMiri Korenblit #define DRIVER_TOTAL_IES_LEN \
43d1e879ecSMiri Korenblit (MAC_HDR_LEN + WFA_TPC_IE_LEN + DS_IE_LEN + SSID_IE_LEN)
44d1e879ecSMiri Korenblit
45d1e879ecSMiri Korenblit BUILD_BUG_ON(SCAN_OFFLOAD_PROBE_REQ_SIZE < DRIVER_TOTAL_IES_LEN);
46d1e879ecSMiri Korenblit
47d1e879ecSMiri Korenblit return SCAN_OFFLOAD_PROBE_REQ_SIZE - DRIVER_TOTAL_IES_LEN;
48d1e879ecSMiri Korenblit }
49d1e879ecSMiri Korenblit
50d1e879ecSMiri Korenblit void iwl_mld_report_scan_aborted(struct iwl_mld *mld);
51d1e879ecSMiri Korenblit
52d1e879ecSMiri Korenblit enum iwl_mld_scan_status {
53d1e879ecSMiri Korenblit IWL_MLD_SCAN_NONE = 0,
54d1e879ecSMiri Korenblit IWL_MLD_SCAN_REGULAR = BIT(0),
55d1e879ecSMiri Korenblit IWL_MLD_SCAN_SCHED = BIT(1),
56d1e879ecSMiri Korenblit IWL_MLD_SCAN_NETDETECT = BIT(2),
57d1e879ecSMiri Korenblit IWL_MLD_SCAN_INT_MLO = BIT(3),
58d1e879ecSMiri Korenblit };
59d1e879ecSMiri Korenblit
60d1e879ecSMiri Korenblit /* enum iwl_mld_pass_all_sched_results_states - Defines the states for
61d1e879ecSMiri Korenblit * handling/passing scheduled scan results to mac80211
62d1e879ecSMiri Korenblit * @SCHED_SCAN_PASS_ALL_STATE_DISABLED: Don't pass all scan results, only when
63d1e879ecSMiri Korenblit * a match found.
64d1e879ecSMiri Korenblit * @SCHED_SCAN_PASS_ALL_STATE_ENABLED: Pass all scan results is enabled
65d1e879ecSMiri Korenblit * (no filtering).
66d1e879ecSMiri Korenblit * @SCHED_SCAN_PASS_ALL_STATE_FOUND: A scan result is found, pass it on the
67d1e879ecSMiri Korenblit * next scan iteration complete notification.
68d1e879ecSMiri Korenblit */
69d1e879ecSMiri Korenblit enum iwl_mld_pass_all_sched_results_states {
70d1e879ecSMiri Korenblit SCHED_SCAN_PASS_ALL_STATE_DISABLED,
71d1e879ecSMiri Korenblit SCHED_SCAN_PASS_ALL_STATE_ENABLED,
72d1e879ecSMiri Korenblit SCHED_SCAN_PASS_ALL_STATE_FOUND,
73d1e879ecSMiri Korenblit };
74d1e879ecSMiri Korenblit
75d1e879ecSMiri Korenblit /**
76d1e879ecSMiri Korenblit * enum iwl_mld_traffic_load - Levels of traffic load
77d1e879ecSMiri Korenblit *
78d1e879ecSMiri Korenblit * @IWL_MLD_TRAFFIC_LOW: low traffic load
79d1e879ecSMiri Korenblit * @IWL_MLD_TRAFFIC_MEDIUM: medium traffic load
80d1e879ecSMiri Korenblit * @IWL_MLD_TRAFFIC_HIGH: high traffic load
81d1e879ecSMiri Korenblit */
82d1e879ecSMiri Korenblit enum iwl_mld_traffic_load {
83d1e879ecSMiri Korenblit IWL_MLD_TRAFFIC_LOW,
84d1e879ecSMiri Korenblit IWL_MLD_TRAFFIC_MEDIUM,
85d1e879ecSMiri Korenblit IWL_MLD_TRAFFIC_HIGH,
86d1e879ecSMiri Korenblit };
87d1e879ecSMiri Korenblit
88d1e879ecSMiri Korenblit /**
89d1e879ecSMiri Korenblit * struct iwl_mld_scan - Scan data
90d1e879ecSMiri Korenblit * @status: scan status, a combination of %enum iwl_mld_scan_status,
91d1e879ecSMiri Korenblit * reflects the %scan.uid_status array.
92d1e879ecSMiri Korenblit * @uid_status: array to track the scan status per uid.
93d1e879ecSMiri Korenblit * @start_tsf: start time of last scan in TSF of the link that requested
94d1e879ecSMiri Korenblit * the scan.
95d1e879ecSMiri Korenblit * @last_ebs_failed: true if the last EBS (Energy Based Scan) failed.
96d1e879ecSMiri Korenblit * @pass_all_sched_res: see %enum iwl_mld_pass_all_sched_results_states.
97d1e879ecSMiri Korenblit * @fw_link_id: the current (regular) scan fw link id, used by scan
98d1e879ecSMiri Korenblit * complete notif.
99d1e879ecSMiri Korenblit * @traffic_load: traffic load related data
100d1e879ecSMiri Korenblit * @traffic_load.last_stats_ts_usec: The timestamp of the last statistics
101d1e879ecSMiri Korenblit * notification, used to calculate the elapsed time between two
102d1e879ecSMiri Korenblit * notifications and determine the traffic load
103d1e879ecSMiri Korenblit * @traffic_load.status: The current traffic load status, see
104d1e879ecSMiri Korenblit * &enum iwl_mld_traffic_load
105d1e879ecSMiri Korenblit * @cmd_size: size of %cmd.
106d1e879ecSMiri Korenblit * @cmd: pointer to scan cmd buffer (allocated once in op mode start).
107d1e879ecSMiri Korenblit * @last_6ghz_passive_jiffies: stores the last 6GHz passive scan time
108d1e879ecSMiri Korenblit * in jiffies.
109d1e879ecSMiri Korenblit * @last_start_time_jiffies: stores the last start time in jiffies
110d1e879ecSMiri Korenblit * (interface up/reset/resume).
111*9324731bSMiri Korenblit * @last_mlo_scan_time: start time of the last MLO scan in nanoseconds since
112*9324731bSMiri Korenblit * boot.
113d1e879ecSMiri Korenblit */
114d1e879ecSMiri Korenblit struct iwl_mld_scan {
115d1e879ecSMiri Korenblit /* Add here fields that need clean up on restart */
116d1e879ecSMiri Korenblit struct_group(zeroed_on_hw_restart,
117d1e879ecSMiri Korenblit unsigned int status;
118d1e879ecSMiri Korenblit u32 uid_status[IWL_MAX_UMAC_SCANS];
119d1e879ecSMiri Korenblit u64 start_tsf;
120d1e879ecSMiri Korenblit bool last_ebs_failed;
121d1e879ecSMiri Korenblit enum iwl_mld_pass_all_sched_results_states pass_all_sched_res;
122d1e879ecSMiri Korenblit u8 fw_link_id;
123d1e879ecSMiri Korenblit struct {
124d1e879ecSMiri Korenblit u32 last_stats_ts_usec;
125d1e879ecSMiri Korenblit enum iwl_mld_traffic_load status;
126d1e879ecSMiri Korenblit } traffic_load;
127d1e879ecSMiri Korenblit );
128d1e879ecSMiri Korenblit /* And here fields that survive a fw restart */
129d1e879ecSMiri Korenblit size_t cmd_size;
130d1e879ecSMiri Korenblit void *cmd;
131d1e879ecSMiri Korenblit unsigned long last_6ghz_passive_jiffies;
132d1e879ecSMiri Korenblit unsigned long last_start_time_jiffies;
133*9324731bSMiri Korenblit unsigned long last_mlo_scan_time;
134d1e879ecSMiri Korenblit };
135d1e879ecSMiri Korenblit
136d1e879ecSMiri Korenblit #endif /* __iwl_mld_scan_h__ */
137