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