summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mld/scan.h
blob: 69110f0cfc8e2ad17ea1ffc09f67a2dd14168de4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
 * Copyright (C) 2024-2025 Intel Corporation
 */
#ifndef __iwl_mld_scan_h__
#define __iwl_mld_scan_h__

int iwl_mld_alloc_scan_cmd(struct iwl_mld *mld);

int iwl_mld_regular_scan_start(struct iwl_mld *mld, struct ieee80211_vif *vif,
			       struct cfg80211_scan_request *req,
			       struct ieee80211_scan_ies *ies);

void iwl_mld_int_mlo_scan(struct iwl_mld *mld, struct ieee80211_vif *vif);

void iwl_mld_handle_scan_iter_complete_notif(struct iwl_mld *mld,
					     struct iwl_rx_packet *pkt);

int iwl_mld_scan_stop(struct iwl_mld *mld, int type, bool notify);

int iwl_mld_sched_scan_start(struct iwl_mld *mld,
			     struct ieee80211_vif *vif,
			     struct cfg80211_sched_scan_request *req,
			     struct ieee80211_scan_ies *ies,
			     int type);

void iwl_mld_handle_match_found_notif(struct iwl_mld *mld,
				      struct iwl_rx_packet *pkt);

void iwl_mld_handle_scan_complete_notif(struct iwl_mld *mld,
					struct iwl_rx_packet *pkt);

int iwl_mld_mac80211_get_survey(struct ieee80211_hw *hw, int idx,
				struct survey_info *survey);

void iwl_mld_handle_channel_survey_notif(struct iwl_mld *mld,
					 struct iwl_rx_packet *pkt);

#define WFA_TPC_IE_LEN 9

static inline int iwl_mld_scan_max_template_size(void)
{
#define MAC_HDR_LEN 24
#define DS_IE_LEN 3
#define SSID_IE_LEN 2

/* driver create the 802.11 header, WFA TPC IE, DS parameter and SSID IE */
#define DRIVER_TOTAL_IES_LEN \
	(MAC_HDR_LEN + WFA_TPC_IE_LEN + DS_IE_LEN + SSID_IE_LEN)

	BUILD_BUG_ON(SCAN_OFFLOAD_PROBE_REQ_SIZE < DRIVER_TOTAL_IES_LEN);

	return SCAN_OFFLOAD_PROBE_REQ_SIZE - DRIVER_TOTAL_IES_LEN;
}

void iwl_mld_report_scan_aborted(struct iwl_mld *mld);

enum iwl_mld_scan_status {
	IWL_MLD_SCAN_NONE		= 0,
	IWL_MLD_SCAN_REGULAR		= BIT(0),
	IWL_MLD_SCAN_SCHED		= BIT(1),
	IWL_MLD_SCAN_NETDETECT		= BIT(2),
	IWL_MLD_SCAN_INT_MLO		= BIT(3),
};

/* enum iwl_mld_pass_all_sched_results_states - Defines the states for
 * handling/passing scheduled scan results to mac80211
 * @SCHED_SCAN_PASS_ALL_STATE_DISABLED: Don't pass all scan results, only when
 *	a match found.
 * @SCHED_SCAN_PASS_ALL_STATE_ENABLED: Pass all scan results is enabled
 *	(no filtering).
 * @SCHED_SCAN_PASS_ALL_STATE_FOUND: A scan result is found, pass it on the
 *	next scan iteration complete notification.
 */
enum iwl_mld_pass_all_sched_results_states {
	SCHED_SCAN_PASS_ALL_STATE_DISABLED,
	SCHED_SCAN_PASS_ALL_STATE_ENABLED,
	SCHED_SCAN_PASS_ALL_STATE_FOUND,
};

/**
 * enum iwl_mld_traffic_load - Levels of traffic load
 *
 * @IWL_MLD_TRAFFIC_LOW: low traffic load
 * @IWL_MLD_TRAFFIC_MEDIUM: medium traffic load
 * @IWL_MLD_TRAFFIC_HIGH: high traffic load
 */
enum iwl_mld_traffic_load {
	IWL_MLD_TRAFFIC_LOW,
	IWL_MLD_TRAFFIC_MEDIUM,
	IWL_MLD_TRAFFIC_HIGH,
};

/**
 * struct iwl_mld_scan - Scan data
 * @status: scan status, a combination of %enum iwl_mld_scan_status,
 *	reflects the %scan.uid_status array.
 * @uid_status: array to track the scan status per uid.
 * @start_tsf: start time of last scan in TSF of the link that requested
 *	the scan.
 * @last_ebs_failed: true if the last EBS (Energy Based Scan) failed.
 * @pass_all_sched_res: see %enum iwl_mld_pass_all_sched_results_states.
 * @fw_link_id: the current (regular) scan fw link id, used by scan
 *	complete notif.
 * @traffic_load: traffic load related data
 * @traffic_load.last_stats_ts_usec: The timestamp of the last statistics
 *	notification, used to calculate the elapsed time between two
 *	notifications and determine the traffic load
 * @traffic_load.status: The current traffic load status, see
 *	&enum iwl_mld_traffic_load
 * @cmd_size: size of %cmd.
 * @cmd: pointer to scan cmd buffer (allocated once in op mode start).
 * @last_6ghz_passive_jiffies: stores the last 6GHz passive scan time
 *	in jiffies.
 * @last_start_time_jiffies: stores the last start time in jiffies
 *	(interface up/reset/resume).
 * @last_mlo_scan_time: start time of the last MLO scan in nanoseconds since
 *	boot.
 */
struct iwl_mld_scan {
	/* Add here fields that need clean up on restart */
	struct_group(zeroed_on_hw_restart,
		unsigned int status;
		u32 uid_status[IWL_MAX_UMAC_SCANS];
		u64 start_tsf;
		bool last_ebs_failed;
		enum iwl_mld_pass_all_sched_results_states pass_all_sched_res;
		u8 fw_link_id;
		struct {
			u32 last_stats_ts_usec;
			enum iwl_mld_traffic_load status;
		} traffic_load;
	);
	/* And here fields that survive a fw restart */
	size_t cmd_size;
	void *cmd;
	unsigned long last_6ghz_passive_jiffies;
	unsigned long last_start_time_jiffies;
	u64 last_mlo_scan_time;
};

/**
 * struct iwl_mld_survey_channel - per-channel survey information
 *
 * Driver version of &struct survey_info with just the data we want to report.
 *
 * @time: time in ms the radio was on the channel
 * @time_busy: time in ms the channel was sensed busy
 * @noise: channel noise in dBm
 */
struct iwl_mld_survey_channel {
	u32 time;
	u32 time_busy;
	s8 noise;
};

/**
 * struct iwl_mld_survey - survey information
 *
 * Survey information for all available channels.
 *
 * @bands: per-band array for per-channel survey data, points into @channels
 * @n_channels: Number of @channels entries that are allocated
 * @channels: per-channel information
 */
struct iwl_mld_survey {
	struct iwl_mld_survey_channel *bands[NUM_NL80211_BANDS];

	int n_channels;
	struct iwl_mld_survey_channel channels[] __counted_by(n_channels);
};

#endif /* __iwl_mld_scan_h__ */