xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/intel/iwlwifi/mvm/time-event.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /******************************************************************************
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * This file is provided under a dual BSD/GPLv2 license.  When using or
4*4882a593Smuzhiyun  * redistributing this file, you may do so under either license.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * GPL LICENSE SUMMARY
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9*4882a593Smuzhiyun  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
10*4882a593Smuzhiyun  * Copyright (C) 2019 - 2020 Intel Corporation
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify
13*4882a593Smuzhiyun  * it under the terms of version 2 of the GNU General Public License as
14*4882a593Smuzhiyun  * published by the Free Software Foundation.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * This program is distributed in the hope that it will be useful, but
17*4882a593Smuzhiyun  * WITHOUT ANY WARRANTY; without even the implied warranty of
18*4882a593Smuzhiyun  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19*4882a593Smuzhiyun  * General Public License for more details.
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * The full GNU General Public License is included in this distribution
22*4882a593Smuzhiyun  * in the file called COPYING.
23*4882a593Smuzhiyun  *
24*4882a593Smuzhiyun  * Contact Information:
25*4882a593Smuzhiyun  *  Intel Linux Wireless <linuxwifi@intel.com>
26*4882a593Smuzhiyun  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * BSD LICENSE
29*4882a593Smuzhiyun  *
30*4882a593Smuzhiyun  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
31*4882a593Smuzhiyun  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
32*4882a593Smuzhiyun  * Copyright (C) 2019 - 2020 Intel Corporation
33*4882a593Smuzhiyun  * All rights reserved.
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * Redistribution and use in source and binary forms, with or without
36*4882a593Smuzhiyun  * modification, are permitted provided that the following conditions
37*4882a593Smuzhiyun  * are met:
38*4882a593Smuzhiyun  *
39*4882a593Smuzhiyun  *  * Redistributions of source code must retain the above copyright
40*4882a593Smuzhiyun  *    notice, this list of conditions and the following disclaimer.
41*4882a593Smuzhiyun  *  * Redistributions in binary form must reproduce the above copyright
42*4882a593Smuzhiyun  *    notice, this list of conditions and the following disclaimer in
43*4882a593Smuzhiyun  *    the documentation and/or other materials provided with the
44*4882a593Smuzhiyun  *    distribution.
45*4882a593Smuzhiyun  *  * Neither the name Intel Corporation nor the names of its
46*4882a593Smuzhiyun  *    contributors may be used to endorse or promote products derived
47*4882a593Smuzhiyun  *    from this software without specific prior written permission.
48*4882a593Smuzhiyun  *
49*4882a593Smuzhiyun  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50*4882a593Smuzhiyun  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51*4882a593Smuzhiyun  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
52*4882a593Smuzhiyun  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
53*4882a593Smuzhiyun  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
54*4882a593Smuzhiyun  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
55*4882a593Smuzhiyun  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56*4882a593Smuzhiyun  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57*4882a593Smuzhiyun  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58*4882a593Smuzhiyun  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
59*4882a593Smuzhiyun  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60*4882a593Smuzhiyun  *
61*4882a593Smuzhiyun  *****************************************************************************/
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun #ifndef __time_event_h__
64*4882a593Smuzhiyun #define __time_event_h__
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun #include "fw-api.h"
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun #include "mvm.h"
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /**
71*4882a593Smuzhiyun  * DOC: Time Events - what is it?
72*4882a593Smuzhiyun  *
73*4882a593Smuzhiyun  * Time Events are a fw feature that allows the driver to control the presence
74*4882a593Smuzhiyun  * of the device on the channel. Since the fw supports multiple channels
75*4882a593Smuzhiyun  * concurrently, the fw may choose to jump to another channel at any time.
76*4882a593Smuzhiyun  * In order to make sure that the fw is on a specific channel at a certain time
77*4882a593Smuzhiyun  * and for a certain duration, the driver needs to issue a time event.
78*4882a593Smuzhiyun  *
79*4882a593Smuzhiyun  * The simplest example is for BSS association. The driver issues a time event,
80*4882a593Smuzhiyun  * waits for it to start, and only then tells mac80211 that we can start the
81*4882a593Smuzhiyun  * association. This way, we make sure that the association will be done
82*4882a593Smuzhiyun  * smoothly and won't be interrupted by channel switch decided within the fw.
83*4882a593Smuzhiyun  */
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun  /**
86*4882a593Smuzhiyun  * DOC: The flow against the fw
87*4882a593Smuzhiyun  *
88*4882a593Smuzhiyun  * When the driver needs to make sure we are in a certain channel, at a certain
89*4882a593Smuzhiyun  * time and for a certain duration, it sends a Time Event. The flow against the
90*4882a593Smuzhiyun  * fw goes like this:
91*4882a593Smuzhiyun  *	1) Driver sends a TIME_EVENT_CMD to the fw
92*4882a593Smuzhiyun  *	2) Driver gets the response for that command. This response contains the
93*4882a593Smuzhiyun  *	   Unique ID (UID) of the event.
94*4882a593Smuzhiyun  *	3) The fw sends notification when the event starts.
95*4882a593Smuzhiyun  *
96*4882a593Smuzhiyun  * Of course the API provides various options that allow to cover parameters
97*4882a593Smuzhiyun  * of the flow.
98*4882a593Smuzhiyun  *	What is the duration of the event?
99*4882a593Smuzhiyun  *	What is the start time of the event?
100*4882a593Smuzhiyun  *	Is there an end-time for the event?
101*4882a593Smuzhiyun  *	How much can the event be delayed?
102*4882a593Smuzhiyun  *	Can the event be split?
103*4882a593Smuzhiyun  *	If yes what is the maximal number of chunks?
104*4882a593Smuzhiyun  *	etc...
105*4882a593Smuzhiyun  */
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /**
108*4882a593Smuzhiyun  * DOC: Abstraction to the driver
109*4882a593Smuzhiyun  *
110*4882a593Smuzhiyun  * In order to simplify the use of time events to the rest of the driver,
111*4882a593Smuzhiyun  * we abstract the use of time events. This component provides the functions
112*4882a593Smuzhiyun  * needed by the driver.
113*4882a593Smuzhiyun  */
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun #define IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS 600
116*4882a593Smuzhiyun #define IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS 400
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun /**
119*4882a593Smuzhiyun  * iwl_mvm_protect_session - start / extend the session protection.
120*4882a593Smuzhiyun  * @mvm: the mvm component
121*4882a593Smuzhiyun  * @vif: the virtual interface for which the session is issued
122*4882a593Smuzhiyun  * @duration: the duration of the session in TU.
123*4882a593Smuzhiyun  * @min_duration: will start a new session if the current session will end
124*4882a593Smuzhiyun  *	in less than min_duration.
125*4882a593Smuzhiyun  * @max_delay: maximum delay before starting the time event (in TU)
126*4882a593Smuzhiyun  * @wait_for_notif: true if it is required that a time event notification be
127*4882a593Smuzhiyun  *	waited for (that the time event has been scheduled before returning)
128*4882a593Smuzhiyun  *
129*4882a593Smuzhiyun  * This function can be used to start a session protection which means that the
130*4882a593Smuzhiyun  * fw will stay on the channel for %duration_ms milliseconds. This function
131*4882a593Smuzhiyun  * can block (sleep) until the session starts. This function can also be used
132*4882a593Smuzhiyun  * to extend a currently running session.
133*4882a593Smuzhiyun  * This function is meant to be used for BSS association for example, where we
134*4882a593Smuzhiyun  * want to make sure that the fw stays on the channel during the association.
135*4882a593Smuzhiyun  */
136*4882a593Smuzhiyun void iwl_mvm_protect_session(struct iwl_mvm *mvm,
137*4882a593Smuzhiyun 			     struct ieee80211_vif *vif,
138*4882a593Smuzhiyun 			     u32 duration, u32 min_duration,
139*4882a593Smuzhiyun 			     u32 max_delay, bool wait_for_notif);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun /**
142*4882a593Smuzhiyun  * iwl_mvm_stop_session_protection - cancel the session protection.
143*4882a593Smuzhiyun  * @mvm: the mvm component
144*4882a593Smuzhiyun  * @vif: the virtual interface for which the session is issued
145*4882a593Smuzhiyun  *
146*4882a593Smuzhiyun  * This functions cancels the session protection which is an act of good
147*4882a593Smuzhiyun  * citizenship. If it is not needed any more it should be canceled because
148*4882a593Smuzhiyun  * the other bindings wait for the medium during that time.
149*4882a593Smuzhiyun  * This funtions doesn't sleep.
150*4882a593Smuzhiyun  */
151*4882a593Smuzhiyun void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
152*4882a593Smuzhiyun 				      struct ieee80211_vif *vif);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /*
155*4882a593Smuzhiyun  * iwl_mvm_rx_time_event_notif - handles %TIME_EVENT_NOTIFICATION.
156*4882a593Smuzhiyun  */
157*4882a593Smuzhiyun void iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
158*4882a593Smuzhiyun 				 struct iwl_rx_cmd_buffer *rxb);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /**
161*4882a593Smuzhiyun  * iwl_mvm_start_p2p_roc - start remain on channel for p2p device functionality
162*4882a593Smuzhiyun  * @mvm: the mvm component
163*4882a593Smuzhiyun  * @vif: the virtual interface for which the roc is requested. It is assumed
164*4882a593Smuzhiyun  * that the vif type is NL80211_IFTYPE_P2P_DEVICE
165*4882a593Smuzhiyun  * @duration: the requested duration in millisecond for the fw to be on the
166*4882a593Smuzhiyun  * channel that is bound to the vif.
167*4882a593Smuzhiyun  * @type: the remain on channel request type
168*4882a593Smuzhiyun  *
169*4882a593Smuzhiyun  * This function can be used to issue a remain on channel session,
170*4882a593Smuzhiyun  * which means that the fw will stay in the channel for the request %duration
171*4882a593Smuzhiyun  * milliseconds. The function is async, meaning that it only issues the ROC
172*4882a593Smuzhiyun  * request but does not wait for it to start. Once the FW is ready to serve the
173*4882a593Smuzhiyun  * ROC request, it will issue a notification to the driver that it is on the
174*4882a593Smuzhiyun  * requested channel. Once the FW completes the ROC request it will issue
175*4882a593Smuzhiyun  * another notification to the driver.
176*4882a593Smuzhiyun  */
177*4882a593Smuzhiyun int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
178*4882a593Smuzhiyun 			  int duration, enum ieee80211_roc_type type);
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun /**
181*4882a593Smuzhiyun  * iwl_mvm_stop_roc - stop remain on channel functionality
182*4882a593Smuzhiyun  * @mvm: the mvm component
183*4882a593Smuzhiyun  * @vif: the virtual interface for which the roc is stopped
184*4882a593Smuzhiyun  *
185*4882a593Smuzhiyun  * This function can be used to cancel an ongoing ROC session.
186*4882a593Smuzhiyun  * The function is async, it will instruct the FW to stop serving the ROC
187*4882a593Smuzhiyun  * session, but will not wait for the actual stopping of the session.
188*4882a593Smuzhiyun  */
189*4882a593Smuzhiyun void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun /**
192*4882a593Smuzhiyun  * iwl_mvm_remove_time_event - general function to clean up of time event
193*4882a593Smuzhiyun  * @mvm: the mvm component
194*4882a593Smuzhiyun  * @vif: the vif to which the time event belongs
195*4882a593Smuzhiyun  * @te_data: the time event data that corresponds to that time event
196*4882a593Smuzhiyun  *
197*4882a593Smuzhiyun  * This function can be used to cancel a time event regardless its type.
198*4882a593Smuzhiyun  * It is useful for cleaning up time events running before removing an
199*4882a593Smuzhiyun  * interface.
200*4882a593Smuzhiyun  */
201*4882a593Smuzhiyun void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
202*4882a593Smuzhiyun 			       struct iwl_mvm_vif *mvmvif,
203*4882a593Smuzhiyun 			       struct iwl_mvm_time_event_data *te_data);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun /**
206*4882a593Smuzhiyun  * iwl_mvm_te_clear_data - remove time event from list
207*4882a593Smuzhiyun  * @mvm: the mvm component
208*4882a593Smuzhiyun  * @te_data: the time event data to remove
209*4882a593Smuzhiyun  *
210*4882a593Smuzhiyun  * This function is mostly internal, it is made available here only
211*4882a593Smuzhiyun  * for firmware restart purposes.
212*4882a593Smuzhiyun  */
213*4882a593Smuzhiyun void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
214*4882a593Smuzhiyun 			   struct iwl_mvm_time_event_data *te_data);
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun void iwl_mvm_cleanup_roc_te(struct iwl_mvm *mvm);
217*4882a593Smuzhiyun void iwl_mvm_roc_done_wk(struct work_struct *wk);
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun void iwl_mvm_remove_csa_period(struct iwl_mvm *mvm,
220*4882a593Smuzhiyun 			       struct ieee80211_vif *vif);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun /**
223*4882a593Smuzhiyun  * iwl_mvm_schedule_csa_period - request channel switch absence period
224*4882a593Smuzhiyun  * @mvm: the mvm component
225*4882a593Smuzhiyun  * @vif: the virtual interface for which the channel switch is issued
226*4882a593Smuzhiyun  * @duration: the duration of the NoA in TU.
227*4882a593Smuzhiyun  * @apply_time: NoA start time in GP2.
228*4882a593Smuzhiyun  *
229*4882a593Smuzhiyun  * This function is used to schedule NoA time event and is used to perform
230*4882a593Smuzhiyun  * the channel switch flow.
231*4882a593Smuzhiyun  */
232*4882a593Smuzhiyun int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
233*4882a593Smuzhiyun 				struct ieee80211_vif *vif,
234*4882a593Smuzhiyun 				u32 duration, u32 apply_time);
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun /**
237*4882a593Smuzhiyun  * iwl_mvm_te_scheduled - check if the fw received the TE cmd
238*4882a593Smuzhiyun  * @te_data: the time event data that corresponds to that time event
239*4882a593Smuzhiyun  *
240*4882a593Smuzhiyun  * This function returns true iff this TE is added to the fw.
241*4882a593Smuzhiyun  */
242*4882a593Smuzhiyun static inline bool
iwl_mvm_te_scheduled(struct iwl_mvm_time_event_data * te_data)243*4882a593Smuzhiyun iwl_mvm_te_scheduled(struct iwl_mvm_time_event_data *te_data)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	if (!te_data)
246*4882a593Smuzhiyun 		return false;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	return !!te_data->uid;
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun /**
252*4882a593Smuzhiyun  * iwl_mvm_schedule_session_protection - schedule a session protection
253*4882a593Smuzhiyun  * @mvm: the mvm component
254*4882a593Smuzhiyun  * @vif: the virtual interface for which the protection issued
255*4882a593Smuzhiyun  * @duration: the duration of the protection
256*4882a593Smuzhiyun  * @wait_for_notif: if true, will block until the start of the protection
257*4882a593Smuzhiyun  */
258*4882a593Smuzhiyun void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
259*4882a593Smuzhiyun 					 struct ieee80211_vif *vif,
260*4882a593Smuzhiyun 					 u32 duration, u32 min_duration,
261*4882a593Smuzhiyun 					 bool wait_for_notif);
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun /**
264*4882a593Smuzhiyun  * iwl_mvm_rx_session_protect_notif - handles %SESSION_PROTECTION_NOTIF
265*4882a593Smuzhiyun  */
266*4882a593Smuzhiyun void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
267*4882a593Smuzhiyun 				      struct iwl_rx_cmd_buffer *rxb);
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun #endif /* __time_event_h__ */
270