blob: 864a1e73fc013fa669ed41adbe37353285fc1edf [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28#ifndef _WLAN_HDD_WMM_H
29#define _WLAN_HDD_WMM_H
30
31/**
32 * DOC: HDD WMM
33 *
34 * This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
35 * houses all the logic for WMM in HDD.
36 *
37 * On the control path, it has the logic to setup QoS, modify QoS and delete
38 * QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
39 * explicit application invoked and an internal HDD invoked. The implicit QoS
40 * is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
41 * which DO mark their traffic for priortization. It also has logic to start,
42 * update and stop the U-APSD trigger frame generation. It also has logic to
43 * read WMM related config parameters from the registry.
44 *
45 * On the data path, it has the logic to figure out the WMM AC of an egress
46 * packet and when to signal TL to serve a particular AC queue. It also has the
47 * logic to retrieve a packet based on WMM priority in response to a fetch from
48 * TL.
49 *
50 * The remaining functions are utility functions for information hiding.
51 */
52
53/* Include files */
54#include <linux/workqueue.h>
55#include <linux/list.h>
56#include <wlan_hdd_main.h>
57#include <wlan_hdd_wext.h>
58#include <sme_qos_api.h>
59
60/*Maximum number of ACs */
61#define WLAN_MAX_AC 4
62
63
64/* Preprocessor Definitions and Constants */
65
66/* #define HDD_WMM_DEBUG 1 */
67
68#define HDD_WMM_CTX_MAGIC 0x574d4d58 /* "WMMX" */
69
70#define HDD_WMM_HANDLE_IMPLICIT 0xFFFFFFFF
71
72#define HDD_WLAN_INVALID_STA_ID 0xFF
73
74/* Type Declarations */
75
76/**
77 * enum hdd_wmm_classification: types of classification supported
78 */
79typedef enum hdd_wmm_classification {
80 HDD_WMM_CLASSIFICATION_DSCP = 0,
81 HDD_WMM_CLASSIFICATION_802_1Q = 1
82} hdd_wmm_classification_t;
83
84/**
85 * enum hdd_wmm_user_mode - WMM modes of operation
86 *
87 * @HDD_WMM_USER_MODE_AUTO: STA can associate with any AP, & HDD looks at
88 * the SME notification after association to find out if associated
89 * with QAP and acts accordingly
90 * @HDD_WMM_USER_MODE_QBSS_ONLY - SME will add the extra logic to make sure
91 * STA associates with a QAP only
92 * @HDD_WMM_USER_MODE_NO_QOS - SME will not join a QoS AP, unless the phy
93 * mode setting says "Auto". In that case, STA is free to join 11n AP.
94 * Although from HDD point of view, it will not be doing any packet
95 * classifications.
96 */
97typedef enum hdd_wmm_user_mode {
98 HDD_WMM_USER_MODE_AUTO = 0,
99 HDD_WMM_USER_MODE_QBSS_ONLY = 1,
100 HDD_WMM_USER_MODE_NO_QOS = 2,
101} hdd_wmm_user_mode_t;
102
103/* UAPSD Mask bits */
104/* (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored) */
105#define HDD_AC_VO 0x1
106#define HDD_AC_VI 0x2
107#define HDD_AC_BK 0x4
108#define HDD_AC_BE 0x8
109
110/**
111 * struct hdd_wmm_qos_context - HDD WMM QoS Context
112 *
113 * This structure holds the context for a single flow which has either
114 * been confgured explicitly from userspace or implicitly via the
115 * Implicit QoS feature.
116 *
117 * @node: list node which can be used to put the context into a list
118 * of contexts
119 * @handle: identifer which uniquely identifies this context to userspace
120 * @qosFlowID: identifier which uniquely identifies this flow to SME
121 * @pAdapter: adapter upon which this flow was configured
122 * @acType: access category for this flow
123 * @lastStatus: the status of the last operation performed on this flow by SME
124 * @wmmAcSetupImplicitQos: work structure used for deferring implicit QoS work
125 * from softirq context to thread context
126 * @magic: magic number used to verify that this is a valid context when
127 * referenced anonymously
128 */
129typedef struct hdd_wmm_qos_context {
130 struct list_head node;
131 uint32_t handle;
132 uint32_t qosFlowId;
133 hdd_adapter_t *pAdapter;
134 sme_ac_enum_type acType;
135 hdd_wlan_wmm_status_e lastStatus;
136 struct work_struct wmmAcSetupImplicitQos;
137 uint32_t magic;
138 bool is_inactivity_timer_running;
139} hdd_wmm_qos_context_t;
140
141/**
142 * struct hdd_wmm_ac_status - WMM related per-AC state & status info
143 * @wmmAcAccessRequired - does the AP require access to this AC?
144 * @wmmAcAccessNeeded - does the worker thread need to acquire access to
145 * this AC?
146 * @wmmAcAccessPending - is implicit QoS negotiation currently taking place?
147 * @wmmAcAccessFailed - has implicit QoS negotiation already failed?
148 * @wmmAcAccessGranted - has implicit QoS negotiation already succeeded?
149 * @wmmAcAccessAllowed - is access to this AC allowed, either because we
150 * are not doing WMM, we are not doing implicit QoS, implict QoS has
151 * completed, or explicit QoS has completed?
152 * @wmmAcTspecValid - is the wmmAcTspecInfo valid?
153 * @wmmAcUapsdInfoValid - are the wmmAcUapsd* fields valid?
154 * @wmmAcTspecInfo - current (possibly aggregate) Tspec for this AC
155 * @wmmAcIsUapsdEnabled - is UAPSD enabled on this AC?
156 * @wmmAcUapsdServiceInterval - service interval for this AC
157 * @wmmAcUapsdSuspensionInterval - suspension interval for this AC
158 * @wmmAcUapsdDirection - direction for this AC
159 * @wmmInactivityTime - inactivity time for this AC
160 * @wmmPrevTrafficCnt - TX counter used for inactivity detection
161 * @wmmInactivityTimer - timer used for inactivity detection
162 */
163typedef struct hdd_wmm_ac_status {
164 bool wmmAcAccessRequired;
165 bool wmmAcAccessNeeded;
166 bool wmmAcAccessPending;
167 bool wmmAcAccessFailed;
168 bool wmmAcAccessGranted;
169 bool wmmAcAccessAllowed;
170 bool wmmAcTspecValid;
171 bool wmmAcUapsdInfoValid;
172 sme_QosWmmTspecInfo wmmAcTspecInfo;
173 bool wmmAcIsUapsdEnabled;
174 uint32_t wmmAcUapsdServiceInterval;
175 uint32_t wmmAcUapsdSuspensionInterval;
176 sme_QosWmmDirType wmmAcUapsdDirection;
177
178#ifdef FEATURE_WLAN_ESE
179 uint32_t wmmInactivityTime;
180 uint32_t wmmPrevTrafficCnt;
181 cdf_mc_timer_t wmmInactivityTimer;
182#endif
183
184} hdd_wmm_ac_status_t;
185
186/**
187 * struct hdd_wmm_status - WMM status maintained per-adapter
188 * @wmmContextList - list of WMM contexts active on the adapter
189 * @wmmLock - mutex used for exclusive access to this adapter's WMM status
190 * @wmmACStatus - per-AC WMM status
191 * @wmmQap - is this connected to a QoS-enabled AP?
192 * @wmmQosConnection - is this a QoS connection?
193 */
194typedef struct hdd_wmm_status {
195 struct list_head wmmContextList;
196 struct mutex wmmLock;
197 hdd_wmm_ac_status_t wmmAcStatus[WLAN_MAX_AC];
198 bool wmmQap;
199 bool wmmQosConnection;
200} hdd_wmm_status_t;
201
202extern const uint8_t hdd_qdisc_ac_to_tl_ac[];
203extern const uint8_t hdd_wmm_up_to_ac_map[];
204extern const uint8_t hdd_linux_up_to_ac_map[];
205
206#define WLAN_HDD_MAX_DSCP 0x3f
207
208/**
209 * hdd_wmmps_helper() - Function to set uapsd psb dynamically
210 *
211 * @pAdapter: [in] pointer to adapter structure
212 * @ptr: [in] pointer to command buffer
213 *
214 * Return: Zero on success, appropriate error on failure.
215 */
216int hdd_wmmps_helper(hdd_adapter_t *pAdapter, uint8_t *ptr);
217
218/**
219 * hdd_wmm_init() - initialize the WMM DSCP configuation
220 * @pAdapter : [in] pointer to Adapter context
221 *
222 * This function will initialize the WMM DSCP configuation of an
223 * adapter to an initial state. The configuration can later be
224 * overwritten via application APIs or via QoS Map sent OTA.
225 *
226 * Return: CDF_STATUS enumeration
227 */
228CDF_STATUS hdd_wmm_init(hdd_adapter_t *pAdapter);
229
230/**
231 * hdd_wmm_adapter_init() - initialize the WMM configuration of an adapter
232 * @pAdapter: [in] pointer to Adapter context
233 *
234 * This function will initialize the WMM configuation and status of an
235 * adapter to an initial state. The configuration can later be
236 * overwritten via application APIs
237 *
238 * Return: CDF_STATUS enumeration
239 */
240CDF_STATUS hdd_wmm_adapter_init(hdd_adapter_t *pAdapter);
241
242/**
243 * hdd_wmm_close() - WMM close function
244 * @pAdapter: [in] pointer to adapter context
245 *
246 * Function which will perform any necessary work to to clean up the
247 * WMM functionality prior to the kernel module unload.
248 *
249 * Return: CDF_STATUS enumeration
250 */
251CDF_STATUS hdd_wmm_adapter_close(hdd_adapter_t *pAdapter);
252
253/**
254 * hdd_wmm_select_queue() - Function which will classify the packet
255 * according to linux qdisc expectation.
256 *
257 * @dev: [in] pointer to net_device structure
258 * @skb: [in] pointer to os packet
259 *
260 * Return: Qdisc queue index
261 */
262uint16_t hdd_wmm_select_queue(struct net_device *dev, struct sk_buff *skb);
263
264/**
265 * hdd_hostapd_select_queue() - Function which will classify the packet
266 * according to linux qdisc expectation.
267 *
268 * @dev: [in] pointer to net_device structure
269 * @skb: [in] pointer to os packet
270 *
271 * Return: Qdisc queue index
272 */
273uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb
274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
275 , void *accel_priv
276#endif
277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
278 , select_queue_fallback_t fallback
279#endif
280);
281
282/**
283 * hdd_wmm_acquire_access_required() - Function which will determine
284 * acquire admittance for a WMM AC is required or not based on psb configuration
285 * done in framework
286 *
287 * @pAdapter: [in] pointer to adapter structure
288 * @acType: [in] WMM AC type of OS packet
289 *
290 * Return: void
291 */
292void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
293 sme_ac_enum_type acType);
294
295/**
296 * hdd_wmm_acquire_access() - Function which will attempt to acquire
297 * admittance for a WMM AC
298 *
299 * @pAdapter: [in] pointer to adapter context
300 * @acType: [in] WMM AC type of OS packet
301 * @pGranted: [out] pointer to bool flag when indicates if access
302 * has been granted or not
303 *
304 * Return: CDF_STATUS enumeration
305 */
306CDF_STATUS hdd_wmm_acquire_access(hdd_adapter_t *pAdapter,
307 sme_ac_enum_type acType, bool *pGranted);
308
309/**
310 * hdd_wmm_assoc() - Function which will handle the housekeeping
311 * required by WMM when association takes place
312 *
313 * @pAdapter: [in] pointer to adapter context
314 * @pRoamInfo: [in] pointer to roam information
315 * @eBssType: [in] type of BSS
316 *
317 * Return: CDF_STATUS enumeration
318 */
319CDF_STATUS hdd_wmm_assoc(hdd_adapter_t *pAdapter,
320 tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType);
321
322/**
323 * hdd_wmm_connect() - Function which will handle the housekeeping
324 * required by WMM when a connection is established
325 *
326 * @pAdapter : [in] pointer to adapter context
327 * @pRoamInfo: [in] pointer to roam information
328 * @eBssType : [in] type of BSS
329 *
330 * Return: CDF_STATUS enumeration
331 */
332CDF_STATUS hdd_wmm_connect(hdd_adapter_t *pAdapter,
333 tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType);
334
335/**
336 * hdd_wmm_get_uapsd_mask() - Function which will calculate the
337 * initial value of the UAPSD mask based upon the device configuration
338 *
339 * @pAdapter : [in] pointer to adapter context
340 * @pUapsdMask: [out] pointer to where the UAPSD Mask is to be stored
341 *
342 * Return: CDF_STATUS enumeration
343 */
344CDF_STATUS hdd_wmm_get_uapsd_mask(hdd_adapter_t *pAdapter,
345 uint8_t *pUapsdMask);
346
347/**
348 * hdd_wmm_is_active() - Function which will determine if WMM is
349 * active on the current connection
350 *
351 * @pAdapter: [in] pointer to adapter context
352 *
353 * Return: true if WMM is enabled, false if WMM is not enabled
354 */
355bool hdd_wmm_is_active(hdd_adapter_t *pAdapter);
356
357/**
358 * hdd_wmm_addts() - Function which will add a traffic spec at the
359 * request of an application
360 *
361 * @pAdapter : [in] pointer to adapter context
362 * @handle : [in] handle to uniquely identify a TS
363 * @pTspec : [in] pointer to the traffic spec
364 *
365 * Return: HDD_WLAN_WMM_STATUS_*
366 */
367hdd_wlan_wmm_status_e hdd_wmm_addts(hdd_adapter_t *pAdapter,
368 uint32_t handle,
369 sme_QosWmmTspecInfo *pTspec);
370
371/**
372 * hdd_wmm_delts() - Function which will delete a traffic spec at the
373 * request of an application
374 *
375 * @pAdapter: [in] pointer to adapter context
376 * @handle: [in] handle to uniquely identify a TS
377 *
378 * Return: HDD_WLAN_WMM_STATUS_*
379 */
380hdd_wlan_wmm_status_e hdd_wmm_delts(hdd_adapter_t *pAdapter, uint32_t handle);
381
382/**
383 * hdd_wmm_checkts() - Function which will return the status of a traffic
384 * spec at the request of an application
385 *
386 * @pAdapter: [in] pointer to adapter context
387 * @handle: [in] handle to uniquely identify a TS
388 *
389 * Return: HDD_WLAN_WMM_STATUS_*
390 */
391hdd_wlan_wmm_status_e hdd_wmm_checkts(hdd_adapter_t *pAdapter,
392 uint32_t handle);
393/**
394 * hdd_wmm_adapter_clear() - Function which will clear the WMM status
395 * for all the ACs
396 *
397 * @pAdapter: [in] pointer to Adapter context
398 *
399 * Return: CDF_STATUS enumeration
400 */
401CDF_STATUS hdd_wmm_adapter_clear(hdd_adapter_t *pAdapter);
402
403void wlan_hdd_process_peer_unauthorised_pause(hdd_adapter_t *adapter);
404#endif /* #ifndef _WLAN_HDD_WMM_H */